xref: /aosp_15_r20/external/deqp/modules/glshared/glsRandomShaderProgram.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL (ES) Module
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 sglr-rsg adaptation.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "glsRandomShaderProgram.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "rsgShader.hpp"
26*35238bceSAndroid Build Coastguard Worker 
27*35238bceSAndroid Build Coastguard Worker namespace deqp
28*35238bceSAndroid Build Coastguard Worker {
29*35238bceSAndroid Build Coastguard Worker namespace gls
30*35238bceSAndroid Build Coastguard Worker {
31*35238bceSAndroid Build Coastguard Worker 
32*35238bceSAndroid Build Coastguard Worker using std::vector;
33*35238bceSAndroid Build Coastguard Worker 
mapToGenericVecType(const rsg::VariableType & varType)34*35238bceSAndroid Build Coastguard Worker static rr::GenericVecType mapToGenericVecType(const rsg::VariableType &varType)
35*35238bceSAndroid Build Coastguard Worker {
36*35238bceSAndroid Build Coastguard Worker     if (varType.isFloatOrVec())
37*35238bceSAndroid Build Coastguard Worker         return rr::GENERICVECTYPE_FLOAT;
38*35238bceSAndroid Build Coastguard Worker     else if (varType.isIntOrVec())
39*35238bceSAndroid Build Coastguard Worker         return rr::GENERICVECTYPE_INT32;
40*35238bceSAndroid Build Coastguard Worker     else
41*35238bceSAndroid Build Coastguard Worker     {
42*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
43*35238bceSAndroid Build Coastguard Worker         return rr::GENERICVECTYPE_LAST;
44*35238bceSAndroid Build Coastguard Worker     }
45*35238bceSAndroid Build Coastguard Worker }
46*35238bceSAndroid Build Coastguard Worker 
mapToBasicType(const rsg::VariableType & varType)47*35238bceSAndroid Build Coastguard Worker static glu::DataType mapToBasicType(const rsg::VariableType &varType)
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker     if (varType.isFloatOrVec() || varType.isIntOrVec() || varType.isBoolOrVec())
50*35238bceSAndroid Build Coastguard Worker     {
51*35238bceSAndroid Build Coastguard Worker         const glu::DataType scalarType = varType.isFloatOrVec() ? glu::TYPE_FLOAT :
52*35238bceSAndroid Build Coastguard Worker                                          varType.isIntOrVec()   ? glu::TYPE_INT :
53*35238bceSAndroid Build Coastguard Worker                                          varType.isBoolOrVec()  ? glu::TYPE_BOOL :
54*35238bceSAndroid Build Coastguard Worker                                                                   glu::TYPE_LAST;
55*35238bceSAndroid Build Coastguard Worker         const int numComps             = varType.getNumElements();
56*35238bceSAndroid Build Coastguard Worker 
57*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(de::inRange(numComps, 1, 4));
58*35238bceSAndroid Build Coastguard Worker         return glu::DataType(scalarType + numComps - 1);
59*35238bceSAndroid Build Coastguard Worker     }
60*35238bceSAndroid Build Coastguard Worker     else if (varType.getBaseType() == rsg::VariableType::TYPE_SAMPLER_2D)
61*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_SAMPLER_2D;
62*35238bceSAndroid Build Coastguard Worker     else if (varType.getBaseType() == rsg::VariableType::TYPE_SAMPLER_CUBE)
63*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_SAMPLER_CUBE;
64*35238bceSAndroid Build Coastguard Worker     else
65*35238bceSAndroid Build Coastguard Worker     {
66*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
67*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_LAST;
68*35238bceSAndroid Build Coastguard Worker     }
69*35238bceSAndroid Build Coastguard Worker }
70*35238bceSAndroid Build Coastguard Worker 
generateProgramDeclaration(sglr::pdec::ShaderProgramDeclaration & decl,const rsg::Shader & vertexShader,const rsg::Shader & fragmentShader,int numUnifiedUniforms,const rsg::ShaderInput * const * unifiedUniforms)71*35238bceSAndroid Build Coastguard Worker static void generateProgramDeclaration(sglr::pdec::ShaderProgramDeclaration &decl, const rsg::Shader &vertexShader,
72*35238bceSAndroid Build Coastguard Worker                                        const rsg::Shader &fragmentShader, int numUnifiedUniforms,
73*35238bceSAndroid Build Coastguard Worker                                        const rsg::ShaderInput *const *unifiedUniforms)
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::VertexSource(vertexShader.getSource())
76*35238bceSAndroid Build Coastguard Worker          << sglr::pdec::FragmentSource(fragmentShader.getSource());
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker     for (vector<rsg::ShaderInput *>::const_iterator vtxInIter = vertexShader.getInputs().begin();
79*35238bceSAndroid Build Coastguard Worker          vtxInIter != vertexShader.getInputs().end(); ++vtxInIter)
80*35238bceSAndroid Build Coastguard Worker     {
81*35238bceSAndroid Build Coastguard Worker         const rsg::ShaderInput *vertexInput = *vtxInIter;
82*35238bceSAndroid Build Coastguard Worker         decl << sglr::pdec::VertexAttribute(vertexInput->getVariable()->getName(),
83*35238bceSAndroid Build Coastguard Worker                                             mapToGenericVecType(vertexInput->getVariable()->getType()));
84*35238bceSAndroid Build Coastguard Worker     }
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker     for (vector<rsg::ShaderInput *>::const_iterator fragInIter = fragmentShader.getInputs().begin();
87*35238bceSAndroid Build Coastguard Worker          fragInIter != fragmentShader.getInputs().end(); ++fragInIter)
88*35238bceSAndroid Build Coastguard Worker     {
89*35238bceSAndroid Build Coastguard Worker         const rsg::ShaderInput *fragInput = *fragInIter;
90*35238bceSAndroid Build Coastguard Worker         decl << sglr::pdec::VertexToFragmentVarying(mapToGenericVecType(fragInput->getVariable()->getType()));
91*35238bceSAndroid Build Coastguard Worker     }
92*35238bceSAndroid Build Coastguard Worker 
93*35238bceSAndroid Build Coastguard Worker     for (int uniformNdx = 0; uniformNdx < numUnifiedUniforms; uniformNdx++)
94*35238bceSAndroid Build Coastguard Worker     {
95*35238bceSAndroid Build Coastguard Worker         const rsg::ShaderInput *uniform = unifiedUniforms[uniformNdx];
96*35238bceSAndroid Build Coastguard Worker         decl << sglr::pdec::Uniform(uniform->getVariable()->getName(),
97*35238bceSAndroid Build Coastguard Worker                                     mapToBasicType(uniform->getVariable()->getType()));
98*35238bceSAndroid Build Coastguard Worker     }
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT);
101*35238bceSAndroid Build Coastguard Worker }
102*35238bceSAndroid Build Coastguard Worker 
generateProgramDeclaration(const rsg::Shader & vertexShader,const rsg::Shader & fragmentShader,int numUnifiedUniforms,const rsg::ShaderInput * const * unifiedUniforms)103*35238bceSAndroid Build Coastguard Worker static sglr::pdec::ShaderProgramDeclaration generateProgramDeclaration(const rsg::Shader &vertexShader,
104*35238bceSAndroid Build Coastguard Worker                                                                        const rsg::Shader &fragmentShader,
105*35238bceSAndroid Build Coastguard Worker                                                                        int numUnifiedUniforms,
106*35238bceSAndroid Build Coastguard Worker                                                                        const rsg::ShaderInput *const *unifiedUniforms)
107*35238bceSAndroid Build Coastguard Worker {
108*35238bceSAndroid Build Coastguard Worker     sglr::pdec::ShaderProgramDeclaration decl;
109*35238bceSAndroid Build Coastguard Worker     generateProgramDeclaration(decl, vertexShader, fragmentShader, numUnifiedUniforms, unifiedUniforms);
110*35238bceSAndroid Build Coastguard Worker     return decl;
111*35238bceSAndroid Build Coastguard Worker }
112*35238bceSAndroid Build Coastguard Worker 
findShaderOutputByName(const rsg::Shader & shader,const char * name)113*35238bceSAndroid Build Coastguard Worker static const rsg::Variable *findShaderOutputByName(const rsg::Shader &shader, const char *name)
114*35238bceSAndroid Build Coastguard Worker {
115*35238bceSAndroid Build Coastguard Worker     vector<const rsg::Variable *> outputs;
116*35238bceSAndroid Build Coastguard Worker     shader.getOutputs(outputs);
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker     for (vector<const rsg::Variable *>::const_iterator iter = outputs.begin(); iter != outputs.end(); ++iter)
119*35238bceSAndroid Build Coastguard Worker     {
120*35238bceSAndroid Build Coastguard Worker         if (deStringEqual((*iter)->getName(), name))
121*35238bceSAndroid Build Coastguard Worker             return *iter;
122*35238bceSAndroid Build Coastguard Worker     }
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker     return DE_NULL;
125*35238bceSAndroid Build Coastguard Worker }
126*35238bceSAndroid Build Coastguard Worker 
findShaderOutputByLocation(const rsg::Shader & shader,int location)127*35238bceSAndroid Build Coastguard Worker static const rsg::Variable *findShaderOutputByLocation(const rsg::Shader &shader, int location)
128*35238bceSAndroid Build Coastguard Worker {
129*35238bceSAndroid Build Coastguard Worker     vector<const rsg::Variable *> outputs;
130*35238bceSAndroid Build Coastguard Worker     shader.getOutputs(outputs);
131*35238bceSAndroid Build Coastguard Worker 
132*35238bceSAndroid Build Coastguard Worker     for (vector<const rsg::Variable *>::const_iterator iter = outputs.begin(); iter != outputs.end(); iter++)
133*35238bceSAndroid Build Coastguard Worker     {
134*35238bceSAndroid Build Coastguard Worker         if ((*iter)->getLayoutLocation() == location)
135*35238bceSAndroid Build Coastguard Worker             return *iter;
136*35238bceSAndroid Build Coastguard Worker     }
137*35238bceSAndroid Build Coastguard Worker 
138*35238bceSAndroid Build Coastguard Worker     return DE_NULL;
139*35238bceSAndroid Build Coastguard Worker }
140*35238bceSAndroid Build Coastguard Worker 
RandomShaderProgram(const rsg::Shader & vertexShader,const rsg::Shader & fragmentShader,int numUnifiedUniforms,const rsg::ShaderInput * const * unifiedUniforms)141*35238bceSAndroid Build Coastguard Worker RandomShaderProgram::RandomShaderProgram(const rsg::Shader &vertexShader, const rsg::Shader &fragmentShader,
142*35238bceSAndroid Build Coastguard Worker                                          int numUnifiedUniforms, const rsg::ShaderInput *const *unifiedUniforms)
143*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(generateProgramDeclaration(vertexShader, fragmentShader, numUnifiedUniforms, unifiedUniforms))
144*35238bceSAndroid Build Coastguard Worker     , m_vertexShader(vertexShader)
145*35238bceSAndroid Build Coastguard Worker     , m_fragmentShader(fragmentShader)
146*35238bceSAndroid Build Coastguard Worker     , m_numUnifiedUniforms(numUnifiedUniforms)
147*35238bceSAndroid Build Coastguard Worker     , m_unifiedUniforms(unifiedUniforms)
148*35238bceSAndroid Build Coastguard Worker     , m_positionVar(findShaderOutputByName(vertexShader, "gl_Position"))
149*35238bceSAndroid Build Coastguard Worker     , m_fragColorVar(findShaderOutputByLocation(fragmentShader, 0))
150*35238bceSAndroid Build Coastguard Worker     , m_execCtx(m_sampler2DMap, m_samplerCubeMap)
151*35238bceSAndroid Build Coastguard Worker {
152*35238bceSAndroid Build Coastguard Worker     TCU_CHECK_INTERNAL(m_positionVar && m_positionVar->getType().getBaseType() == rsg::VariableType::TYPE_FLOAT &&
153*35238bceSAndroid Build Coastguard Worker                        m_positionVar->getType().getNumElements() == 4);
154*35238bceSAndroid Build Coastguard Worker     TCU_CHECK_INTERNAL(m_fragColorVar && m_fragColorVar->getType().getBaseType() == rsg::VariableType::TYPE_FLOAT &&
155*35238bceSAndroid Build Coastguard Worker                        m_fragColorVar->getType().getNumElements() == 4);
156*35238bceSAndroid Build Coastguard Worker 
157*35238bceSAndroid Build Coastguard Worker     // Build list of vertex outputs.
158*35238bceSAndroid Build Coastguard Worker     for (vector<rsg::ShaderInput *>::const_iterator fragInIter = fragmentShader.getInputs().begin();
159*35238bceSAndroid Build Coastguard Worker          fragInIter != fragmentShader.getInputs().end(); ++fragInIter)
160*35238bceSAndroid Build Coastguard Worker     {
161*35238bceSAndroid Build Coastguard Worker         const rsg::ShaderInput *fragInput = *fragInIter;
162*35238bceSAndroid Build Coastguard Worker         const rsg::Variable *vertexOutput = findShaderOutputByName(vertexShader, fragInput->getVariable()->getName());
163*35238bceSAndroid Build Coastguard Worker 
164*35238bceSAndroid Build Coastguard Worker         TCU_CHECK_INTERNAL(vertexOutput);
165*35238bceSAndroid Build Coastguard Worker         m_vertexOutputs.push_back(vertexOutput);
166*35238bceSAndroid Build Coastguard Worker     }
167*35238bceSAndroid Build Coastguard Worker }
168*35238bceSAndroid Build Coastguard Worker 
refreshUniforms(void) const169*35238bceSAndroid Build Coastguard Worker void RandomShaderProgram::refreshUniforms(void) const
170*35238bceSAndroid Build Coastguard Worker {
171*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_numUnifiedUniforms == (int)m_uniforms.size());
172*35238bceSAndroid Build Coastguard Worker 
173*35238bceSAndroid Build Coastguard Worker     for (int uniformNdx = 0; uniformNdx < m_numUnifiedUniforms; uniformNdx++)
174*35238bceSAndroid Build Coastguard Worker     {
175*35238bceSAndroid Build Coastguard Worker         const rsg::Variable *uniformVar      = m_unifiedUniforms[uniformNdx]->getVariable();
176*35238bceSAndroid Build Coastguard Worker         const rsg::VariableType &uniformType = uniformVar->getType();
177*35238bceSAndroid Build Coastguard Worker         const sglr::UniformSlot &uniformSlot = m_uniforms[uniformNdx];
178*35238bceSAndroid Build Coastguard Worker 
179*35238bceSAndroid Build Coastguard Worker         m_execCtx.getValue(uniformVar) =
180*35238bceSAndroid Build Coastguard Worker             rsg::ConstValueAccess(uniformType, (const rsg::Scalar *)&uniformSlot.value).value();
181*35238bceSAndroid Build Coastguard Worker     }
182*35238bceSAndroid Build Coastguard Worker }
183*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const184*35238bceSAndroid Build Coastguard Worker void RandomShaderProgram::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
185*35238bceSAndroid Build Coastguard Worker                                         const int numPackets) const
186*35238bceSAndroid Build Coastguard Worker {
187*35238bceSAndroid Build Coastguard Worker     // \todo [2013-12-13 pyry] Do only when necessary.
188*35238bceSAndroid Build Coastguard Worker     refreshUniforms();
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker     int packetOffset = 0;
191*35238bceSAndroid Build Coastguard Worker 
192*35238bceSAndroid Build Coastguard Worker     while (packetOffset < numPackets)
193*35238bceSAndroid Build Coastguard Worker     {
194*35238bceSAndroid Build Coastguard Worker         const int numToExecute = de::min(numPackets - packetOffset, (int)rsg::EXEC_VEC_WIDTH);
195*35238bceSAndroid Build Coastguard Worker 
196*35238bceSAndroid Build Coastguard Worker         // Fetch attributes.
197*35238bceSAndroid Build Coastguard Worker         for (int attribNdx = 0; attribNdx < (int)m_vertexShader.getInputs().size(); ++attribNdx)
198*35238bceSAndroid Build Coastguard Worker         {
199*35238bceSAndroid Build Coastguard Worker             const rsg::Variable *attribVar      = m_vertexShader.getInputs()[attribNdx]->getVariable();
200*35238bceSAndroid Build Coastguard Worker             const rsg::VariableType &attribType = attribVar->getType();
201*35238bceSAndroid Build Coastguard Worker             const int numComponents             = attribType.getNumElements();
202*35238bceSAndroid Build Coastguard Worker             rsg::ExecValueAccess access         = m_execCtx.getValue(attribVar);
203*35238bceSAndroid Build Coastguard Worker 
204*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(attribType.isFloatOrVec() && de::inRange(numComponents, 1, 4));
205*35238bceSAndroid Build Coastguard Worker 
206*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < numToExecute; ndx++)
207*35238bceSAndroid Build Coastguard Worker             {
208*35238bceSAndroid Build Coastguard Worker                 const int packetNdx            = ndx + packetOffset;
209*35238bceSAndroid Build Coastguard Worker                 const rr::VertexPacket *packet = packets[packetNdx];
210*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 attribValue =
211*35238bceSAndroid Build Coastguard Worker                     rr::readVertexAttribFloat(inputs[attribNdx], packet->instanceNdx, packet->vertexNdx);
212*35238bceSAndroid Build Coastguard Worker 
213*35238bceSAndroid Build Coastguard Worker                 access.component(0).asFloat(ndx) = attribValue[0];
214*35238bceSAndroid Build Coastguard Worker                 if (numComponents >= 2)
215*35238bceSAndroid Build Coastguard Worker                     access.component(1).asFloat(ndx) = attribValue[1];
216*35238bceSAndroid Build Coastguard Worker                 if (numComponents >= 3)
217*35238bceSAndroid Build Coastguard Worker                     access.component(2).asFloat(ndx) = attribValue[2];
218*35238bceSAndroid Build Coastguard Worker                 if (numComponents >= 4)
219*35238bceSAndroid Build Coastguard Worker                     access.component(3).asFloat(ndx) = attribValue[3];
220*35238bceSAndroid Build Coastguard Worker             }
221*35238bceSAndroid Build Coastguard Worker         }
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker         m_vertexShader.execute(m_execCtx);
224*35238bceSAndroid Build Coastguard Worker 
225*35238bceSAndroid Build Coastguard Worker         // Store position
226*35238bceSAndroid Build Coastguard Worker         {
227*35238bceSAndroid Build Coastguard Worker             const rsg::ExecConstValueAccess access = m_execCtx.getValue(m_positionVar);
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < numToExecute; ndx++)
230*35238bceSAndroid Build Coastguard Worker             {
231*35238bceSAndroid Build Coastguard Worker                 const int packetNdx      = ndx + packetOffset;
232*35238bceSAndroid Build Coastguard Worker                 rr::VertexPacket *packet = packets[packetNdx];
233*35238bceSAndroid Build Coastguard Worker 
234*35238bceSAndroid Build Coastguard Worker                 packet->position[0] = access.component(0).asFloat(ndx);
235*35238bceSAndroid Build Coastguard Worker                 packet->position[1] = access.component(1).asFloat(ndx);
236*35238bceSAndroid Build Coastguard Worker                 packet->position[2] = access.component(2).asFloat(ndx);
237*35238bceSAndroid Build Coastguard Worker                 packet->position[3] = access.component(3).asFloat(ndx);
238*35238bceSAndroid Build Coastguard Worker             }
239*35238bceSAndroid Build Coastguard Worker         }
240*35238bceSAndroid Build Coastguard Worker 
241*35238bceSAndroid Build Coastguard Worker         // Other varyings
242*35238bceSAndroid Build Coastguard Worker         for (int varNdx = 0; varNdx < (int)m_vertexOutputs.size(); varNdx++)
243*35238bceSAndroid Build Coastguard Worker         {
244*35238bceSAndroid Build Coastguard Worker             const rsg::Variable *var               = m_vertexOutputs[varNdx];
245*35238bceSAndroid Build Coastguard Worker             const rsg::VariableType &varType       = var->getType();
246*35238bceSAndroid Build Coastguard Worker             const int numComponents                = varType.getNumElements();
247*35238bceSAndroid Build Coastguard Worker             const rsg::ExecConstValueAccess access = m_execCtx.getValue(var);
248*35238bceSAndroid Build Coastguard Worker 
249*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(varType.isFloatOrVec() && de::inRange(numComponents, 1, 4));
250*35238bceSAndroid Build Coastguard Worker 
251*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < numToExecute; ndx++)
252*35238bceSAndroid Build Coastguard Worker             {
253*35238bceSAndroid Build Coastguard Worker                 const int packetNdx            = ndx + packetOffset;
254*35238bceSAndroid Build Coastguard Worker                 rr::VertexPacket *const packet = packets[packetNdx];
255*35238bceSAndroid Build Coastguard Worker                 float *const dst               = packet->outputs[varNdx].getAccess<float>();
256*35238bceSAndroid Build Coastguard Worker 
257*35238bceSAndroid Build Coastguard Worker                 dst[0] = access.component(0).asFloat(ndx);
258*35238bceSAndroid Build Coastguard Worker                 if (numComponents >= 2)
259*35238bceSAndroid Build Coastguard Worker                     dst[1] = access.component(1).asFloat(ndx);
260*35238bceSAndroid Build Coastguard Worker                 if (numComponents >= 3)
261*35238bceSAndroid Build Coastguard Worker                     dst[2] = access.component(2).asFloat(ndx);
262*35238bceSAndroid Build Coastguard Worker                 if (numComponents >= 4)
263*35238bceSAndroid Build Coastguard Worker                     dst[3] = access.component(3).asFloat(ndx);
264*35238bceSAndroid Build Coastguard Worker             }
265*35238bceSAndroid Build Coastguard Worker         }
266*35238bceSAndroid Build Coastguard Worker 
267*35238bceSAndroid Build Coastguard Worker         packetOffset += numToExecute;
268*35238bceSAndroid Build Coastguard Worker     }
269*35238bceSAndroid Build Coastguard Worker }
270*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const271*35238bceSAndroid Build Coastguard Worker void RandomShaderProgram::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
272*35238bceSAndroid Build Coastguard Worker                                          const rr::FragmentShadingContext &context) const
273*35238bceSAndroid Build Coastguard Worker {
274*35238bceSAndroid Build Coastguard Worker     const rsg::ExecConstValueAccess fragColorAccess = m_execCtx.getValue(m_fragColorVar);
275*35238bceSAndroid Build Coastguard Worker     int packetOffset                                = 0;
276*35238bceSAndroid Build Coastguard Worker 
277*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(rsg::EXEC_VEC_WIDTH % rr::NUM_FRAGMENTS_PER_PACKET == 0);
278*35238bceSAndroid Build Coastguard Worker 
279*35238bceSAndroid Build Coastguard Worker     while (packetOffset < numPackets)
280*35238bceSAndroid Build Coastguard Worker     {
281*35238bceSAndroid Build Coastguard Worker         const int numPacketsToExecute =
282*35238bceSAndroid Build Coastguard Worker             de::min(numPackets - packetOffset, (int)rsg::EXEC_VEC_WIDTH / (int)rr::NUM_FRAGMENTS_PER_PACKET);
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker         // Interpolate varyings.
285*35238bceSAndroid Build Coastguard Worker         for (int varNdx = 0; varNdx < (int)m_fragmentShader.getInputs().size(); ++varNdx)
286*35238bceSAndroid Build Coastguard Worker         {
287*35238bceSAndroid Build Coastguard Worker             const rsg::Variable *var         = m_fragmentShader.getInputs()[varNdx]->getVariable();
288*35238bceSAndroid Build Coastguard Worker             const rsg::VariableType &varType = var->getType();
289*35238bceSAndroid Build Coastguard Worker             const int numComponents          = varType.getNumElements();
290*35238bceSAndroid Build Coastguard Worker             rsg::ExecValueAccess access      = m_execCtx.getValue(var);
291*35238bceSAndroid Build Coastguard Worker 
292*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(varType.isFloatOrVec() && de::inRange(numComponents, 1, 4));
293*35238bceSAndroid Build Coastguard Worker 
294*35238bceSAndroid Build Coastguard Worker             for (int packetNdx = 0; packetNdx < numPacketsToExecute; packetNdx++)
295*35238bceSAndroid Build Coastguard Worker             {
296*35238bceSAndroid Build Coastguard Worker                 const rr::FragmentPacket &packet = packets[packetOffset + packetNdx];
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker                 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
299*35238bceSAndroid Build Coastguard Worker                 {
300*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec4 varValue = rr::readVarying<float>(packet, context, varNdx, fragNdx);
301*35238bceSAndroid Build Coastguard Worker                     const int dstNdx         = packetNdx * rr::NUM_FRAGMENTS_PER_PACKET + fragNdx;
302*35238bceSAndroid Build Coastguard Worker 
303*35238bceSAndroid Build Coastguard Worker                     access.component(0).asFloat(dstNdx) = varValue[0];
304*35238bceSAndroid Build Coastguard Worker                     if (numComponents >= 2)
305*35238bceSAndroid Build Coastguard Worker                         access.component(1).asFloat(dstNdx) = varValue[1];
306*35238bceSAndroid Build Coastguard Worker                     if (numComponents >= 3)
307*35238bceSAndroid Build Coastguard Worker                         access.component(2).asFloat(dstNdx) = varValue[2];
308*35238bceSAndroid Build Coastguard Worker                     if (numComponents >= 4)
309*35238bceSAndroid Build Coastguard Worker                         access.component(3).asFloat(dstNdx) = varValue[3];
310*35238bceSAndroid Build Coastguard Worker                 }
311*35238bceSAndroid Build Coastguard Worker             }
312*35238bceSAndroid Build Coastguard Worker         }
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker         m_fragmentShader.execute(m_execCtx);
315*35238bceSAndroid Build Coastguard Worker 
316*35238bceSAndroid Build Coastguard Worker         // Store color
317*35238bceSAndroid Build Coastguard Worker         for (int packetNdx = 0; packetNdx < numPacketsToExecute; packetNdx++)
318*35238bceSAndroid Build Coastguard Worker         {
319*35238bceSAndroid Build Coastguard Worker             for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
320*35238bceSAndroid Build Coastguard Worker             {
321*35238bceSAndroid Build Coastguard Worker                 const int srcNdx = packetNdx * rr::NUM_FRAGMENTS_PER_PACKET + fragNdx;
322*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 color(
323*35238bceSAndroid Build Coastguard Worker                     fragColorAccess.component(0).asFloat(srcNdx), fragColorAccess.component(1).asFloat(srcNdx),
324*35238bceSAndroid Build Coastguard Worker                     fragColorAccess.component(2).asFloat(srcNdx), fragColorAccess.component(3).asFloat(srcNdx));
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker                 rr::writeFragmentOutput(context, packetOffset + packetNdx, fragNdx, 0, color);
327*35238bceSAndroid Build Coastguard Worker             }
328*35238bceSAndroid Build Coastguard Worker         }
329*35238bceSAndroid Build Coastguard Worker 
330*35238bceSAndroid Build Coastguard Worker         packetOffset += numPacketsToExecute;
331*35238bceSAndroid Build Coastguard Worker     }
332*35238bceSAndroid Build Coastguard Worker }
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker } // namespace gls
335*35238bceSAndroid Build Coastguard Worker } // namespace deqp
336