1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Random Shader Generator
3*35238bceSAndroid Build Coastguard Worker * ----------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Program Executor.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "rsgProgramExecutor.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "rsgExecutionContext.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "rsgVariableValue.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "rsgUtils.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
30*35238bceSAndroid Build Coastguard Worker #include "deString.h"
31*35238bceSAndroid Build Coastguard Worker
32*35238bceSAndroid Build Coastguard Worker #include <set>
33*35238bceSAndroid Build Coastguard Worker #include <string>
34*35238bceSAndroid Build Coastguard Worker #include <map>
35*35238bceSAndroid Build Coastguard Worker
36*35238bceSAndroid Build Coastguard Worker using std::map;
37*35238bceSAndroid Build Coastguard Worker using std::set;
38*35238bceSAndroid Build Coastguard Worker using std::string;
39*35238bceSAndroid Build Coastguard Worker using std::vector;
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard Worker namespace rsg
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker
44*35238bceSAndroid Build Coastguard Worker class VaryingStorage
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker public:
47*35238bceSAndroid Build Coastguard Worker VaryingStorage(const VariableType &type, int numVertices);
~VaryingStorage(void)48*35238bceSAndroid Build Coastguard Worker ~VaryingStorage(void)
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker }
51*35238bceSAndroid Build Coastguard Worker
52*35238bceSAndroid Build Coastguard Worker ValueAccess getValue(const VariableType &type, int vtxNdx);
53*35238bceSAndroid Build Coastguard Worker ConstValueAccess getValue(const VariableType &type, int vtxNdx) const;
54*35238bceSAndroid Build Coastguard Worker
55*35238bceSAndroid Build Coastguard Worker private:
56*35238bceSAndroid Build Coastguard Worker std::vector<Scalar> m_value;
57*35238bceSAndroid Build Coastguard Worker };
58*35238bceSAndroid Build Coastguard Worker
VaryingStorage(const VariableType & type,int numVertices)59*35238bceSAndroid Build Coastguard Worker VaryingStorage::VaryingStorage(const VariableType &type, int numVertices) : m_value(type.getScalarSize() * numVertices)
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker }
62*35238bceSAndroid Build Coastguard Worker
getValue(const VariableType & type,int vtxNdx)63*35238bceSAndroid Build Coastguard Worker ValueAccess VaryingStorage::getValue(const VariableType &type, int vtxNdx)
64*35238bceSAndroid Build Coastguard Worker {
65*35238bceSAndroid Build Coastguard Worker return ValueAccess(type, &m_value[type.getScalarSize() * vtxNdx]);
66*35238bceSAndroid Build Coastguard Worker }
67*35238bceSAndroid Build Coastguard Worker
getValue(const VariableType & type,int vtxNdx) const68*35238bceSAndroid Build Coastguard Worker ConstValueAccess VaryingStorage::getValue(const VariableType &type, int vtxNdx) const
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker return ConstValueAccess(type, &m_value[type.getScalarSize() * vtxNdx]);
71*35238bceSAndroid Build Coastguard Worker }
72*35238bceSAndroid Build Coastguard Worker
73*35238bceSAndroid Build Coastguard Worker class VaryingStore
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker public:
76*35238bceSAndroid Build Coastguard Worker VaryingStore(int numVertices);
77*35238bceSAndroid Build Coastguard Worker ~VaryingStore(void);
78*35238bceSAndroid Build Coastguard Worker
79*35238bceSAndroid Build Coastguard Worker VaryingStorage *getStorage(const VariableType &type, const char *name);
80*35238bceSAndroid Build Coastguard Worker
81*35238bceSAndroid Build Coastguard Worker private:
82*35238bceSAndroid Build Coastguard Worker int m_numVertices;
83*35238bceSAndroid Build Coastguard Worker std::map<std::string, VaryingStorage *> m_values;
84*35238bceSAndroid Build Coastguard Worker };
85*35238bceSAndroid Build Coastguard Worker
VaryingStore(int numVertices)86*35238bceSAndroid Build Coastguard Worker VaryingStore::VaryingStore(int numVertices) : m_numVertices(numVertices)
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker
~VaryingStore(void)90*35238bceSAndroid Build Coastguard Worker VaryingStore::~VaryingStore(void)
91*35238bceSAndroid Build Coastguard Worker {
92*35238bceSAndroid Build Coastguard Worker for (map<string, VaryingStorage *>::iterator i = m_values.begin(); i != m_values.end(); i++)
93*35238bceSAndroid Build Coastguard Worker delete i->second;
94*35238bceSAndroid Build Coastguard Worker m_values.clear();
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker
getStorage(const VariableType & type,const char * name)97*35238bceSAndroid Build Coastguard Worker VaryingStorage *VaryingStore::getStorage(const VariableType &type, const char *name)
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker VaryingStorage *storage = m_values[name];
100*35238bceSAndroid Build Coastguard Worker
101*35238bceSAndroid Build Coastguard Worker if (!storage)
102*35238bceSAndroid Build Coastguard Worker {
103*35238bceSAndroid Build Coastguard Worker storage = new VaryingStorage(type, m_numVertices);
104*35238bceSAndroid Build Coastguard Worker m_values[name] = storage;
105*35238bceSAndroid Build Coastguard Worker }
106*35238bceSAndroid Build Coastguard Worker
107*35238bceSAndroid Build Coastguard Worker return storage;
108*35238bceSAndroid Build Coastguard Worker }
109*35238bceSAndroid Build Coastguard Worker
interpolateVertexQuad(const tcu::Vec4 & quad,float x,float y)110*35238bceSAndroid Build Coastguard Worker inline float interpolateVertexQuad(const tcu::Vec4 &quad, float x, float y)
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker float w00 = (1.0f - x) * (1.0f - y);
113*35238bceSAndroid Build Coastguard Worker float w01 = (1.0f - x) * y;
114*35238bceSAndroid Build Coastguard Worker float w10 = x * (1.0f - y);
115*35238bceSAndroid Build Coastguard Worker float w11 = x * y;
116*35238bceSAndroid Build Coastguard Worker return quad.x() * w00 + quad.y() * w10 + quad.z() * w01 + quad.w() * w11;
117*35238bceSAndroid Build Coastguard Worker }
118*35238bceSAndroid Build Coastguard Worker
interpolateVertex(float x0y0,float x1y1,float x,float y)119*35238bceSAndroid Build Coastguard Worker inline float interpolateVertex(float x0y0, float x1y1, float x, float y)
120*35238bceSAndroid Build Coastguard Worker {
121*35238bceSAndroid Build Coastguard Worker return interpolateVertexQuad(tcu::Vec4(x0y0, (x0y0 + x1y1) * 0.5f, (x0y0 + x1y1) * 0.5f, x1y1), x, y);
122*35238bceSAndroid Build Coastguard Worker }
123*35238bceSAndroid Build Coastguard Worker
interpolateTri(float v0,float v1,float v2,float x,float y)124*35238bceSAndroid Build Coastguard Worker inline float interpolateTri(float v0, float v1, float v2, float x, float y)
125*35238bceSAndroid Build Coastguard Worker {
126*35238bceSAndroid Build Coastguard Worker return v0 + (v1 - v0) * x + (v2 - v0) * y;
127*35238bceSAndroid Build Coastguard Worker }
128*35238bceSAndroid Build Coastguard Worker
interpolateFragment(const tcu::Vec4 & quad,float x,float y)129*35238bceSAndroid Build Coastguard Worker inline float interpolateFragment(const tcu::Vec4 &quad, float x, float y)
130*35238bceSAndroid Build Coastguard Worker {
131*35238bceSAndroid Build Coastguard Worker if (x + y < 1.0f)
132*35238bceSAndroid Build Coastguard Worker return interpolateTri(quad.x(), quad.y(), quad.z(), x, y);
133*35238bceSAndroid Build Coastguard Worker else
134*35238bceSAndroid Build Coastguard Worker return interpolateTri(quad.w(), quad.z(), quad.y(), 1.0f - x, 1.0f - y);
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker
137*35238bceSAndroid Build Coastguard Worker template <int Stride>
interpolateVertexInput(StridedValueAccess<Stride> dst,int dstComp,const ConstValueRangeAccess valueRange,float x,float y)138*35238bceSAndroid Build Coastguard Worker void interpolateVertexInput(StridedValueAccess<Stride> dst, int dstComp, const ConstValueRangeAccess valueRange,
139*35238bceSAndroid Build Coastguard Worker float x, float y)
140*35238bceSAndroid Build Coastguard Worker {
141*35238bceSAndroid Build Coastguard Worker TCU_CHECK(valueRange.getType().getBaseType() == VariableType::TYPE_FLOAT);
142*35238bceSAndroid Build Coastguard Worker int numElements = valueRange.getType().getNumElements();
143*35238bceSAndroid Build Coastguard Worker for (int elementNdx = 0; elementNdx < numElements; elementNdx++)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker float xd, yd;
146*35238bceSAndroid Build Coastguard Worker getVertexInterpolationCoords(xd, yd, x, y, elementNdx);
147*35238bceSAndroid Build Coastguard Worker dst.component(elementNdx).asFloat(dstComp) =
148*35238bceSAndroid Build Coastguard Worker interpolateVertex(valueRange.getMin().component(elementNdx).asFloat(),
149*35238bceSAndroid Build Coastguard Worker valueRange.getMax().component(elementNdx).asFloat(), xd, yd);
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker }
152*35238bceSAndroid Build Coastguard Worker
153*35238bceSAndroid Build Coastguard Worker template <int Stride>
interpolateFragmentInput(StridedValueAccess<Stride> dst,int dstComp,ConstValueAccess vtx0,ConstValueAccess vtx1,ConstValueAccess vtx2,ConstValueAccess vtx3,float x,float y)154*35238bceSAndroid Build Coastguard Worker void interpolateFragmentInput(StridedValueAccess<Stride> dst, int dstComp, ConstValueAccess vtx0, ConstValueAccess vtx1,
155*35238bceSAndroid Build Coastguard Worker ConstValueAccess vtx2, ConstValueAccess vtx3, float x, float y)
156*35238bceSAndroid Build Coastguard Worker {
157*35238bceSAndroid Build Coastguard Worker TCU_CHECK(dst.getType().getBaseType() == VariableType::TYPE_FLOAT);
158*35238bceSAndroid Build Coastguard Worker int numElements = dst.getType().getNumElements();
159*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numElements; ndx++)
160*35238bceSAndroid Build Coastguard Worker dst.component(ndx).asFloat(dstComp) =
161*35238bceSAndroid Build Coastguard Worker interpolateFragment(tcu::Vec4(vtx0.component(ndx).asFloat(), vtx1.component(ndx).asFloat(),
162*35238bceSAndroid Build Coastguard Worker vtx2.component(ndx).asFloat(), vtx3.component(ndx).asFloat()),
163*35238bceSAndroid Build Coastguard Worker x, y);
164*35238bceSAndroid Build Coastguard Worker }
165*35238bceSAndroid Build Coastguard Worker
166*35238bceSAndroid Build Coastguard Worker template <int Stride>
copyVarying(ValueAccess dst,ConstStridedValueAccess<Stride> src,int compNdx)167*35238bceSAndroid Build Coastguard Worker void copyVarying(ValueAccess dst, ConstStridedValueAccess<Stride> src, int compNdx)
168*35238bceSAndroid Build Coastguard Worker {
169*35238bceSAndroid Build Coastguard Worker TCU_CHECK(dst.getType().getBaseType() == VariableType::TYPE_FLOAT);
170*35238bceSAndroid Build Coastguard Worker for (int elemNdx = 0; elemNdx < dst.getType().getNumElements(); elemNdx++)
171*35238bceSAndroid Build Coastguard Worker dst.component(elemNdx).asFloat() = src.component(elemNdx).asFloat(compNdx);
172*35238bceSAndroid Build Coastguard Worker }
173*35238bceSAndroid Build Coastguard Worker
ProgramExecutor(const tcu::PixelBufferAccess & dst,int gridWidth,int gridHeight)174*35238bceSAndroid Build Coastguard Worker ProgramExecutor::ProgramExecutor(const tcu::PixelBufferAccess &dst, int gridWidth, int gridHeight)
175*35238bceSAndroid Build Coastguard Worker : m_dst(dst)
176*35238bceSAndroid Build Coastguard Worker , m_gridWidth(gridWidth)
177*35238bceSAndroid Build Coastguard Worker , m_gridHeight(gridHeight)
178*35238bceSAndroid Build Coastguard Worker {
179*35238bceSAndroid Build Coastguard Worker }
180*35238bceSAndroid Build Coastguard Worker
~ProgramExecutor(void)181*35238bceSAndroid Build Coastguard Worker ProgramExecutor::~ProgramExecutor(void)
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker }
184*35238bceSAndroid Build Coastguard Worker
setTexture(int samplerNdx,const tcu::Texture2D * texture,const tcu::Sampler & sampler)185*35238bceSAndroid Build Coastguard Worker void ProgramExecutor::setTexture(int samplerNdx, const tcu::Texture2D *texture, const tcu::Sampler &sampler)
186*35238bceSAndroid Build Coastguard Worker {
187*35238bceSAndroid Build Coastguard Worker m_samplers2D[samplerNdx] = Sampler2D(texture, sampler);
188*35238bceSAndroid Build Coastguard Worker }
189*35238bceSAndroid Build Coastguard Worker
setTexture(int samplerNdx,const tcu::TextureCube * texture,const tcu::Sampler & sampler)190*35238bceSAndroid Build Coastguard Worker void ProgramExecutor::setTexture(int samplerNdx, const tcu::TextureCube *texture, const tcu::Sampler &sampler)
191*35238bceSAndroid Build Coastguard Worker {
192*35238bceSAndroid Build Coastguard Worker m_samplersCube[samplerNdx] = SamplerCube(texture, sampler);
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker
computeVertexIndices(float cellWidth,float cellHeight,int gridVtxWidth,int gridVtxHeight,int x,int y)195*35238bceSAndroid Build Coastguard Worker inline tcu::IVec4 computeVertexIndices(float cellWidth, float cellHeight, int gridVtxWidth, int gridVtxHeight, int x,
196*35238bceSAndroid Build Coastguard Worker int y)
197*35238bceSAndroid Build Coastguard Worker {
198*35238bceSAndroid Build Coastguard Worker DE_UNREF(gridVtxHeight);
199*35238bceSAndroid Build Coastguard Worker int x0 = (int)deFloatFloor((float)x / cellWidth);
200*35238bceSAndroid Build Coastguard Worker int y0 = (int)deFloatFloor((float)y / cellHeight);
201*35238bceSAndroid Build Coastguard Worker return tcu::IVec4(y0 * gridVtxWidth + x0, y0 * gridVtxWidth + x0 + 1, (y0 + 1) * gridVtxWidth + x0,
202*35238bceSAndroid Build Coastguard Worker (y0 + 1) * gridVtxWidth + x0 + 1);
203*35238bceSAndroid Build Coastguard Worker }
204*35238bceSAndroid Build Coastguard Worker
computeGridCellWeights(float cellWidth,float cellHeight,int x,int y)205*35238bceSAndroid Build Coastguard Worker inline tcu::Vec2 computeGridCellWeights(float cellWidth, float cellHeight, int x, int y)
206*35238bceSAndroid Build Coastguard Worker {
207*35238bceSAndroid Build Coastguard Worker float gx = ((float)x + 0.5f) / cellWidth;
208*35238bceSAndroid Build Coastguard Worker float gy = ((float)y + 0.5f) / cellHeight;
209*35238bceSAndroid Build Coastguard Worker return tcu::Vec2(deFloatFrac(gx), deFloatFrac(gy));
210*35238bceSAndroid Build Coastguard Worker }
211*35238bceSAndroid Build Coastguard Worker
toColor(tcu::Vec4 rgba)212*35238bceSAndroid Build Coastguard Worker inline tcu::RGBA toColor(tcu::Vec4 rgba)
213*35238bceSAndroid Build Coastguard Worker {
214*35238bceSAndroid Build Coastguard Worker return tcu::RGBA(
215*35238bceSAndroid Build Coastguard Worker deClamp32(deRoundFloatToInt32(rgba.x() * 255), 0, 255), deClamp32(deRoundFloatToInt32(rgba.y() * 255), 0, 255),
216*35238bceSAndroid Build Coastguard Worker deClamp32(deRoundFloatToInt32(rgba.z() * 255), 0, 255), deClamp32(deRoundFloatToInt32(rgba.w() * 255), 0, 255));
217*35238bceSAndroid Build Coastguard Worker }
218*35238bceSAndroid Build Coastguard Worker
execute(const Shader & vertexShader,const Shader & fragmentShader,const vector<VariableValue> & uniformValues)219*35238bceSAndroid Build Coastguard Worker void ProgramExecutor::execute(const Shader &vertexShader, const Shader &fragmentShader,
220*35238bceSAndroid Build Coastguard Worker const vector<VariableValue> &uniformValues)
221*35238bceSAndroid Build Coastguard Worker {
222*35238bceSAndroid Build Coastguard Worker int gridVtxWidth = m_gridWidth + 1;
223*35238bceSAndroid Build Coastguard Worker int gridVtxHeight = m_gridHeight + 1;
224*35238bceSAndroid Build Coastguard Worker int numVertices = gridVtxWidth * gridVtxHeight;
225*35238bceSAndroid Build Coastguard Worker
226*35238bceSAndroid Build Coastguard Worker VaryingStore varyingStore(numVertices);
227*35238bceSAndroid Build Coastguard Worker
228*35238bceSAndroid Build Coastguard Worker // Execute vertex shader
229*35238bceSAndroid Build Coastguard Worker {
230*35238bceSAndroid Build Coastguard Worker ExecutionContext execCtx(m_samplers2D, m_samplersCube);
231*35238bceSAndroid Build Coastguard Worker int numPackets = numVertices + ((numVertices % EXEC_VEC_WIDTH) ? 1 : 0);
232*35238bceSAndroid Build Coastguard Worker
233*35238bceSAndroid Build Coastguard Worker const vector<ShaderInput *> &inputs = vertexShader.getInputs();
234*35238bceSAndroid Build Coastguard Worker vector<const Variable *> outputs;
235*35238bceSAndroid Build Coastguard Worker vertexShader.getOutputs(outputs);
236*35238bceSAndroid Build Coastguard Worker
237*35238bceSAndroid Build Coastguard Worker // Set uniform values
238*35238bceSAndroid Build Coastguard Worker for (vector<VariableValue>::const_iterator uniformIter = uniformValues.begin();
239*35238bceSAndroid Build Coastguard Worker uniformIter != uniformValues.end(); uniformIter++)
240*35238bceSAndroid Build Coastguard Worker execCtx.getValue(uniformIter->getVariable()) = uniformIter->getValue().value();
241*35238bceSAndroid Build Coastguard Worker
242*35238bceSAndroid Build Coastguard Worker for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker int packetStart = packetNdx * EXEC_VEC_WIDTH;
245*35238bceSAndroid Build Coastguard Worker int packetEnd = deMin32((packetNdx + 1) * EXEC_VEC_WIDTH, numVertices);
246*35238bceSAndroid Build Coastguard Worker
247*35238bceSAndroid Build Coastguard Worker // Compute values for vertex shader inputs
248*35238bceSAndroid Build Coastguard Worker for (vector<ShaderInput *>::const_iterator i = inputs.begin(); i != inputs.end(); i++)
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker const ShaderInput *input = *i;
251*35238bceSAndroid Build Coastguard Worker ExecValueAccess access = execCtx.getValue(input->getVariable());
252*35238bceSAndroid Build Coastguard Worker
253*35238bceSAndroid Build Coastguard Worker for (int vtxNdx = packetStart; vtxNdx < packetEnd; vtxNdx++)
254*35238bceSAndroid Build Coastguard Worker {
255*35238bceSAndroid Build Coastguard Worker int y = (vtxNdx / gridVtxWidth);
256*35238bceSAndroid Build Coastguard Worker int x = vtxNdx - y * gridVtxWidth;
257*35238bceSAndroid Build Coastguard Worker float xf = (float)x / (float)(gridVtxWidth - 1);
258*35238bceSAndroid Build Coastguard Worker float yf = (float)y / (float)(gridVtxHeight - 1);
259*35238bceSAndroid Build Coastguard Worker
260*35238bceSAndroid Build Coastguard Worker interpolateVertexInput(access, vtxNdx - packetStart, input->getValueRange(), xf, yf);
261*35238bceSAndroid Build Coastguard Worker }
262*35238bceSAndroid Build Coastguard Worker }
263*35238bceSAndroid Build Coastguard Worker
264*35238bceSAndroid Build Coastguard Worker // Execute vertex shader for packet
265*35238bceSAndroid Build Coastguard Worker vertexShader.execute(execCtx);
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker // Store output values
268*35238bceSAndroid Build Coastguard Worker for (vector<const Variable *>::const_iterator i = outputs.begin(); i != outputs.end(); i++)
269*35238bceSAndroid Build Coastguard Worker {
270*35238bceSAndroid Build Coastguard Worker const Variable *output = *i;
271*35238bceSAndroid Build Coastguard Worker
272*35238bceSAndroid Build Coastguard Worker if (deStringEqual(output->getName(), "gl_Position"))
273*35238bceSAndroid Build Coastguard Worker continue; // Do not store position
274*35238bceSAndroid Build Coastguard Worker
275*35238bceSAndroid Build Coastguard Worker ExecConstValueAccess access = execCtx.getValue(output);
276*35238bceSAndroid Build Coastguard Worker VaryingStorage *dst = varyingStore.getStorage(output->getType(), output->getName());
277*35238bceSAndroid Build Coastguard Worker
278*35238bceSAndroid Build Coastguard Worker for (int vtxNdx = packetStart; vtxNdx < packetEnd; vtxNdx++)
279*35238bceSAndroid Build Coastguard Worker {
280*35238bceSAndroid Build Coastguard Worker ValueAccess varyingAccess = dst->getValue(output->getType(), vtxNdx);
281*35238bceSAndroid Build Coastguard Worker copyVarying(varyingAccess, access, vtxNdx - packetStart);
282*35238bceSAndroid Build Coastguard Worker }
283*35238bceSAndroid Build Coastguard Worker }
284*35238bceSAndroid Build Coastguard Worker }
285*35238bceSAndroid Build Coastguard Worker }
286*35238bceSAndroid Build Coastguard Worker
287*35238bceSAndroid Build Coastguard Worker // Execute fragment shader
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker ExecutionContext execCtx(m_samplers2D, m_samplersCube);
290*35238bceSAndroid Build Coastguard Worker
291*35238bceSAndroid Build Coastguard Worker // Assign uniform values
292*35238bceSAndroid Build Coastguard Worker for (vector<VariableValue>::const_iterator i = uniformValues.begin(); i != uniformValues.end(); i++)
293*35238bceSAndroid Build Coastguard Worker execCtx.getValue(i->getVariable()) = i->getValue().value();
294*35238bceSAndroid Build Coastguard Worker
295*35238bceSAndroid Build Coastguard Worker const vector<ShaderInput *> &inputs = fragmentShader.getInputs();
296*35238bceSAndroid Build Coastguard Worker const Variable *fragColorVar = DE_NULL;
297*35238bceSAndroid Build Coastguard Worker vector<const Variable *> outputs;
298*35238bceSAndroid Build Coastguard Worker
299*35238bceSAndroid Build Coastguard Worker // Find fragment shader output assigned to location 0. This is fragment color.
300*35238bceSAndroid Build Coastguard Worker fragmentShader.getOutputs(outputs);
301*35238bceSAndroid Build Coastguard Worker for (vector<const Variable *>::const_iterator i = outputs.begin(); i != outputs.end(); i++)
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker if ((*i)->getLayoutLocation() == 0)
304*35238bceSAndroid Build Coastguard Worker {
305*35238bceSAndroid Build Coastguard Worker fragColorVar = *i;
306*35238bceSAndroid Build Coastguard Worker break;
307*35238bceSAndroid Build Coastguard Worker }
308*35238bceSAndroid Build Coastguard Worker }
309*35238bceSAndroid Build Coastguard Worker TCU_CHECK(fragColorVar);
310*35238bceSAndroid Build Coastguard Worker
311*35238bceSAndroid Build Coastguard Worker int width = m_dst.getWidth();
312*35238bceSAndroid Build Coastguard Worker int height = m_dst.getHeight();
313*35238bceSAndroid Build Coastguard Worker int numPackets = (width * height) / EXEC_VEC_WIDTH + (((width * height) % EXEC_VEC_WIDTH) ? 1 : 0);
314*35238bceSAndroid Build Coastguard Worker
315*35238bceSAndroid Build Coastguard Worker float cellWidth = (float)width / (float)m_gridWidth;
316*35238bceSAndroid Build Coastguard Worker float cellHeight = (float)height / (float)m_gridHeight;
317*35238bceSAndroid Build Coastguard Worker
318*35238bceSAndroid Build Coastguard Worker for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
319*35238bceSAndroid Build Coastguard Worker {
320*35238bceSAndroid Build Coastguard Worker int packetStart = packetNdx * EXEC_VEC_WIDTH;
321*35238bceSAndroid Build Coastguard Worker int packetEnd = deMin32((packetNdx + 1) * EXEC_VEC_WIDTH, width * height);
322*35238bceSAndroid Build Coastguard Worker
323*35238bceSAndroid Build Coastguard Worker // Interpolate varyings
324*35238bceSAndroid Build Coastguard Worker for (vector<ShaderInput *>::const_iterator i = inputs.begin(); i != inputs.end(); i++)
325*35238bceSAndroid Build Coastguard Worker {
326*35238bceSAndroid Build Coastguard Worker const ShaderInput *input = *i;
327*35238bceSAndroid Build Coastguard Worker ExecValueAccess access = execCtx.getValue(input->getVariable());
328*35238bceSAndroid Build Coastguard Worker const VariableType &type = input->getVariable()->getType();
329*35238bceSAndroid Build Coastguard Worker const VaryingStorage *src = varyingStore.getStorage(type, input->getVariable()->getName());
330*35238bceSAndroid Build Coastguard Worker
331*35238bceSAndroid Build Coastguard Worker // \todo [2011-03-08 pyry] Part of this could be pre-computed...
332*35238bceSAndroid Build Coastguard Worker for (int fragNdx = packetStart; fragNdx < packetEnd; fragNdx++)
333*35238bceSAndroid Build Coastguard Worker {
334*35238bceSAndroid Build Coastguard Worker int y = fragNdx / width;
335*35238bceSAndroid Build Coastguard Worker int x = fragNdx - y * width;
336*35238bceSAndroid Build Coastguard Worker tcu::IVec4 vtxIndices =
337*35238bceSAndroid Build Coastguard Worker computeVertexIndices(cellWidth, cellHeight, gridVtxWidth, gridVtxHeight, x, y);
338*35238bceSAndroid Build Coastguard Worker tcu::Vec2 weights = computeGridCellWeights(cellWidth, cellHeight, x, y);
339*35238bceSAndroid Build Coastguard Worker
340*35238bceSAndroid Build Coastguard Worker interpolateFragmentInput(access, fragNdx - packetStart, src->getValue(type, vtxIndices.x()),
341*35238bceSAndroid Build Coastguard Worker src->getValue(type, vtxIndices.y()), src->getValue(type, vtxIndices.z()),
342*35238bceSAndroid Build Coastguard Worker src->getValue(type, vtxIndices.w()), weights.x(), weights.y());
343*35238bceSAndroid Build Coastguard Worker }
344*35238bceSAndroid Build Coastguard Worker }
345*35238bceSAndroid Build Coastguard Worker
346*35238bceSAndroid Build Coastguard Worker // Execute fragment shader
347*35238bceSAndroid Build Coastguard Worker fragmentShader.execute(execCtx);
348*35238bceSAndroid Build Coastguard Worker
349*35238bceSAndroid Build Coastguard Worker // Write resulting color
350*35238bceSAndroid Build Coastguard Worker ExecConstValueAccess colorValue = execCtx.getValue(fragColorVar);
351*35238bceSAndroid Build Coastguard Worker for (int fragNdx = packetStart; fragNdx < packetEnd; fragNdx++)
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker int y = fragNdx / width;
354*35238bceSAndroid Build Coastguard Worker int x = fragNdx - y * width;
355*35238bceSAndroid Build Coastguard Worker int cNdx = fragNdx - packetStart;
356*35238bceSAndroid Build Coastguard Worker tcu::Vec4 c = tcu::Vec4(colorValue.component(0).asFloat(cNdx), colorValue.component(1).asFloat(cNdx),
357*35238bceSAndroid Build Coastguard Worker colorValue.component(2).asFloat(cNdx), colorValue.component(3).asFloat(cNdx));
358*35238bceSAndroid Build Coastguard Worker
359*35238bceSAndroid Build Coastguard Worker // \todo [2012-11-13 pyry] Reverse order.
360*35238bceSAndroid Build Coastguard Worker m_dst.setPixel(c, x, m_dst.getHeight() - y - 1);
361*35238bceSAndroid Build Coastguard Worker }
362*35238bceSAndroid Build Coastguard Worker }
363*35238bceSAndroid Build Coastguard Worker }
364*35238bceSAndroid Build Coastguard Worker }
365*35238bceSAndroid Build Coastguard Worker
366*35238bceSAndroid Build Coastguard Worker } // namespace rsg
367