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 Shader execute test.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [petri] Multiple grid with differing constants/uniforms.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [petri]
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderRenderCase.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdio.h>
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gls
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace std;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace tcu;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glu;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int			GRID_SIZE				= 64;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int			MAX_RENDER_WIDTH		= 128;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int			MAX_RENDER_HEIGHT		= 112;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const tcu::Vec4		DEFAULT_CLEAR_COLOR		= tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline RGBA toRGBA (const Vec4& a)
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return RGBA(deClamp32(deRoundFloatToInt32(a.x() * 255.0f), 0, 255),
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(deRoundFloatToInt32(a.y() * 255.0f), 0, 255),
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(deRoundFloatToInt32(a.z() * 255.0f), 0, 255),
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deClamp32(deRoundFloatToInt32(a.w() * 255.0f), 0, 255));
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec4 toVec (const RGBA& c)
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Vec4(c.getRed()		/ 255.0f,
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 c.getGreen()	/ 255.0f,
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 c.getBlue()	/ 255.0f,
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 c.getAlpha()	/ 255.0f);
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureBinding
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureBinding::TextureBinding (const glu::Texture2D* tex2D, const tcu::Sampler& sampler)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type	(TYPE_2D)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_sampler	(sampler)
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.tex2D = tex2D;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureBinding::TextureBinding (const glu::TextureCube* texCube, const tcu::Sampler& sampler)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type	(TYPE_CUBE_MAP)
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_sampler	(sampler)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.texCube = texCube;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureBinding::TextureBinding (const glu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type	(TYPE_2D_ARRAY)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_sampler	(sampler)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.tex2DArray = tex2DArray;
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureBinding::TextureBinding (const glu::Texture3D* tex3D, const tcu::Sampler& sampler)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type	(TYPE_3D)
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_sampler	(sampler)
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.tex3D = tex3D;
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureBinding::TextureBinding (void)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type	(TYPE_NONE)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.tex2D = DE_NULL;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureBinding::setSampler (const tcu::Sampler& sampler)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_sampler = sampler;
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureBinding::setTexture (const glu::Texture2D* tex2D)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type			= TYPE_2D;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.tex2D	= tex2D;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureBinding::setTexture (const glu::TextureCube* texCube)
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type				= TYPE_CUBE_MAP;
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.texCube	= texCube;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureBinding::setTexture (const glu::Texture2DArray* tex2DArray)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type					= TYPE_2D_ARRAY;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.tex2DArray	= tex2DArray;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureBinding::setTexture (const glu::Texture3D* tex3D)
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type			= TYPE_3D;
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_binding.tex3D	= tex3D;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// QuadGrid.
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass QuadGrid
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							QuadGrid				(int gridSize, int screenWidth, int screenHeight, const Vec4& constCoords, const vector<Mat4>& userAttribTransforms, const vector<TextureBinding>& textures);
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~QuadGrid				(void);
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getGridSize				(void) const { return m_gridSize; }
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getNumVertices			(void) const { return m_numVertices; }
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getNumTriangles			(void) const { return m_numTriangles; }
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4&				getConstCoords			(void) const { return m_constCoords; }
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<Mat4>		getUserAttribTransforms	(void) const { return m_userAttribTransforms; }
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<TextureBinding>&	getTextures		(void) const { return m_textures; }
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4*				getPositions			(void) const { return &m_positions[0]; }
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float*			getAttribOne			(void) const { return &m_attribOne[0]; }
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4*				getCoords				(void) const { return &m_coords[0]; }
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4*				getUnitCoords			(void) const { return &m_unitCoords[0]; }
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4*				getUserAttrib			(int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint16*			getIndices				(void) const { return &m_indices[0]; }
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4					getCoords				(float sx, float sy) const;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4					getUnitCoords			(float sx, float sy) const;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getNumUserAttribs		(void) const { return (int)m_userAttribTransforms.size(); }
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4					getUserAttrib			(int attribNdx, float sx, float sy) const;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_gridSize;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_numVertices;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_numTriangles;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4					m_constCoords;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Mat4>			m_userAttribTransforms;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<TextureBinding>	m_textures;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4>			m_screenPos;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4>			m_positions;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4>			m_coords;			//!< Near-unit coordinates, roughly [-2.0 .. 2.0].
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4>			m_unitCoords;		//!< Positive-only coordinates [0.0 .. 1.5].
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>			m_attribOne;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4>			m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint16>		m_indices;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryQuadGrid::QuadGrid (int gridSize, int width, int height, const Vec4& constCoords, const vector<Mat4>& userAttribTransforms, const vector<TextureBinding>& textures)
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_gridSize				(gridSize)
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numVertices				((gridSize + 1) * (gridSize + 1))
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numTriangles			(gridSize * gridSize * 2)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_constCoords				(constCoords)
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_userAttribTransforms	(userAttribTransforms)
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textures				(textures)
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 viewportScale = Vec4((float)width, (float)height, 0.0f, 0.0f);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute vertices.
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_positions.resize(m_numVertices);
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coords.resize(m_numVertices);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_unitCoords.resize(m_numVertices);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_attribOne.resize(m_numVertices);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_screenPos.resize(m_numVertices);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// User attributes.
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_userAttribs); i++)
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribs[i].resize(m_numVertices);
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < gridSize+1; y++)
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < gridSize+1; x++)
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float				sx			= x / (float)gridSize;
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float				sy			= y / (float)gridSize;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float				fx			= 2.0f * sx - 1.0f;
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float				fy			= 2.0f * sy - 1.0f;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					vtxNdx		= ((y * (gridSize+1)) + x);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_positions[vtxNdx]		= Vec4(fx, fy, 0.0f, 1.0f);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_attribOne[vtxNdx]		= 1.0f;
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_screenPos[vtxNdx]		= Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_coords[vtxNdx]		= getCoords(sx, sy);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_unitCoords[vtxNdx]	= getUnitCoords(sx, sy);
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute indices.
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_indices.resize(3 * m_numTriangles);
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < gridSize; y++)
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < gridSize; x++)
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int stride = gridSize + 1;
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int v00 = (y * stride) + x;
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int v01 = (y * stride) + x + 1;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int v10 = ((y+1) * stride) + x;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int v11 = ((y+1) * stride) + x + 1;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int baseNdx = ((y * gridSize) + x) * 6;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices[baseNdx + 0] = v10;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices[baseNdx + 1] = v00;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices[baseNdx + 2] = v01;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices[baseNdx + 3] = v10;
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices[baseNdx + 4] = v01;
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices[baseNdx + 5] = v11;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryQuadGrid::~QuadGrid (void)
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4 QuadGrid::getCoords (float sx, float sy) const
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float fx = 2.0f * sx - 1.0f;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float fy = 2.0f * sy - 1.0f;
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// homogeneous normalized screen-space coordinates
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_userAttribTransforms[attribNdx] * Vec4(sx, sy, 0.0f, 1.0f);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderEvalContext.
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid_)
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: constCoords	(quadGrid_.getConstCoords())
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, isDiscarded	(false)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, quadGrid		(quadGrid_)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<TextureBinding>& bindings = quadGrid.getTextures();
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in texture array.
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const TextureBinding& binding = bindings[ndx];
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (binding.getType() == TextureBinding::TYPE_NONE)
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		textures[ndx].sampler = binding.getSampler();
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (binding.getType())
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureBinding::TYPE_2D:		textures[ndx].tex2D			= &binding.get2D()->getRefTexture();		break;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureBinding::TYPE_CUBE_MAP:	textures[ndx].texCube		= &binding.getCube()->getRefTexture();		break;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureBinding::TYPE_2D_ARRAY:	textures[ndx].tex2DArray	= &binding.get2DArray()->getRefTexture();	break;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureBinding::TYPE_3D:		textures[ndx].tex3D			= &binding.get3D()->getRefTexture();		break;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(DE_FALSE);
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderEvalContext::~ShaderEvalContext (void)
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderEvalContext::reset (float sx, float sy)
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear old values
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	color		= Vec4(0.0f, 0.0f, 0.0f, 1.0f);
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	isDiscarded	= false;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute coords
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	coords		= quadGrid.getCoords(sx, sy);
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	unitCoords	= quadGrid.getUnitCoords(sx, sy);
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute user attributes.
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numAttribs = quadGrid.getNumUserAttribs();
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		in[attribNdx] = quadGrid.getUserAttrib(attribNdx, sx, sy);
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (textures[unitNdx].tex2D)
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderEvaluator
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderEvaluator::ShaderEvaluator (void)
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_evalFunc(DE_NULL)
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_evalFunc(evalFunc)
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderEvaluator::~ShaderEvaluator (void)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderEvaluator::evaluate (ShaderEvalContext& ctx)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_evalFunc);
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_evalFunc(ctx);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderRenderCase.
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderRenderCase::ShaderRenderCase (TestContext& testCtx, RenderContext& renderCtx, const ContextInfo& ctxInfo, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc)
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(testCtx, name, description)
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx			(renderCtx)
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_ctxInfo				(ctxInfo)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isVertexCase		(isVertexCase)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_defaultEvaluator	(evalFunc)
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_evaluator			(m_defaultEvaluator)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_clearColor			(DEFAULT_CLEAR_COLOR)
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program				(DE_NULL)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderRenderCase::ShaderRenderCase (TestContext& testCtx, RenderContext& renderCtx, const ContextInfo& ctxInfo, const char* name, const char* description, bool isVertexCase, ShaderEvaluator& evaluator)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(testCtx, name, description)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx			(renderCtx)
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_ctxInfo				(ctxInfo)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isVertexCase		(isVertexCase)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_defaultEvaluator	(DE_NULL)
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_evaluator			(evaluator)
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_clearColor			(DEFAULT_CLEAR_COLOR)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program				(DE_NULL)
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderRenderCase::~ShaderRenderCase (void)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderRenderCase::deinit();
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::init (void)
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log		= m_testCtx.getLog();
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_renderCtx.getFunctions();
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderRenderCase::init() begin");
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_vertShaderSource.empty() || m_fragShaderSource.empty())
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_vertShaderSource.empty() && m_fragShaderSource.empty());
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setupShaderData();
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new ShaderProgram(m_renderCtx, makeVtxFragSources(m_vertShaderSource, m_fragShaderSource));
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << *m_program; // Always log shader program.
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_program->isOk())
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw CompileFailed(__FILE__, __LINE__);
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderRenderCase::init() end");
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up.
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ShaderRenderCase::deinit();
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::deinit (void)
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::IVec2 ShaderRenderCase::getViewportSize (void) const
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::IVec2(de::min(m_renderCtx.getRenderTarget().getWidth(), MAX_RENDER_WIDTH),
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  de::min(m_renderCtx.getRenderTarget().getHeight(), MAX_RENDER_HEIGHT));
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestNode::IterateResult ShaderRenderCase::iterate (void)
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_renderCtx.getFunctions();
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderRenderCase::iterate() begin");
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_program);
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 programID = m_program->getProgram();
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(programID);
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create quad grid.
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	viewportSize	= getViewportSize();
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		width			= viewportSize.x();
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		height			= viewportSize.y();
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [petri] Better handling of constCoords (render in multiple chunks, vary coords).
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	QuadGrid quadGrid(m_isVertexCase ? GRID_SIZE : 4, width, height, Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures);
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render result.
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface resImage(width, height);
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	render(resImage, programID, quadGrid);
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute reference.
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface refImage (width, height);
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isVertexCase)
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeVertexReference(refImage, quadGrid);
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeFragmentReference(refImage, quadGrid);
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare.
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool testOk = compareImages(resImage, refImage, 0.05f);
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// De-initialize.
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(0);
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(testOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							testOk ? "Pass"					: "Fail");
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return TestNode::STOP;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::setupShaderData (void)
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::setup (int programID)
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(programID);
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::setupUniforms (int programID, const Vec4& constCoords)
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(programID);
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(constCoords);
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::setupDefaultInputs (int programID)
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_renderCtx.getFunctions();
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP UNIFORMS.
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupDefaultUniforms(m_renderCtx, programID);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "post uniform setup");
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP TEXTURES.
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < (int)m_textures.size(); ndx++)
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const TextureBinding&	tex			= m_textures[ndx];
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Sampler&		sampler		= tex.getSampler();
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32				texTarget	= GL_NONE;
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32				texObj		= 0;
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (tex.getType() == TextureBinding::TYPE_NONE)
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Feature check.
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_renderCtx.getType().getAPI() == glu::ApiType::es(2,0))
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (tex.getType() == TextureBinding::TYPE_2D_ARRAY)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("2D array texture binding is not supported");
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (tex.getType() == TextureBinding::TYPE_3D)
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("3D texture binding is not supported");
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (sampler.compare != tcu::Sampler::COMPAREMODE_NONE)
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("Shadow lookups are not supported");
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (tex.getType())
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureBinding::TYPE_2D:		texTarget = GL_TEXTURE_2D;			texObj = tex.get2D()->getGLTexture();		break;
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureBinding::TYPE_CUBE_MAP:	texTarget = GL_TEXTURE_CUBE_MAP;	texObj = tex.getCube()->getGLTexture();		break;
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureBinding::TYPE_2D_ARRAY:	texTarget = GL_TEXTURE_2D_ARRAY;	texObj = tex.get2DArray()->getGLTexture();	break;
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureBinding::TYPE_3D:		texTarget = GL_TEXTURE_3D;			texObj = tex.get3D()->getGLTexture();		break;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(DE_FALSE);
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.activeTexture(GL_TEXTURE0+ndx);
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(texTarget, texObj);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(texTarget, GL_TEXTURE_WRAP_S,		glu::getGLWrapMode(sampler.wrapS));
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(texTarget, GL_TEXTURE_WRAP_T,		glu::getGLWrapMode(sampler.wrapT));
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(texTarget, GL_TEXTURE_MIN_FILTER,	glu::getGLFilterMode(sampler.minFilter));
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(texTarget, GL_TEXTURE_MAG_FILTER,	glu::getGLFilterMode(sampler.magFilter));
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texTarget == GL_TEXTURE_3D)
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(texTarget, GL_TEXTURE_WRAP_R, glu::getGLWrapMode(sampler.wrapR));
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (sampler.compare != tcu::Sampler::COMPAREMODE_NONE)
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(texTarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texParameteri(texTarget, GL_TEXTURE_COMPARE_FUNC, glu::getGLCompareFunc(sampler.compare));
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "texture sampler setup");
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getDefaultVertexArrays (const glw::Functions& gl, const QuadGrid& quadGrid, deUint32 program, vector<VertexArrayBinding>& vertexArrays)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int numElements = quadGrid.getNumVertices();
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertexArrays.push_back(va::Float("a_position",		4, numElements, 0, (const float*)quadGrid.getPositions()));
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertexArrays.push_back(va::Float("a_coords",		4, numElements, 0, (const float*)quadGrid.getCoords()));
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertexArrays.push_back(va::Float("a_unitCoords",	4, numElements, 0, (const float*)quadGrid.getUnitCoords()));
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertexArrays.push_back(va::Float("a_one",			1, numElements, 0, quadGrid.getAttribOne()));
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// a_inN.
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int userNdx = 0; userNdx < quadGrid.getNumUserAttribs(); userNdx++)
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string name = string("a_in") + de::toString(userNdx);
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexArrays.push_back(va::Float(name, 4, numElements, 0, (const float*)quadGrid.getUserAttrib(userNdx)));
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Matrix attributes - these are set by location
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*	name;
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			numCols;
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			numRows;
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} matrices[] =
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat2",		2, 2 },
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat2x3",	2, 3 },
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat2x4",	2, 4 },
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat3x2",	3, 2 },
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat3",		3, 3 },
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat3x4",	3, 4 },
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat4x2",	4, 2 },
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat4x3",	4, 3 },
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a_mat4",		4, 4 }
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int loc = gl.getAttribLocation(program, matrices[matNdx].name);
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (loc < 0)
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue; // Not used in shader.
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int numRows	= matrices[matNdx].numRows;
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int numCols	= matrices[matNdx].numCols;
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int colNdx = 0; colNdx < numCols; colNdx++)
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vertexArrays.push_back(va::Float(loc+colNdx, numRows, numElements, 4*(int)sizeof(float), (const float*)quadGrid.getUserAttrib(colNdx)));
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::render (Surface& result, int programID, const QuadGrid& quadGrid)
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_renderCtx.getFunctions();
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "pre render");
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Buffer info.
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				width		= result.getWidth();
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				height		= result.getHeight();
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				xOffsetMax	= m_renderCtx.getRenderTarget().getWidth() - width;
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				yOffsetMax	= m_renderCtx.getRenderTarget().getHeight() - height;
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		hash		= deStringHash(m_vertShaderSource.c_str()) + deStringHash(m_fragShaderSource.c_str());
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random		rnd			(hash);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				xOffset		= rnd.getInt(0, xOffsetMax);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				yOffset		= rnd.getInt(0, yOffsetMax);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(xOffset, yOffset, width, height);
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup program.
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupUniforms(programID, quadGrid.getConstCoords());
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupDefaultInputs(programID);
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear.
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(m_clearColor.x(), m_clearColor.y(), m_clearColor.z(), m_clearColor.w());
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw.
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<VertexArrayBinding>	vertexArrays;
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int						numElements		= quadGrid.getNumTriangles()*3;
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getDefaultVertexArrays(gl, quadGrid, programID, vertexArrays);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		draw(m_renderCtx, programID, (int)vertexArrays.size(), &vertexArrays[0], pr::Triangles(numElements, quadGrid.getIndices()));
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read back results.
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, xOffset, yOffset, result.getAccess());
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "post render");
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::computeVertexReference (Surface& result, const QuadGrid& quadGrid)
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Buffer info.
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					width		= result.getWidth();
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					height		= result.getHeight();
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					gridSize	= quadGrid.getGridSize();
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					stride		= gridSize + 1;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				hasAlpha	= m_renderCtx.getRenderTarget().getPixelFormat().alphaBits > 0;
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalContext	evalCtx		(quadGrid);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Evaluate color for each vertex.
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4> colors((gridSize+1)*(gridSize+1));
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < gridSize+1; y++)
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < gridSize+1; x++)
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float				sx			= x / (float)gridSize;
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float				sy			= y / (float)gridSize;
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					vtxNdx		= ((y * (gridSize+1)) + x);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.reset(sx, sy);
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_evaluator.evaluate(evalCtx);
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4 color = evalCtx.color;
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasAlpha)
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			color.w() = 1.0f;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		colors[vtxNdx] = color;
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render quads.
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < gridSize; y++)
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < gridSize; x++)
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float x0 = x / (float)gridSize;
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float x1 = (x + 1) / (float)gridSize;
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float y0 = y / (float)gridSize;
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float y1 = (y + 1) / (float)gridSize;
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float sx0 = x0 * (float)width;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float sx1 = x1 * (float)width;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float sy0 = y0 * (float)height;
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float sy1 = y1 * (float)height;
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float oosx = 1.0f / (sx1 - sx0);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float oosy = 1.0f / (sy1 - sy0);
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		v00 = (y * stride) + x;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		v01 = (y * stride) + x + 1;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		v10 = ((y + 1) * stride) + x;
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		v11 = ((y + 1) * stride) + x + 1;
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4	c00 = colors[v00];
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4	c01 = colors[v01];
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4	c10 = colors[v10];
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4	c11 = colors[v11];
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int iy = iy0; iy < iy1; iy++)
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ix = ix0; ix < ix1; ix++)
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(deInBounds32(ix, 0, width));
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(deInBounds32(iy, 0, height));
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		sfx		= (float)ix + 0.5f;
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		sfy		= (float)iy + 0.5f;
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		fx1		= deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		fy1		= deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Triangle quad interpolation.
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool		tri		= fx1 + fy1 <= 1.0f;
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		tx		= tri ? fx1 : (1.0f-fx1);
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float		ty		= tri ? fy1 : (1.0f-fy1);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4&	t0		= tri ? c00 : c11;
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4&	t1		= tri ? c01 : c10;
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4&	t2		= tri ? c10 : c01;
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4		color	= t0 + (t1-t0)*tx + (t2-t0)*ty;
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.setPixel(ix, iy, toRGBA(color));
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderRenderCase::computeFragmentReference (Surface& result, const QuadGrid& quadGrid)
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Buffer info.
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					width		= result.getWidth();
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					height		= result.getHeight();
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				hasAlpha	= m_renderCtx.getRenderTarget().getPixelFormat().alphaBits > 0;
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalContext	evalCtx		(quadGrid);
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render.
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < height; y++)
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < width; x++)
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float sx = ((float)x + 0.5f) / (float)width;
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float sy = ((float)y + 0.5f) / (float)height;
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.reset(sx, sy);
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_evaluator.evaluate(evalCtx);
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select either clear color or computed color based on discarded bit.
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasAlpha)
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			color.w() = 1.0f;
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.setPixel(x, y, toRGBA(color));
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderRenderCase::compareImages (const Surface& resImage, const Surface& refImage, float errorThreshold)
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::fuzzyCompare(m_testCtx.getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Uniform name helpers.
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* getIntUniformName (int number)
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (number)
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 0:		return "ui_zero";
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 1:		return "ui_one";
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 2:		return "ui_two";
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 3:		return "ui_three";
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 4:		return "ui_four";
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 5:		return "ui_five";
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 6:		return "ui_six";
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 7:		return "ui_seven";
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 8:		return "ui_eight";
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 101:	return "ui_oneHundredOne";
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return "";
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* getFloatUniformName (int number)
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (number)
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 0:	return "uf_zero";
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 1: return "uf_one";
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 2: return "uf_two";
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 3: return "uf_three";
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 4: return "uf_four";
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 5: return "uf_five";
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 6: return "uf_six";
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 7: return "uf_seven";
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 8: return "uf_eight";
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return "";
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* getFloatFractionUniformName (int number)
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (number)
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 1: return "uf_one";
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 2: return "uf_half";
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 3: return "uf_third";
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 4: return "uf_fourth";
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 5: return "uf_fifth";
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 6: return "uf_sixth";
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 7: return "uf_seventh";
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 8: return "uf_eighth";
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return "";
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid setupDefaultUniforms (const glu::RenderContext& context, deUint32 programID)
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = context.getFunctions();
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bool.
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BoolUniform { const char* name; bool value; };
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const BoolUniform s_boolUniforms[] =
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ub_true",	true },
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ub_false",	false },
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_boolUniforms); i++)
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_boolUniforms[i].name);
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1i(uniLoc, s_boolUniforms[i].value);
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// BVec4.
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BVec4Uniform { const char* name; BVec4 value; };
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const BVec4Uniform s_bvec4Uniforms[] =
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ub4_true",	BVec4(true) },
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ub4_false",	BVec4(false) },
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_bvec4Uniforms); i++)
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BVec4Uniform& uni = s_bvec4Uniforms[i];
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int arr[4];
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		arr[0] = (int)uni.value.x();
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		arr[1] = (int)uni.value.y();
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		arr[2] = (int)uni.value.z();
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		arr[3] = (int)uni.value.w();
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, uni.name);
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform4iv(uniLoc, 1, &arr[0]);
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Int.
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct IntUniform { const char* name; int value; };
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const IntUniform s_intUniforms[] =
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_minusOne",		-1 },
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_zero",			0 },
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_one",				1 },
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_two",				2 },
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_three",			3 },
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_four",			4 },
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_five",			5 },
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_six",				6 },
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_seven",			7 },
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_eight",			8 },
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui_oneHundredOne",	101 }
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_intUniforms); i++)
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_intUniforms[i].name);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1i(uniLoc, s_intUniforms[i].value);
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// IVec2.
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct IVec2Uniform { const char* name; IVec2 value; };
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const IVec2Uniform s_ivec2Uniforms[] =
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui2_minusOne",	IVec2(-1) },
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui2_zero",		IVec2(0) },
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui2_one",		IVec2(1) },
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui2_two",		IVec2(2) },
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui2_four",		IVec2(4) },
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui2_five",		IVec2(5) }
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_ivec2Uniforms); i++)
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_ivec2Uniforms[i].name);
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform2iv(uniLoc, 1, s_ivec2Uniforms[i].value.getPtr());
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// IVec3.
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct IVec3Uniform { const char* name; IVec3 value; };
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const IVec3Uniform s_ivec3Uniforms[] =
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui3_minusOne",	IVec3(-1) },
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui3_zero",		IVec3(0) },
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui3_one",		IVec3(1) },
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui3_two",		IVec3(2) },
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui3_four",		IVec3(4) },
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui3_five",		IVec3(5) }
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_ivec3Uniforms); i++)
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_ivec3Uniforms[i].name);
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform3iv(uniLoc, 1, s_ivec3Uniforms[i].value.getPtr());
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// IVec4.
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct IVec4Uniform { const char* name; IVec4 value; };
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const IVec4Uniform s_ivec4Uniforms[] =
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui4_minusOne",	IVec4(-1) },
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui4_zero",		IVec4(0) },
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui4_one",		IVec4(1) },
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui4_two",		IVec4(2) },
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui4_four",		IVec4(4) },
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "ui4_five",		IVec4(5) }
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_ivec4Uniforms); i++)
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_ivec4Uniforms[i].name);
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform4iv(uniLoc, 1, s_ivec4Uniforms[i].value.getPtr());
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Float.
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FloatUniform { const char* name; float value; };
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const FloatUniform s_floatUniforms[] =
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_zero",	0.0f },
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_one",		1.0f },
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_two",		2.0f },
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_three",	3.0f },
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_four",	4.0f },
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_five",	5.0f },
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_six",		6.0f },
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_seven",	7.0f },
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_eight",	8.0f },
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_half",	1.0f / 2.0f },
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_third",	1.0f / 3.0f },
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_fourth",	1.0f / 4.0f },
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_fifth",	1.0f / 5.0f },
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_sixth",	1.0f / 6.0f },
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_seventh",	1.0f / 7.0f },
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uf_eighth",	1.0f / 8.0f }
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_floatUniforms); i++)
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_floatUniforms[i].name);
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1f(uniLoc, s_floatUniforms[i].value);
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Vec2.
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct Vec2Uniform { const char* name; Vec2 value; };
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Vec2Uniform s_vec2Uniforms[] =
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv2_minusOne",	Vec2(-1.0f) },
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv2_zero",		Vec2(0.0f) },
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv2_half",		Vec2(0.5f) },
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv2_one",		Vec2(1.0f) },
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv2_two",		Vec2(2.0f) },
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_vec2Uniforms); i++)
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_vec2Uniforms[i].name);
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform2fv(uniLoc, 1, s_vec2Uniforms[i].value.getPtr());
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Vec3.
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct Vec3Uniform { const char* name; Vec3 value; };
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Vec3Uniform s_vec3Uniforms[] =
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv3_minusOne",	Vec3(-1.0f) },
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv3_zero",		Vec3(0.0f) },
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv3_half",		Vec3(0.5f) },
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv3_one",		Vec3(1.0f) },
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv3_two",		Vec3(2.0f) },
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_vec3Uniforms); i++)
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_vec3Uniforms[i].name);
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform3fv(uniLoc, 1, s_vec3Uniforms[i].value.getPtr());
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Vec4.
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct Vec4Uniform { const char* name; Vec4 value; };
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Vec4Uniform s_vec4Uniforms[] =
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv4_minusOne",	Vec4(-1.0f) },
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv4_zero",		Vec4(0.0f) },
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv4_half",		Vec4(0.5f) },
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv4_one",		Vec4(1.0f) },
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv4_two",		Vec4(2.0f) },
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv4_black",		Vec4(0.0f, 0.0f, 0.0f, 1.0f) },
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv4_gray",		Vec4(0.5f, 0.5f, 0.5f, 1.0f) },
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uv4_white",		Vec4(1.0f, 1.0f, 1.0f, 1.0f) },
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_vec4Uniforms); i++)
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int uniLoc = gl.getUniformLocation(programID, s_vec4Uniforms[i].name);
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniLoc != -1)
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform4fv(uniLoc, 1, s_vec4Uniforms[i].value.getPtr());
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gls
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1039