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