13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Random Shader Generator
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 Program Executor.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgProgramExecutor.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgExecutionContext.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgVariableValue.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgUtils.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set;
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace rsg
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VaryingStorage
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							VaryingStorage		(const VariableType& type, int numVertices);
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~VaryingStorage		(void) {}
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueAccess				getValue			(const VariableType& type, int vtxNdx);
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstValueAccess		getValue			(const VariableType& type, int vtxNdx) const;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<Scalar>		m_value;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVaryingStorage::VaryingStorage (const VariableType& type, int numVertices)
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_value(type.getScalarSize()*numVertices)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryValueAccess VaryingStorage::getValue (const VariableType& type, int vtxNdx)
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ValueAccess(type, &m_value[type.getScalarSize()*vtxNdx]);
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstValueAccess VaryingStorage::getValue (const VariableType& type, int vtxNdx) const
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ConstValueAccess(type, &m_value[type.getScalarSize()*vtxNdx]);
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VaryingStore
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							VaryingStore		(int numVertices);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~VaryingStore		(void);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VaryingStorage*			getStorage			(const VariableType& type, const char* name);
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int											m_numVertices;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::map<std::string, VaryingStorage*>		m_values;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVaryingStore::VaryingStore (int numVertices)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numVertices(numVertices)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVaryingStore::~VaryingStore (void)
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (map<string, VaryingStorage*>::iterator i = m_values.begin(); i != m_values.end(); i++)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete i->second;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_values.clear();
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVaryingStorage* VaryingStore::getStorage (const VariableType& type, const char* name)
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VaryingStorage* storage = m_values[name];
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!storage)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		storage = new VaryingStorage(type, m_numVertices);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_values[name] = storage;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return storage;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float interpolateVertexQuad (const tcu::Vec4& quad, float x, float y)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float w00 = (1.0f-x)*(1.0f-y);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float w01 = (1.0f-x)*y;
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float w10 = x*(1.0f-y);
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float w11 = x*y;
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return quad.x()*w00 + quad.y()*w10 + quad.z()*w01 + quad.w()*w11;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float interpolateVertex (float x0y0, float x1y1, float x, float y)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return interpolateVertexQuad(tcu::Vec4(x0y0, (x0y0+x1y1)*0.5f, (x0y0+x1y1)*0.5f, x1y1), x, y);
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float interpolateTri (float v0, float v1, float v2, float x, float y)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return v0 + (v1-v0)*x + (v2-v0)*y;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float interpolateFragment (const tcu::Vec4& quad, float x, float y)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (x + y < 1.0f)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return interpolateTri(quad.x(), quad.y(), quad.z(), x, y);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return interpolateTri(quad.w(), quad.z(), quad.y(), 1.0f-x, 1.0f-y);
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Stride>
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid interpolateVertexInput (StridedValueAccess<Stride> dst, int dstComp, const ConstValueRangeAccess valueRange, float x, float y)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(valueRange.getType().getBaseType() == VariableType::TYPE_FLOAT);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numElements = valueRange.getType().getNumElements();
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int elementNdx = 0; elementNdx < numElements; elementNdx++)
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float xd, yd;
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getVertexInterpolationCoords(xd, yd, x, y, elementNdx);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst.component(elementNdx).asFloat(dstComp) = interpolateVertex(valueRange.getMin().component(elementNdx).asFloat(), valueRange.getMax().component(elementNdx).asFloat(), xd, yd);
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Stride>
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid interpolateFragmentInput (StridedValueAccess<Stride> dst, int dstComp, ConstValueAccess vtx0, ConstValueAccess vtx1, ConstValueAccess vtx2, ConstValueAccess vtx3, float x, float y)
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(dst.getType().getBaseType() == VariableType::TYPE_FLOAT);
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numElements = dst.getType().getNumElements();
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numElements; ndx++)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst.component(ndx).asFloat(dstComp) = interpolateFragment(tcu::Vec4(vtx0.component(ndx).asFloat(), vtx1.component(ndx).asFloat(), vtx2.component(ndx).asFloat(), vtx3.component(ndx).asFloat()), x, y);
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Stride>
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyVarying (ValueAccess dst, ConstStridedValueAccess<Stride> src, int compNdx)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(dst.getType().getBaseType() == VariableType::TYPE_FLOAT);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int elemNdx = 0; elemNdx < dst.getType().getNumElements(); elemNdx++)
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst.component(elemNdx).asFloat() = src.component(elemNdx).asFloat(compNdx);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramExecutor::ProgramExecutor (const tcu::PixelBufferAccess& dst, int gridWidth, int gridHeight)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_dst			(dst)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridWidth	(gridWidth)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridHeight	(gridHeight)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramExecutor::~ProgramExecutor (void)
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramExecutor::setTexture (int samplerNdx, const tcu::Texture2D* texture, const tcu::Sampler& sampler)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_samplers2D[samplerNdx] = Sampler2D(texture, sampler);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramExecutor::setTexture (int samplerNdx, const tcu::TextureCube* texture, const tcu::Sampler& sampler)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_samplersCube[samplerNdx] = SamplerCube(texture, sampler);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::IVec4 computeVertexIndices (float cellWidth, float cellHeight, int gridVtxWidth, int gridVtxHeight, int x, int y)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(gridVtxHeight);
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = (int)deFloatFloor((float)x / cellWidth);
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = (int)deFloatFloor((float)y / cellHeight);
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::IVec4(y0*gridVtxWidth + x0, y0*gridVtxWidth + x0 + 1, (y0+1)*gridVtxWidth + x0, (y0+1)*gridVtxWidth + x0 + 1);
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec2 computeGridCellWeights (float cellWidth, float cellHeight, int x, int y)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float gx = (x + 0.5f) / cellWidth;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float gy = (y + 0.5f) / cellHeight;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Vec2(deFloatFrac(gx), deFloatFrac(gy));
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::RGBA toColor (tcu::Vec4 rgba)
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::RGBA(deClamp32(deRoundFloatToInt32(rgba.x()*255), 0, 255),
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deClamp32(deRoundFloatToInt32(rgba.y()*255), 0, 255),
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deClamp32(deRoundFloatToInt32(rgba.z()*255), 0, 255),
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deClamp32(deRoundFloatToInt32(rgba.w()*255), 0, 255));
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramExecutor::execute (const Shader& vertexShader, const Shader& fragmentShader, const vector<VariableValue>& uniformValues)
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int	gridVtxWidth	= m_gridWidth+1;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int gridVtxHeight	= m_gridHeight+1;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numVertices		= gridVtxWidth*gridVtxHeight;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VaryingStore varyingStore(numVertices);
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute vertex shader
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExecutionContext	execCtx(m_samplers2D, m_samplersCube);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					numPackets	= numVertices + ((numVertices%EXEC_VEC_WIDTH) ? 1 : 0);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<ShaderInput*>& inputs	= vertexShader.getInputs();
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<const Variable*>		outputs;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexShader.getOutputs(outputs);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Set uniform values
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<VariableValue>::const_iterator uniformIter = uniformValues.begin(); uniformIter != uniformValues.end(); uniformIter++)
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			execCtx.getValue(uniformIter->getVariable()) = uniformIter->getValue().value();
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int packetStart	= packetNdx*EXEC_VEC_WIDTH;
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int packetEnd	= deMin32((packetNdx+1)*EXEC_VEC_WIDTH, numVertices);
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compute values for vertex shader inputs
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<ShaderInput*>::const_iterator i = inputs.begin(); i != inputs.end(); i++)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const ShaderInput*	input	= *i;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ExecValueAccess		access	= execCtx.getValue(input->getVariable());
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int vtxNdx = packetStart; vtxNdx < packetEnd; vtxNdx++)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int		y	= (vtxNdx/gridVtxWidth);
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int		x	= vtxNdx - y*gridVtxWidth;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	xf	= (float)x / (float)(gridVtxWidth-1);
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	yf	= (float)y / (float)(gridVtxHeight-1);
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					interpolateVertexInput(access, vtxNdx-packetStart, input->getValueRange(), xf, yf);
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Execute vertex shader for packet
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vertexShader.execute(execCtx);
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Store output values
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<const Variable*>::const_iterator i = outputs.begin(); i != outputs.end(); i++)
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Variable*			output	= *i;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (deStringEqual(output->getName(), "gl_Position"))
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue; // Do not store position
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ExecConstValueAccess	access	= execCtx.getValue(output);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				VaryingStorage*			dst		= varyingStore.getStorage(output->getType(), output->getName());
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int vtxNdx = packetStart; vtxNdx < packetEnd; vtxNdx++)
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ValueAccess varyingAccess = dst->getValue(output->getType(), vtxNdx);
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					copyVarying(varyingAccess, access, vtxNdx-packetStart);
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute fragment shader
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExecutionContext execCtx(m_samplers2D, m_samplersCube);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Assign uniform values
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<VariableValue>::const_iterator i = uniformValues.begin(); i != uniformValues.end(); i++)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			execCtx.getValue(i->getVariable()) = i->getValue().value();
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<ShaderInput*>& inputs			= fragmentShader.getInputs();
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Variable*				fragColorVar	= DE_NULL;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<const Variable*>		outputs;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Find fragment shader output assigned to location 0. This is fragment color.
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentShader.getOutputs(outputs);
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<const Variable*>::const_iterator i = outputs.begin(); i != outputs.end(); i++)
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((*i)->getLayoutLocation() == 0)
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				fragColorVar = *i;
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(fragColorVar);
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int	width		= m_dst.getWidth();
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int height		= m_dst.getHeight();
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int numPackets	= (width*height)/EXEC_VEC_WIDTH + (((width*height)%EXEC_VEC_WIDTH) ? 1 : 0);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float cellWidth		= (float)width	/ (float)m_gridWidth;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float cellHeight	= (float)height	/ (float)m_gridHeight;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int packetStart	= packetNdx*EXEC_VEC_WIDTH;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int packetEnd	= deMin32((packetNdx+1)*EXEC_VEC_WIDTH, width*height);
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Interpolate varyings
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<ShaderInput*>::const_iterator i = inputs.begin(); i != inputs.end(); i++)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const ShaderInput*		input	= *i;
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ExecValueAccess			access	= execCtx.getValue(input->getVariable());
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const VariableType&		type	= input->getVariable()->getType();
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const VaryingStorage*	src		= varyingStore.getStorage(type, input->getVariable()->getName());
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \todo [2011-03-08 pyry] Part of this could be pre-computed...
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int fragNdx = packetStart; fragNdx < packetEnd; fragNdx++)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int y = fragNdx/width;
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int x = fragNdx - y*width;
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tcu::IVec4	vtxIndices	= computeVertexIndices(cellWidth, cellHeight, gridVtxWidth, gridVtxHeight, x, y);
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tcu::Vec2	weights		= computeGridCellWeights(cellWidth, cellHeight, x, y);
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					interpolateFragmentInput(access, fragNdx-packetStart,
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 src->getValue(type, vtxIndices.x()),
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 src->getValue(type, vtxIndices.y()),
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 src->getValue(type, vtxIndices.z()),
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 src->getValue(type, vtxIndices.w()),
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 weights.x(), weights.y());
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Execute fragment shader
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fragmentShader.execute(execCtx);
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Write resulting color
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ExecConstValueAccess colorValue = execCtx.getValue(fragColorVar);
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int fragNdx = packetStart; fragNdx < packetEnd; fragNdx++)
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int			y		= fragNdx/width;
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int			x		= fragNdx - y*width;
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int			cNdx	= fragNdx-packetStart;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4	c		= tcu::Vec4(colorValue.component(0).asFloat(cNdx),
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												colorValue.component(1).asFloat(cNdx),
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												colorValue.component(2).asFloat(cNdx),
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												colorValue.component(3).asFloat(cNdx));
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \todo [2012-11-13 pyry] Reverse order.
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_dst.setPixel(c, x, m_dst.getHeight()-y-1);
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // rsg
361