xref: /aosp_15_r20/external/deqp/framework/randomshaders/rsgProgramExecutor.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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