xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fShaderIndexingTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 2.0 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 Shader indexing (arrays, vector, matrices) tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2fShaderIndexingTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "glsShaderRenderCase.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluShaderUtil.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
28*35238bceSAndroid Build Coastguard Worker 
29*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
30*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
31*35238bceSAndroid Build Coastguard Worker 
32*35238bceSAndroid Build Coastguard Worker #include <map>
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker using namespace std;
38*35238bceSAndroid Build Coastguard Worker using namespace tcu;
39*35238bceSAndroid Build Coastguard Worker using namespace glu;
40*35238bceSAndroid Build Coastguard Worker using namespace deqp::gls;
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker namespace deqp
43*35238bceSAndroid Build Coastguard Worker {
44*35238bceSAndroid Build Coastguard Worker namespace gles2
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker namespace Functional
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker 
49*35238bceSAndroid Build Coastguard Worker enum IndexAccessType
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker     INDEXACCESS_STATIC = 0,
52*35238bceSAndroid Build Coastguard Worker     INDEXACCESS_DYNAMIC,
53*35238bceSAndroid Build Coastguard Worker     INDEXACCESS_STATIC_LOOP,
54*35238bceSAndroid Build Coastguard Worker     INDEXACCESS_DYNAMIC_LOOP,
55*35238bceSAndroid Build Coastguard Worker 
56*35238bceSAndroid Build Coastguard Worker     /* Must be next to last, since most loop iterations won't include
57*35238bceSAndroid Build Coastguard Worker      * _CONST
58*35238bceSAndroid Build Coastguard Worker      */
59*35238bceSAndroid Build Coastguard Worker     INDEXACCESS_CONST,
60*35238bceSAndroid Build Coastguard Worker     INDEXACCESS_LAST
61*35238bceSAndroid Build Coastguard Worker };
62*35238bceSAndroid Build Coastguard Worker 
getIndexAccessTypeName(IndexAccessType accessType)63*35238bceSAndroid Build Coastguard Worker static const char *getIndexAccessTypeName(IndexAccessType accessType)
64*35238bceSAndroid Build Coastguard Worker {
65*35238bceSAndroid Build Coastguard Worker     static const char *s_names[INDEXACCESS_LAST] = {
66*35238bceSAndroid Build Coastguard Worker         "static", "dynamic", "static_loop", "dynamic_loop", "const",
67*35238bceSAndroid Build Coastguard Worker     };
68*35238bceSAndroid Build Coastguard Worker 
69*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInBounds32((int)accessType, 0, INDEXACCESS_LAST));
70*35238bceSAndroid Build Coastguard Worker     return s_names[(int)accessType];
71*35238bceSAndroid Build Coastguard Worker }
72*35238bceSAndroid Build Coastguard Worker 
73*35238bceSAndroid Build Coastguard Worker enum VectorAccessType
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker     DIRECT = 0,
76*35238bceSAndroid Build Coastguard Worker     COMPONENT,
77*35238bceSAndroid Build Coastguard Worker     SUBSCRIPT_STATIC,
78*35238bceSAndroid Build Coastguard Worker     SUBSCRIPT_DYNAMIC,
79*35238bceSAndroid Build Coastguard Worker     SUBSCRIPT_STATIC_LOOP,
80*35238bceSAndroid Build Coastguard Worker     SUBSCRIPT_DYNAMIC_LOOP,
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker     VECTORACCESS_LAST
83*35238bceSAndroid Build Coastguard Worker };
84*35238bceSAndroid Build Coastguard Worker 
getVectorAccessTypeName(VectorAccessType accessType)85*35238bceSAndroid Build Coastguard Worker static const char *getVectorAccessTypeName(VectorAccessType accessType)
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker     static const char *s_names[VECTORACCESS_LAST] = {"direct",
88*35238bceSAndroid Build Coastguard Worker                                                      "component",
89*35238bceSAndroid Build Coastguard Worker                                                      "static_subscript",
90*35238bceSAndroid Build Coastguard Worker                                                      "dynamic_subscript",
91*35238bceSAndroid Build Coastguard Worker                                                      "static_loop_subscript",
92*35238bceSAndroid Build Coastguard Worker                                                      "dynamic_loop_subscript"};
93*35238bceSAndroid Build Coastguard Worker 
94*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInBounds32((int)accessType, 0, VECTORACCESS_LAST));
95*35238bceSAndroid Build Coastguard Worker     return s_names[(int)accessType];
96*35238bceSAndroid Build Coastguard Worker }
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker enum RequirementFlags
99*35238bceSAndroid Build Coastguard Worker {
100*35238bceSAndroid Build Coastguard Worker     REQUIREMENT_UNIFORM_INDEXING       = (1 << 0),
101*35238bceSAndroid Build Coastguard Worker     REQUIREMENT_VERTEX_UNIFORM_LOOPS   = (1 << 1),
102*35238bceSAndroid Build Coastguard Worker     REQUIREMENT_FRAGMENT_UNIFORM_LOOPS = (1 << 2),
103*35238bceSAndroid Build Coastguard Worker };
104*35238bceSAndroid Build Coastguard Worker 
evalArrayCoordsFloat(ShaderEvalContext & c)105*35238bceSAndroid Build Coastguard Worker void evalArrayCoordsFloat(ShaderEvalContext &c)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker     c.color.x() = 1.875f * c.coords.x();
108*35238bceSAndroid Build Coastguard Worker }
evalArrayCoordsVec2(ShaderEvalContext & c)109*35238bceSAndroid Build Coastguard Worker void evalArrayCoordsVec2(ShaderEvalContext &c)
110*35238bceSAndroid Build Coastguard Worker {
111*35238bceSAndroid Build Coastguard Worker     c.color.xy() = 1.875f * c.coords.swizzle(0, 1);
112*35238bceSAndroid Build Coastguard Worker }
evalArrayCoordsVec3(ShaderEvalContext & c)113*35238bceSAndroid Build Coastguard Worker void evalArrayCoordsVec3(ShaderEvalContext &c)
114*35238bceSAndroid Build Coastguard Worker {
115*35238bceSAndroid Build Coastguard Worker     c.color.xyz() = 1.875f * c.coords.swizzle(0, 1, 2);
116*35238bceSAndroid Build Coastguard Worker }
evalArrayCoordsVec4(ShaderEvalContext & c)117*35238bceSAndroid Build Coastguard Worker void evalArrayCoordsVec4(ShaderEvalContext &c)
118*35238bceSAndroid Build Coastguard Worker {
119*35238bceSAndroid Build Coastguard Worker     c.color = 1.875f * c.coords;
120*35238bceSAndroid Build Coastguard Worker }
121*35238bceSAndroid Build Coastguard Worker 
getArrayCoordsEvalFunc(DataType dataType)122*35238bceSAndroid Build Coastguard Worker static ShaderEvalFunc getArrayCoordsEvalFunc(DataType dataType)
123*35238bceSAndroid Build Coastguard Worker {
124*35238bceSAndroid Build Coastguard Worker     if (dataType == TYPE_FLOAT)
125*35238bceSAndroid Build Coastguard Worker         return evalArrayCoordsFloat;
126*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_VEC2)
127*35238bceSAndroid Build Coastguard Worker         return evalArrayCoordsVec2;
128*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_VEC3)
129*35238bceSAndroid Build Coastguard Worker         return evalArrayCoordsVec3;
130*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_VEC4)
131*35238bceSAndroid Build Coastguard Worker         return evalArrayCoordsVec4;
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker     DE_FATAL("Invalid data type.");
134*35238bceSAndroid Build Coastguard Worker     return NULL;
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker 
evalArrayUniformFloat(ShaderEvalContext & c)137*35238bceSAndroid Build Coastguard Worker void evalArrayUniformFloat(ShaderEvalContext &c)
138*35238bceSAndroid Build Coastguard Worker {
139*35238bceSAndroid Build Coastguard Worker     c.color.x() = 1.875f * c.constCoords.x();
140*35238bceSAndroid Build Coastguard Worker }
evalArrayUniformVec2(ShaderEvalContext & c)141*35238bceSAndroid Build Coastguard Worker void evalArrayUniformVec2(ShaderEvalContext &c)
142*35238bceSAndroid Build Coastguard Worker {
143*35238bceSAndroid Build Coastguard Worker     c.color.xy() = 1.875f * c.constCoords.swizzle(0, 1);
144*35238bceSAndroid Build Coastguard Worker }
evalArrayUniformVec3(ShaderEvalContext & c)145*35238bceSAndroid Build Coastguard Worker void evalArrayUniformVec3(ShaderEvalContext &c)
146*35238bceSAndroid Build Coastguard Worker {
147*35238bceSAndroid Build Coastguard Worker     c.color.xyz() = 1.875f * c.constCoords.swizzle(0, 1, 2);
148*35238bceSAndroid Build Coastguard Worker }
evalArrayUniformVec4(ShaderEvalContext & c)149*35238bceSAndroid Build Coastguard Worker void evalArrayUniformVec4(ShaderEvalContext &c)
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker     c.color = 1.875f * c.constCoords;
152*35238bceSAndroid Build Coastguard Worker }
153*35238bceSAndroid Build Coastguard Worker 
getArrayUniformEvalFunc(DataType dataType)154*35238bceSAndroid Build Coastguard Worker static ShaderEvalFunc getArrayUniformEvalFunc(DataType dataType)
155*35238bceSAndroid Build Coastguard Worker {
156*35238bceSAndroid Build Coastguard Worker     if (dataType == TYPE_FLOAT)
157*35238bceSAndroid Build Coastguard Worker         return evalArrayUniformFloat;
158*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_VEC2)
159*35238bceSAndroid Build Coastguard Worker         return evalArrayUniformVec2;
160*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_VEC3)
161*35238bceSAndroid Build Coastguard Worker         return evalArrayUniformVec3;
162*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_VEC4)
163*35238bceSAndroid Build Coastguard Worker         return evalArrayUniformVec4;
164*35238bceSAndroid Build Coastguard Worker 
165*35238bceSAndroid Build Coastguard Worker     DE_FATAL("Invalid data type.");
166*35238bceSAndroid Build Coastguard Worker     return NULL;
167*35238bceSAndroid Build Coastguard Worker }
168*35238bceSAndroid Build Coastguard Worker 
169*35238bceSAndroid Build Coastguard Worker // ShaderIndexingCase
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker class ShaderIndexingCase : public ShaderRenderCase
172*35238bceSAndroid Build Coastguard Worker {
173*35238bceSAndroid Build Coastguard Worker public:
174*35238bceSAndroid Build Coastguard Worker     ShaderIndexingCase(Context &context, const char *name, const char *description, bool isVertexCase, DataType varType,
175*35238bceSAndroid Build Coastguard Worker                        ShaderEvalFunc evalFunc, uint32_t requirements, const char *vertShaderSource,
176*35238bceSAndroid Build Coastguard Worker                        const char *fragShaderSource);
177*35238bceSAndroid Build Coastguard Worker     virtual ~ShaderIndexingCase(void);
178*35238bceSAndroid Build Coastguard Worker 
179*35238bceSAndroid Build Coastguard Worker     virtual void init(void);
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker private:
182*35238bceSAndroid Build Coastguard Worker     ShaderIndexingCase(const ShaderIndexingCase &);            // not allowed!
183*35238bceSAndroid Build Coastguard Worker     ShaderIndexingCase &operator=(const ShaderIndexingCase &); // not allowed!
184*35238bceSAndroid Build Coastguard Worker 
185*35238bceSAndroid Build Coastguard Worker     virtual void setup(int programID);
186*35238bceSAndroid Build Coastguard Worker     virtual void setupUniforms(int programID, const Vec4 &constCoords);
187*35238bceSAndroid Build Coastguard Worker 
188*35238bceSAndroid Build Coastguard Worker     DataType m_varType;
189*35238bceSAndroid Build Coastguard Worker     uint32_t m_requirements;
190*35238bceSAndroid Build Coastguard Worker };
191*35238bceSAndroid Build Coastguard Worker 
ShaderIndexingCase(Context & context,const char * name,const char * description,bool isVertexCase,DataType varType,ShaderEvalFunc evalFunc,uint32_t requirements,const char * vertShaderSource,const char * fragShaderSource)192*35238bceSAndroid Build Coastguard Worker ShaderIndexingCase::ShaderIndexingCase(Context &context, const char *name, const char *description, bool isVertexCase,
193*35238bceSAndroid Build Coastguard Worker                                        DataType varType, ShaderEvalFunc evalFunc, uint32_t requirements,
194*35238bceSAndroid Build Coastguard Worker                                        const char *vertShaderSource, const char *fragShaderSource)
195*35238bceSAndroid Build Coastguard Worker     : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
196*35238bceSAndroid Build Coastguard Worker                        description, isVertexCase, evalFunc)
197*35238bceSAndroid Build Coastguard Worker     , m_requirements(requirements)
198*35238bceSAndroid Build Coastguard Worker {
199*35238bceSAndroid Build Coastguard Worker     m_varType          = varType;
200*35238bceSAndroid Build Coastguard Worker     m_vertShaderSource = vertShaderSource;
201*35238bceSAndroid Build Coastguard Worker     m_fragShaderSource = fragShaderSource;
202*35238bceSAndroid Build Coastguard Worker }
203*35238bceSAndroid Build Coastguard Worker 
~ShaderIndexingCase(void)204*35238bceSAndroid Build Coastguard Worker ShaderIndexingCase::~ShaderIndexingCase(void)
205*35238bceSAndroid Build Coastguard Worker {
206*35238bceSAndroid Build Coastguard Worker }
207*35238bceSAndroid Build Coastguard Worker 
init(void)208*35238bceSAndroid Build Coastguard Worker void ShaderIndexingCase::init(void)
209*35238bceSAndroid Build Coastguard Worker {
210*35238bceSAndroid Build Coastguard Worker     const bool isSupported =
211*35238bceSAndroid Build Coastguard Worker         !(m_requirements & REQUIREMENT_UNIFORM_INDEXING) &&
212*35238bceSAndroid Build Coastguard Worker         (!(m_requirements & REQUIREMENT_VERTEX_UNIFORM_LOOPS) || m_ctxInfo.isVertexUniformLoopSupported()) &&
213*35238bceSAndroid Build Coastguard Worker         (!(m_requirements & REQUIREMENT_FRAGMENT_UNIFORM_LOOPS) || m_ctxInfo.isFragmentUniformLoopSupported());
214*35238bceSAndroid Build Coastguard Worker 
215*35238bceSAndroid Build Coastguard Worker     try
216*35238bceSAndroid Build Coastguard Worker     {
217*35238bceSAndroid Build Coastguard Worker         ShaderRenderCase::init();
218*35238bceSAndroid Build Coastguard Worker     }
219*35238bceSAndroid Build Coastguard Worker     catch (const CompileFailed &)
220*35238bceSAndroid Build Coastguard Worker     {
221*35238bceSAndroid Build Coastguard Worker         if (!isSupported)
222*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Shader is not supported");
223*35238bceSAndroid Build Coastguard Worker         else
224*35238bceSAndroid Build Coastguard Worker             throw;
225*35238bceSAndroid Build Coastguard Worker     }
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker 
setup(int programID)228*35238bceSAndroid Build Coastguard Worker void ShaderIndexingCase::setup(int programID)
229*35238bceSAndroid Build Coastguard Worker {
230*35238bceSAndroid Build Coastguard Worker     DE_UNREF(programID);
231*35238bceSAndroid Build Coastguard Worker }
232*35238bceSAndroid Build Coastguard Worker 
setupUniforms(int programID,const Vec4 & constCoords)233*35238bceSAndroid Build Coastguard Worker void ShaderIndexingCase::setupUniforms(int programID, const Vec4 &constCoords)
234*35238bceSAndroid Build Coastguard Worker {
235*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_renderCtx.getFunctions();
236*35238bceSAndroid Build Coastguard Worker 
237*35238bceSAndroid Build Coastguard Worker     DE_UNREF(constCoords);
238*35238bceSAndroid Build Coastguard Worker 
239*35238bceSAndroid Build Coastguard Worker     int arrLoc = gl.getUniformLocation(programID, "u_arr");
240*35238bceSAndroid Build Coastguard Worker     if (arrLoc != -1)
241*35238bceSAndroid Build Coastguard Worker     {
242*35238bceSAndroid Build Coastguard Worker         //int scalarSize = getDataTypeScalarSize(m_varType);
243*35238bceSAndroid Build Coastguard Worker         if (m_varType == TYPE_FLOAT)
244*35238bceSAndroid Build Coastguard Worker         {
245*35238bceSAndroid Build Coastguard Worker             float arr[4];
246*35238bceSAndroid Build Coastguard Worker             arr[0] = constCoords.x();
247*35238bceSAndroid Build Coastguard Worker             arr[1] = constCoords.x() * 0.5f;
248*35238bceSAndroid Build Coastguard Worker             arr[2] = constCoords.x() * 0.25f;
249*35238bceSAndroid Build Coastguard Worker             arr[3] = constCoords.x() * 0.125f;
250*35238bceSAndroid Build Coastguard Worker             gl.uniform1fv(arrLoc, 4, &arr[0]);
251*35238bceSAndroid Build Coastguard Worker         }
252*35238bceSAndroid Build Coastguard Worker         else if (m_varType == TYPE_FLOAT_VEC2)
253*35238bceSAndroid Build Coastguard Worker         {
254*35238bceSAndroid Build Coastguard Worker             Vec2 arr[4];
255*35238bceSAndroid Build Coastguard Worker             arr[0] = constCoords.swizzle(0, 1);
256*35238bceSAndroid Build Coastguard Worker             arr[1] = constCoords.swizzle(0, 1) * 0.5f;
257*35238bceSAndroid Build Coastguard Worker             arr[2] = constCoords.swizzle(0, 1) * 0.25f;
258*35238bceSAndroid Build Coastguard Worker             arr[3] = constCoords.swizzle(0, 1) * 0.125f;
259*35238bceSAndroid Build Coastguard Worker             gl.uniform2fv(arrLoc, 4, arr[0].getPtr());
260*35238bceSAndroid Build Coastguard Worker         }
261*35238bceSAndroid Build Coastguard Worker         else if (m_varType == TYPE_FLOAT_VEC3)
262*35238bceSAndroid Build Coastguard Worker         {
263*35238bceSAndroid Build Coastguard Worker             Vec3 arr[4];
264*35238bceSAndroid Build Coastguard Worker             arr[0] = constCoords.swizzle(0, 1, 2);
265*35238bceSAndroid Build Coastguard Worker             arr[1] = constCoords.swizzle(0, 1, 2) * 0.5f;
266*35238bceSAndroid Build Coastguard Worker             arr[2] = constCoords.swizzle(0, 1, 2) * 0.25f;
267*35238bceSAndroid Build Coastguard Worker             arr[3] = constCoords.swizzle(0, 1, 2) * 0.125f;
268*35238bceSAndroid Build Coastguard Worker             gl.uniform3fv(arrLoc, 4, arr[0].getPtr());
269*35238bceSAndroid Build Coastguard Worker         }
270*35238bceSAndroid Build Coastguard Worker         else if (m_varType == TYPE_FLOAT_VEC4)
271*35238bceSAndroid Build Coastguard Worker         {
272*35238bceSAndroid Build Coastguard Worker             Vec4 arr[4];
273*35238bceSAndroid Build Coastguard Worker             arr[0] = constCoords.swizzle(0, 1, 2, 3);
274*35238bceSAndroid Build Coastguard Worker             arr[1] = constCoords.swizzle(0, 1, 2, 3) * 0.5f;
275*35238bceSAndroid Build Coastguard Worker             arr[2] = constCoords.swizzle(0, 1, 2, 3) * 0.25f;
276*35238bceSAndroid Build Coastguard Worker             arr[3] = constCoords.swizzle(0, 1, 2, 3) * 0.125f;
277*35238bceSAndroid Build Coastguard Worker             gl.uniform4fv(arrLoc, 4, arr[0].getPtr());
278*35238bceSAndroid Build Coastguard Worker         }
279*35238bceSAndroid Build Coastguard Worker         else
280*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("u_arr should not have location assigned in this test case");
281*35238bceSAndroid Build Coastguard Worker     }
282*35238bceSAndroid Build Coastguard Worker }
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker // Helpers.
285*35238bceSAndroid Build Coastguard Worker 
createVaryingArrayCase(Context & context,const char * caseName,const char * description,DataType varType,IndexAccessType vertAccess,IndexAccessType fragAccess)286*35238bceSAndroid Build Coastguard Worker static ShaderIndexingCase *createVaryingArrayCase(Context &context, const char *caseName, const char *description,
287*35238bceSAndroid Build Coastguard Worker                                                   DataType varType, IndexAccessType vertAccess,
288*35238bceSAndroid Build Coastguard Worker                                                   IndexAccessType fragAccess)
289*35238bceSAndroid Build Coastguard Worker {
290*35238bceSAndroid Build Coastguard Worker     std::ostringstream vtx;
291*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_position;\n";
292*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_coords;\n";
293*35238bceSAndroid Build Coastguard Worker     if (vertAccess == INDEXACCESS_DYNAMIC)
294*35238bceSAndroid Build Coastguard Worker         vtx << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
295*35238bceSAndroid Build Coastguard Worker     else if (vertAccess == INDEXACCESS_DYNAMIC_LOOP)
296*35238bceSAndroid Build Coastguard Worker         vtx << "uniform mediump int ui_four;\n";
297*35238bceSAndroid Build Coastguard Worker     vtx << "varying ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
298*35238bceSAndroid Build Coastguard Worker     vtx << "\n";
299*35238bceSAndroid Build Coastguard Worker     vtx << "void main()\n";
300*35238bceSAndroid Build Coastguard Worker     vtx << "{\n";
301*35238bceSAndroid Build Coastguard Worker     vtx << "    gl_Position = a_position;\n";
302*35238bceSAndroid Build Coastguard Worker     if (vertAccess == INDEXACCESS_STATIC)
303*35238bceSAndroid Build Coastguard Worker     {
304*35238bceSAndroid Build Coastguard Worker         vtx << "    var[0] = ${VAR_TYPE}(a_coords);\n";
305*35238bceSAndroid Build Coastguard Worker         vtx << "    var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n";
306*35238bceSAndroid Build Coastguard Worker         vtx << "    var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n";
307*35238bceSAndroid Build Coastguard Worker         vtx << "    var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n";
308*35238bceSAndroid Build Coastguard Worker     }
309*35238bceSAndroid Build Coastguard Worker     else if (vertAccess == INDEXACCESS_DYNAMIC)
310*35238bceSAndroid Build Coastguard Worker     {
311*35238bceSAndroid Build Coastguard Worker         vtx << "    var[ui_zero]  = ${VAR_TYPE}(a_coords);\n";
312*35238bceSAndroid Build Coastguard Worker         vtx << "    var[ui_one]   = ${VAR_TYPE}(a_coords) * 0.5;\n";
313*35238bceSAndroid Build Coastguard Worker         vtx << "    var[ui_two]   = ${VAR_TYPE}(a_coords) * 0.25;\n";
314*35238bceSAndroid Build Coastguard Worker         vtx << "    var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n";
315*35238bceSAndroid Build Coastguard Worker     }
316*35238bceSAndroid Build Coastguard Worker     else if (vertAccess == INDEXACCESS_STATIC_LOOP)
317*35238bceSAndroid Build Coastguard Worker     {
318*35238bceSAndroid Build Coastguard Worker         vtx << "    ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
319*35238bceSAndroid Build Coastguard Worker         vtx << "    for (int i = 0; i < 4; i++)\n";
320*35238bceSAndroid Build Coastguard Worker         vtx << "    {\n";
321*35238bceSAndroid Build Coastguard Worker         vtx << "        var[i] = ${VAR_TYPE}(coords);\n";
322*35238bceSAndroid Build Coastguard Worker         vtx << "        coords = coords * 0.5;\n";
323*35238bceSAndroid Build Coastguard Worker         vtx << "    }\n";
324*35238bceSAndroid Build Coastguard Worker     }
325*35238bceSAndroid Build Coastguard Worker     else
326*35238bceSAndroid Build Coastguard Worker     {
327*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(vertAccess == INDEXACCESS_DYNAMIC_LOOP);
328*35238bceSAndroid Build Coastguard Worker         vtx << "    ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
329*35238bceSAndroid Build Coastguard Worker         vtx << "    for (int i = 0; i < ui_four; i++)\n";
330*35238bceSAndroid Build Coastguard Worker         vtx << "    {\n";
331*35238bceSAndroid Build Coastguard Worker         vtx << "        var[i] = ${VAR_TYPE}(coords);\n";
332*35238bceSAndroid Build Coastguard Worker         vtx << "        coords = coords * 0.5;\n";
333*35238bceSAndroid Build Coastguard Worker         vtx << "    }\n";
334*35238bceSAndroid Build Coastguard Worker     }
335*35238bceSAndroid Build Coastguard Worker     vtx << "}\n";
336*35238bceSAndroid Build Coastguard Worker 
337*35238bceSAndroid Build Coastguard Worker     std::ostringstream frag;
338*35238bceSAndroid Build Coastguard Worker     frag << "precision mediump int;\n";
339*35238bceSAndroid Build Coastguard Worker     if (fragAccess == INDEXACCESS_DYNAMIC)
340*35238bceSAndroid Build Coastguard Worker         frag << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
341*35238bceSAndroid Build Coastguard Worker     else if (fragAccess == INDEXACCESS_DYNAMIC_LOOP)
342*35238bceSAndroid Build Coastguard Worker         frag << "uniform int ui_four;\n";
343*35238bceSAndroid Build Coastguard Worker     frag << "varying ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
344*35238bceSAndroid Build Coastguard Worker     frag << "\n";
345*35238bceSAndroid Build Coastguard Worker     frag << "void main()\n";
346*35238bceSAndroid Build Coastguard Worker     frag << "{\n";
347*35238bceSAndroid Build Coastguard Worker     frag << "    ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
348*35238bceSAndroid Build Coastguard Worker     if (fragAccess == INDEXACCESS_STATIC)
349*35238bceSAndroid Build Coastguard Worker     {
350*35238bceSAndroid Build Coastguard Worker         frag << "    res += var[0];\n";
351*35238bceSAndroid Build Coastguard Worker         frag << "    res += var[1];\n";
352*35238bceSAndroid Build Coastguard Worker         frag << "    res += var[2];\n";
353*35238bceSAndroid Build Coastguard Worker         frag << "    res += var[3];\n";
354*35238bceSAndroid Build Coastguard Worker     }
355*35238bceSAndroid Build Coastguard Worker     else if (fragAccess == INDEXACCESS_DYNAMIC)
356*35238bceSAndroid Build Coastguard Worker     {
357*35238bceSAndroid Build Coastguard Worker         frag << "    res += var[ui_zero];\n";
358*35238bceSAndroid Build Coastguard Worker         frag << "    res += var[ui_one];\n";
359*35238bceSAndroid Build Coastguard Worker         frag << "    res += var[ui_two];\n";
360*35238bceSAndroid Build Coastguard Worker         frag << "    res += var[ui_three];\n";
361*35238bceSAndroid Build Coastguard Worker     }
362*35238bceSAndroid Build Coastguard Worker     else if (fragAccess == INDEXACCESS_STATIC_LOOP)
363*35238bceSAndroid Build Coastguard Worker     {
364*35238bceSAndroid Build Coastguard Worker         frag << "    for (int i = 0; i < 4; i++)\n";
365*35238bceSAndroid Build Coastguard Worker         frag << "        res += var[i];\n";
366*35238bceSAndroid Build Coastguard Worker     }
367*35238bceSAndroid Build Coastguard Worker     else
368*35238bceSAndroid Build Coastguard Worker     {
369*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(fragAccess == INDEXACCESS_DYNAMIC_LOOP);
370*35238bceSAndroid Build Coastguard Worker         frag << "    for (int i = 0; i < ui_four; i++)\n";
371*35238bceSAndroid Build Coastguard Worker         frag << "        res += var[i];\n";
372*35238bceSAndroid Build Coastguard Worker     }
373*35238bceSAndroid Build Coastguard Worker     frag << "    gl_FragColor = vec4(res${PADDING});\n";
374*35238bceSAndroid Build Coastguard Worker     frag << "}\n";
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker     // Fill in shader templates.
377*35238bceSAndroid Build Coastguard Worker     map<string, string> params;
378*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
379*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("ARRAY_LEN", "4"));
380*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("PRECISION", "mediump"));
381*35238bceSAndroid Build Coastguard Worker 
382*35238bceSAndroid Build Coastguard Worker     if (varType == TYPE_FLOAT)
383*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
384*35238bceSAndroid Build Coastguard Worker     else if (varType == TYPE_FLOAT_VEC2)
385*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
386*35238bceSAndroid Build Coastguard Worker     else if (varType == TYPE_FLOAT_VEC3)
387*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 1.0"));
388*35238bceSAndroid Build Coastguard Worker     else
389*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ""));
390*35238bceSAndroid Build Coastguard Worker 
391*35238bceSAndroid Build Coastguard Worker     StringTemplate vertTemplate(vtx.str().c_str());
392*35238bceSAndroid Build Coastguard Worker     StringTemplate fragTemplate(frag.str().c_str());
393*35238bceSAndroid Build Coastguard Worker     string vertexShaderSource   = vertTemplate.specialize(params);
394*35238bceSAndroid Build Coastguard Worker     string fragmentShaderSource = fragTemplate.specialize(params);
395*35238bceSAndroid Build Coastguard Worker 
396*35238bceSAndroid Build Coastguard Worker     ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
397*35238bceSAndroid Build Coastguard Worker     uint32_t requirements   = 0;
398*35238bceSAndroid Build Coastguard Worker 
399*35238bceSAndroid Build Coastguard Worker     if (vertAccess == INDEXACCESS_DYNAMIC || fragAccess == INDEXACCESS_DYNAMIC)
400*35238bceSAndroid Build Coastguard Worker         requirements |= REQUIREMENT_UNIFORM_INDEXING;
401*35238bceSAndroid Build Coastguard Worker 
402*35238bceSAndroid Build Coastguard Worker     if (vertAccess == INDEXACCESS_DYNAMIC_LOOP)
403*35238bceSAndroid Build Coastguard Worker         requirements |= REQUIREMENT_VERTEX_UNIFORM_LOOPS | REQUIREMENT_UNIFORM_INDEXING;
404*35238bceSAndroid Build Coastguard Worker 
405*35238bceSAndroid Build Coastguard Worker     if (fragAccess == INDEXACCESS_DYNAMIC_LOOP)
406*35238bceSAndroid Build Coastguard Worker         requirements |= REQUIREMENT_FRAGMENT_UNIFORM_LOOPS | REQUIREMENT_UNIFORM_INDEXING;
407*35238bceSAndroid Build Coastguard Worker 
408*35238bceSAndroid Build Coastguard Worker     return new ShaderIndexingCase(context, caseName, description, true, varType, evalFunc, requirements,
409*35238bceSAndroid Build Coastguard Worker                                   vertexShaderSource.c_str(), fragmentShaderSource.c_str());
410*35238bceSAndroid Build Coastguard Worker }
411*35238bceSAndroid Build Coastguard Worker 
createUniformArrayCase(Context & context,const char * caseName,const char * description,bool isVertexCase,DataType varType,IndexAccessType readAccess)412*35238bceSAndroid Build Coastguard Worker static ShaderIndexingCase *createUniformArrayCase(Context &context, const char *caseName, const char *description,
413*35238bceSAndroid Build Coastguard Worker                                                   bool isVertexCase, DataType varType, IndexAccessType readAccess)
414*35238bceSAndroid Build Coastguard Worker {
415*35238bceSAndroid Build Coastguard Worker     std::ostringstream vtx;
416*35238bceSAndroid Build Coastguard Worker     std::ostringstream frag;
417*35238bceSAndroid Build Coastguard Worker     std::ostringstream &op = isVertexCase ? vtx : frag;
418*35238bceSAndroid Build Coastguard Worker 
419*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_position;\n";
420*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_coords;\n";
421*35238bceSAndroid Build Coastguard Worker 
422*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
423*35238bceSAndroid Build Coastguard Worker     {
424*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec4 v_color;\n";
425*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec4 v_color;\n";
426*35238bceSAndroid Build Coastguard Worker     }
427*35238bceSAndroid Build Coastguard Worker     else
428*35238bceSAndroid Build Coastguard Worker     {
429*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec4 v_coords;\n";
430*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec4 v_coords;\n";
431*35238bceSAndroid Build Coastguard Worker     }
432*35238bceSAndroid Build Coastguard Worker 
433*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_DYNAMIC)
434*35238bceSAndroid Build Coastguard Worker         op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
435*35238bceSAndroid Build Coastguard Worker     else if (readAccess == INDEXACCESS_DYNAMIC_LOOP)
436*35238bceSAndroid Build Coastguard Worker         op << "uniform mediump int ui_four;\n";
437*35238bceSAndroid Build Coastguard Worker 
438*35238bceSAndroid Build Coastguard Worker     op << "uniform ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}];\n";
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker     vtx << "\n";
441*35238bceSAndroid Build Coastguard Worker     vtx << "void main()\n";
442*35238bceSAndroid Build Coastguard Worker     vtx << "{\n";
443*35238bceSAndroid Build Coastguard Worker     vtx << "    gl_Position = a_position;\n";
444*35238bceSAndroid Build Coastguard Worker 
445*35238bceSAndroid Build Coastguard Worker     frag << "\n";
446*35238bceSAndroid Build Coastguard Worker     frag << "void main()\n";
447*35238bceSAndroid Build Coastguard Worker     frag << "{\n";
448*35238bceSAndroid Build Coastguard Worker 
449*35238bceSAndroid Build Coastguard Worker     // Read array.
450*35238bceSAndroid Build Coastguard Worker     op << "    ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
451*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_STATIC)
452*35238bceSAndroid Build Coastguard Worker     {
453*35238bceSAndroid Build Coastguard Worker         op << "    res += u_arr[0];\n";
454*35238bceSAndroid Build Coastguard Worker         op << "    res += u_arr[1];\n";
455*35238bceSAndroid Build Coastguard Worker         op << "    res += u_arr[2];\n";
456*35238bceSAndroid Build Coastguard Worker         op << "    res += u_arr[3];\n";
457*35238bceSAndroid Build Coastguard Worker     }
458*35238bceSAndroid Build Coastguard Worker     else if (readAccess == INDEXACCESS_DYNAMIC)
459*35238bceSAndroid Build Coastguard Worker     {
460*35238bceSAndroid Build Coastguard Worker         op << "    res += u_arr[ui_zero];\n";
461*35238bceSAndroid Build Coastguard Worker         op << "    res += u_arr[ui_one];\n";
462*35238bceSAndroid Build Coastguard Worker         op << "    res += u_arr[ui_two];\n";
463*35238bceSAndroid Build Coastguard Worker         op << "    res += u_arr[ui_three];\n";
464*35238bceSAndroid Build Coastguard Worker     }
465*35238bceSAndroid Build Coastguard Worker     else if (readAccess == INDEXACCESS_STATIC_LOOP)
466*35238bceSAndroid Build Coastguard Worker     {
467*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < 4; i++)\n";
468*35238bceSAndroid Build Coastguard Worker         op << "        res += u_arr[i];\n";
469*35238bceSAndroid Build Coastguard Worker     }
470*35238bceSAndroid Build Coastguard Worker     else
471*35238bceSAndroid Build Coastguard Worker     {
472*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
473*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < ui_four; i++)\n";
474*35238bceSAndroid Build Coastguard Worker         op << "        res += u_arr[i];\n";
475*35238bceSAndroid Build Coastguard Worker     }
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
478*35238bceSAndroid Build Coastguard Worker     {
479*35238bceSAndroid Build Coastguard Worker         vtx << "    v_color = vec4(res${PADDING});\n";
480*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = v_color;\n";
481*35238bceSAndroid Build Coastguard Worker     }
482*35238bceSAndroid Build Coastguard Worker     else
483*35238bceSAndroid Build Coastguard Worker     {
484*35238bceSAndroid Build Coastguard Worker         vtx << "    v_coords = a_coords;\n";
485*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = vec4(res${PADDING});\n";
486*35238bceSAndroid Build Coastguard Worker     }
487*35238bceSAndroid Build Coastguard Worker 
488*35238bceSAndroid Build Coastguard Worker     vtx << "}\n";
489*35238bceSAndroid Build Coastguard Worker     frag << "}\n";
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker     // Fill in shader templates.
492*35238bceSAndroid Build Coastguard Worker     map<string, string> params;
493*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
494*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("ARRAY_LEN", "4"));
495*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("PRECISION", "mediump"));
496*35238bceSAndroid Build Coastguard Worker 
497*35238bceSAndroid Build Coastguard Worker     if (varType == TYPE_FLOAT)
498*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
499*35238bceSAndroid Build Coastguard Worker     else if (varType == TYPE_FLOAT_VEC2)
500*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
501*35238bceSAndroid Build Coastguard Worker     else if (varType == TYPE_FLOAT_VEC3)
502*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 1.0"));
503*35238bceSAndroid Build Coastguard Worker     else
504*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ""));
505*35238bceSAndroid Build Coastguard Worker 
506*35238bceSAndroid Build Coastguard Worker     StringTemplate vertTemplate(vtx.str().c_str());
507*35238bceSAndroid Build Coastguard Worker     StringTemplate fragTemplate(frag.str().c_str());
508*35238bceSAndroid Build Coastguard Worker     string vertexShaderSource   = vertTemplate.specialize(params);
509*35238bceSAndroid Build Coastguard Worker     string fragmentShaderSource = fragTemplate.specialize(params);
510*35238bceSAndroid Build Coastguard Worker 
511*35238bceSAndroid Build Coastguard Worker     ShaderEvalFunc evalFunc = getArrayUniformEvalFunc(varType);
512*35238bceSAndroid Build Coastguard Worker     uint32_t requirements   = 0;
513*35238bceSAndroid Build Coastguard Worker 
514*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_DYNAMIC)
515*35238bceSAndroid Build Coastguard Worker         requirements |= REQUIREMENT_UNIFORM_INDEXING;
516*35238bceSAndroid Build Coastguard Worker 
517*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_DYNAMIC_LOOP)
518*35238bceSAndroid Build Coastguard Worker         requirements |= (isVertexCase ? REQUIREMENT_VERTEX_UNIFORM_LOOPS : REQUIREMENT_FRAGMENT_UNIFORM_LOOPS) |
519*35238bceSAndroid Build Coastguard Worker                         REQUIREMENT_UNIFORM_INDEXING;
520*35238bceSAndroid Build Coastguard Worker 
521*35238bceSAndroid Build Coastguard Worker     return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, requirements,
522*35238bceSAndroid Build Coastguard Worker                                   vertexShaderSource.c_str(), fragmentShaderSource.c_str());
523*35238bceSAndroid Build Coastguard Worker }
524*35238bceSAndroid Build Coastguard Worker 
createTmpArrayCase(Context & context,const char * caseName,const char * description,bool isVertexCase,DataType varType,IndexAccessType writeAccess,IndexAccessType readAccess)525*35238bceSAndroid Build Coastguard Worker static ShaderIndexingCase *createTmpArrayCase(Context &context, const char *caseName, const char *description,
526*35238bceSAndroid Build Coastguard Worker                                               bool isVertexCase, DataType varType, IndexAccessType writeAccess,
527*35238bceSAndroid Build Coastguard Worker                                               IndexAccessType readAccess)
528*35238bceSAndroid Build Coastguard Worker {
529*35238bceSAndroid Build Coastguard Worker     std::ostringstream vtx;
530*35238bceSAndroid Build Coastguard Worker     std::ostringstream frag;
531*35238bceSAndroid Build Coastguard Worker     std::ostringstream &op = isVertexCase ? vtx : frag;
532*35238bceSAndroid Build Coastguard Worker 
533*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_position;\n";
534*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_coords;\n";
535*35238bceSAndroid Build Coastguard Worker 
536*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
537*35238bceSAndroid Build Coastguard Worker     {
538*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec4 v_color;\n";
539*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec4 v_color;\n";
540*35238bceSAndroid Build Coastguard Worker     }
541*35238bceSAndroid Build Coastguard Worker     else if (writeAccess != INDEXACCESS_CONST)
542*35238bceSAndroid Build Coastguard Worker     {
543*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec4 v_coords;\n";
544*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec4 v_coords;\n";
545*35238bceSAndroid Build Coastguard Worker     }
546*35238bceSAndroid Build Coastguard Worker 
547*35238bceSAndroid Build Coastguard Worker     if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
548*35238bceSAndroid Build Coastguard Worker         op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
549*35238bceSAndroid Build Coastguard Worker 
550*35238bceSAndroid Build Coastguard Worker     if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
551*35238bceSAndroid Build Coastguard Worker         op << "uniform mediump int ui_four;\n";
552*35238bceSAndroid Build Coastguard Worker 
553*35238bceSAndroid Build Coastguard Worker     vtx << "\n";
554*35238bceSAndroid Build Coastguard Worker     vtx << "void main()\n";
555*35238bceSAndroid Build Coastguard Worker     vtx << "{\n";
556*35238bceSAndroid Build Coastguard Worker     vtx << "    gl_Position = a_position;\n";
557*35238bceSAndroid Build Coastguard Worker 
558*35238bceSAndroid Build Coastguard Worker     frag << "\n";
559*35238bceSAndroid Build Coastguard Worker     frag << "void main()\n";
560*35238bceSAndroid Build Coastguard Worker     frag << "{\n";
561*35238bceSAndroid Build Coastguard Worker 
562*35238bceSAndroid Build Coastguard Worker     // Write array.
563*35238bceSAndroid Build Coastguard Worker     if (writeAccess != INDEXACCESS_CONST)
564*35238bceSAndroid Build Coastguard Worker     {
565*35238bceSAndroid Build Coastguard Worker         if (isVertexCase)
566*35238bceSAndroid Build Coastguard Worker             op << "    ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
567*35238bceSAndroid Build Coastguard Worker         else
568*35238bceSAndroid Build Coastguard Worker             op << "    ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";
569*35238bceSAndroid Build Coastguard Worker     }
570*35238bceSAndroid Build Coastguard Worker 
571*35238bceSAndroid Build Coastguard Worker     op << "    ${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n";
572*35238bceSAndroid Build Coastguard Worker     if (writeAccess == INDEXACCESS_STATIC)
573*35238bceSAndroid Build Coastguard Worker     {
574*35238bceSAndroid Build Coastguard Worker         op << "    arr[0] = ${VAR_TYPE}(coords);\n";
575*35238bceSAndroid Build Coastguard Worker         op << "    arr[1] = ${VAR_TYPE}(coords) * 0.5;\n";
576*35238bceSAndroid Build Coastguard Worker         op << "    arr[2] = ${VAR_TYPE}(coords) * 0.25;\n";
577*35238bceSAndroid Build Coastguard Worker         op << "    arr[3] = ${VAR_TYPE}(coords) * 0.125;\n";
578*35238bceSAndroid Build Coastguard Worker     }
579*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == INDEXACCESS_CONST)
580*35238bceSAndroid Build Coastguard Worker     {
581*35238bceSAndroid Build Coastguard Worker         // Not using a loop inside the shader because we want it
582*35238bceSAndroid Build Coastguard Worker         // unrolled to encourage the shader compiler to store it as
583*35238bceSAndroid Build Coastguard Worker         // constant data.
584*35238bceSAndroid Build Coastguard Worker         static const char *constructors[] = {"0.125", "0.125, 0.25", "0.125, 0.25, 0.5", "0.125, 0.25, 0.5, 1.0"};
585*35238bceSAndroid Build Coastguard Worker         const char *constructor_args      = constructors[getDataTypeNumComponents(varType) - 1];
586*35238bceSAndroid Build Coastguard Worker 
587*35238bceSAndroid Build Coastguard Worker         op << "    arr[0] = ${VAR_TYPE}(" << constructor_args << ");\n";
588*35238bceSAndroid Build Coastguard Worker         op << "    arr[1] = ${VAR_TYPE}(" << constructor_args << ") * 0.5;\n";
589*35238bceSAndroid Build Coastguard Worker         op << "    arr[2] = ${VAR_TYPE}(" << constructor_args << ") * 0.25;\n";
590*35238bceSAndroid Build Coastguard Worker         op << "    arr[3] = ${VAR_TYPE}(" << constructor_args << ") * 0.125;\n";
591*35238bceSAndroid Build Coastguard Worker 
592*35238bceSAndroid Build Coastguard Worker         /* Stuff unused values in the rest of the array. */
593*35238bceSAndroid Build Coastguard Worker         op << "    int i = 4;\n";
594*35238bceSAndroid Build Coastguard Worker         for (int i = 4; i < 40; i++)
595*35238bceSAndroid Build Coastguard Worker             op << "    arr[i++] = ${VAR_TYPE}(" << i << ".0);\n";
596*35238bceSAndroid Build Coastguard Worker     }
597*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == INDEXACCESS_DYNAMIC)
598*35238bceSAndroid Build Coastguard Worker     {
599*35238bceSAndroid Build Coastguard Worker         op << "    arr[ui_zero]  = ${VAR_TYPE}(coords);\n";
600*35238bceSAndroid Build Coastguard Worker         op << "    arr[ui_one]   = ${VAR_TYPE}(coords) * 0.5;\n";
601*35238bceSAndroid Build Coastguard Worker         op << "    arr[ui_two]   = ${VAR_TYPE}(coords) * 0.25;\n";
602*35238bceSAndroid Build Coastguard Worker         op << "    arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n";
603*35238bceSAndroid Build Coastguard Worker     }
604*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == INDEXACCESS_STATIC_LOOP)
605*35238bceSAndroid Build Coastguard Worker     {
606*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < 4; i++)\n";
607*35238bceSAndroid Build Coastguard Worker         op << "    {\n";
608*35238bceSAndroid Build Coastguard Worker         op << "        arr[i] = ${VAR_TYPE}(coords);\n";
609*35238bceSAndroid Build Coastguard Worker         op << "        coords = coords * 0.5;\n";
610*35238bceSAndroid Build Coastguard Worker         op << "    }\n";
611*35238bceSAndroid Build Coastguard Worker     }
612*35238bceSAndroid Build Coastguard Worker     else
613*35238bceSAndroid Build Coastguard Worker     {
614*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
615*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < ui_four; i++)\n";
616*35238bceSAndroid Build Coastguard Worker         op << "    {\n";
617*35238bceSAndroid Build Coastguard Worker         op << "        arr[i] = ${VAR_TYPE}(coords);\n";
618*35238bceSAndroid Build Coastguard Worker         op << "        coords = coords * 0.5;\n";
619*35238bceSAndroid Build Coastguard Worker         op << "    }\n";
620*35238bceSAndroid Build Coastguard Worker     }
621*35238bceSAndroid Build Coastguard Worker 
622*35238bceSAndroid Build Coastguard Worker     // Read array.
623*35238bceSAndroid Build Coastguard Worker     op << "    ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
624*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_STATIC)
625*35238bceSAndroid Build Coastguard Worker     {
626*35238bceSAndroid Build Coastguard Worker         op << "    res += arr[0];\n";
627*35238bceSAndroid Build Coastguard Worker         op << "    res += arr[1];\n";
628*35238bceSAndroid Build Coastguard Worker         op << "    res += arr[2];\n";
629*35238bceSAndroid Build Coastguard Worker         op << "    res += arr[3];\n";
630*35238bceSAndroid Build Coastguard Worker     }
631*35238bceSAndroid Build Coastguard Worker     else if (readAccess == INDEXACCESS_DYNAMIC)
632*35238bceSAndroid Build Coastguard Worker     {
633*35238bceSAndroid Build Coastguard Worker         op << "    res += arr[ui_zero];\n";
634*35238bceSAndroid Build Coastguard Worker         op << "    res += arr[ui_one];\n";
635*35238bceSAndroid Build Coastguard Worker         op << "    res += arr[ui_two];\n";
636*35238bceSAndroid Build Coastguard Worker         op << "    res += arr[ui_three];\n";
637*35238bceSAndroid Build Coastguard Worker     }
638*35238bceSAndroid Build Coastguard Worker     else if (readAccess == INDEXACCESS_STATIC_LOOP)
639*35238bceSAndroid Build Coastguard Worker     {
640*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < 4; i++)\n";
641*35238bceSAndroid Build Coastguard Worker         op << "        res += arr[i];\n";
642*35238bceSAndroid Build Coastguard Worker     }
643*35238bceSAndroid Build Coastguard Worker     else
644*35238bceSAndroid Build Coastguard Worker     {
645*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
646*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < ui_four; i++)\n";
647*35238bceSAndroid Build Coastguard Worker         op << "        res += arr[i];\n";
648*35238bceSAndroid Build Coastguard Worker     }
649*35238bceSAndroid Build Coastguard Worker 
650*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
651*35238bceSAndroid Build Coastguard Worker     {
652*35238bceSAndroid Build Coastguard Worker         vtx << "    v_color = vec4(res${PADDING});\n";
653*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = v_color;\n";
654*35238bceSAndroid Build Coastguard Worker     }
655*35238bceSAndroid Build Coastguard Worker     else
656*35238bceSAndroid Build Coastguard Worker     {
657*35238bceSAndroid Build Coastguard Worker         if (writeAccess != INDEXACCESS_CONST)
658*35238bceSAndroid Build Coastguard Worker             vtx << "    v_coords = a_coords;\n";
659*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = vec4(res${PADDING});\n";
660*35238bceSAndroid Build Coastguard Worker     }
661*35238bceSAndroid Build Coastguard Worker 
662*35238bceSAndroid Build Coastguard Worker     vtx << "}\n";
663*35238bceSAndroid Build Coastguard Worker     frag << "}\n";
664*35238bceSAndroid Build Coastguard Worker 
665*35238bceSAndroid Build Coastguard Worker     // Fill in shader templates.
666*35238bceSAndroid Build Coastguard Worker     map<string, string> params;
667*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
668*35238bceSAndroid Build Coastguard Worker     // For const indexing, size the array such that the compiler is
669*35238bceSAndroid Build Coastguard Worker     // more likely to optimize the temporary to constants.  4 wasn't
670*35238bceSAndroid Build Coastguard Worker     // enough for Mesa's i965 driver to do it, while 40 was enough to
671*35238bceSAndroid Build Coastguard Worker     // trigger the pass, and also enough to trigger compile failures
672*35238bceSAndroid Build Coastguard Worker     // on the freedreno driver at vec3/vec4 without the optimization
673*35238bceSAndroid Build Coastguard Worker     // in place.
674*35238bceSAndroid Build Coastguard Worker     if (writeAccess == INDEXACCESS_CONST)
675*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("ARRAY_LEN", "40"));
676*35238bceSAndroid Build Coastguard Worker     else
677*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("ARRAY_LEN", "4"));
678*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("PRECISION", "mediump"));
679*35238bceSAndroid Build Coastguard Worker 
680*35238bceSAndroid Build Coastguard Worker     if (varType == TYPE_FLOAT)
681*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
682*35238bceSAndroid Build Coastguard Worker     else if (varType == TYPE_FLOAT_VEC2)
683*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
684*35238bceSAndroid Build Coastguard Worker     else if (varType == TYPE_FLOAT_VEC3)
685*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 1.0"));
686*35238bceSAndroid Build Coastguard Worker     else
687*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ""));
688*35238bceSAndroid Build Coastguard Worker 
689*35238bceSAndroid Build Coastguard Worker     StringTemplate vertTemplate(vtx.str().c_str());
690*35238bceSAndroid Build Coastguard Worker     StringTemplate fragTemplate(frag.str().c_str());
691*35238bceSAndroid Build Coastguard Worker     string vertexShaderSource   = vertTemplate.specialize(params);
692*35238bceSAndroid Build Coastguard Worker     string fragmentShaderSource = fragTemplate.specialize(params);
693*35238bceSAndroid Build Coastguard Worker 
694*35238bceSAndroid Build Coastguard Worker     ShaderEvalFunc evalFunc;
695*35238bceSAndroid Build Coastguard Worker     if (writeAccess == INDEXACCESS_CONST)
696*35238bceSAndroid Build Coastguard Worker         evalFunc = getArrayUniformEvalFunc(varType);
697*35238bceSAndroid Build Coastguard Worker     else
698*35238bceSAndroid Build Coastguard Worker         evalFunc = getArrayCoordsEvalFunc(varType);
699*35238bceSAndroid Build Coastguard Worker     uint32_t requirements = 0;
700*35238bceSAndroid Build Coastguard Worker 
701*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_DYNAMIC || writeAccess == INDEXACCESS_DYNAMIC)
702*35238bceSAndroid Build Coastguard Worker         requirements |= REQUIREMENT_UNIFORM_INDEXING;
703*35238bceSAndroid Build Coastguard Worker 
704*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_DYNAMIC_LOOP || writeAccess == INDEXACCESS_DYNAMIC_LOOP)
705*35238bceSAndroid Build Coastguard Worker         requirements |= (isVertexCase ? REQUIREMENT_VERTEX_UNIFORM_LOOPS : REQUIREMENT_FRAGMENT_UNIFORM_LOOPS) |
706*35238bceSAndroid Build Coastguard Worker                         REQUIREMENT_UNIFORM_INDEXING;
707*35238bceSAndroid Build Coastguard Worker 
708*35238bceSAndroid Build Coastguard Worker     return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, requirements,
709*35238bceSAndroid Build Coastguard Worker                                   vertexShaderSource.c_str(), fragmentShaderSource.c_str());
710*35238bceSAndroid Build Coastguard Worker }
711*35238bceSAndroid Build Coastguard Worker 
712*35238bceSAndroid Build Coastguard Worker // VECTOR SUBSCRIPT.
713*35238bceSAndroid Build Coastguard Worker 
evalSubscriptVec2(ShaderEvalContext & c)714*35238bceSAndroid Build Coastguard Worker void evalSubscriptVec2(ShaderEvalContext &c)
715*35238bceSAndroid Build Coastguard Worker {
716*35238bceSAndroid Build Coastguard Worker     c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y());
717*35238bceSAndroid Build Coastguard Worker }
evalSubscriptVec3(ShaderEvalContext & c)718*35238bceSAndroid Build Coastguard Worker void evalSubscriptVec3(ShaderEvalContext &c)
719*35238bceSAndroid Build Coastguard Worker {
720*35238bceSAndroid Build Coastguard Worker     c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y() + 0.25f * c.coords.z());
721*35238bceSAndroid Build Coastguard Worker }
evalSubscriptVec4(ShaderEvalContext & c)722*35238bceSAndroid Build Coastguard Worker void evalSubscriptVec4(ShaderEvalContext &c)
723*35238bceSAndroid Build Coastguard Worker {
724*35238bceSAndroid Build Coastguard Worker     c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y() + 0.25f * c.coords.z() + 0.125f * c.coords.w());
725*35238bceSAndroid Build Coastguard Worker }
726*35238bceSAndroid Build Coastguard Worker 
getVectorSubscriptEvalFunc(DataType dataType)727*35238bceSAndroid Build Coastguard Worker static ShaderEvalFunc getVectorSubscriptEvalFunc(DataType dataType)
728*35238bceSAndroid Build Coastguard Worker {
729*35238bceSAndroid Build Coastguard Worker     if (dataType == TYPE_FLOAT_VEC2)
730*35238bceSAndroid Build Coastguard Worker         return evalSubscriptVec2;
731*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_VEC3)
732*35238bceSAndroid Build Coastguard Worker         return evalSubscriptVec3;
733*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_VEC4)
734*35238bceSAndroid Build Coastguard Worker         return evalSubscriptVec4;
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker     DE_FATAL("Invalid data type.");
737*35238bceSAndroid Build Coastguard Worker     return NULL;
738*35238bceSAndroid Build Coastguard Worker }
739*35238bceSAndroid Build Coastguard Worker 
createVectorSubscriptCase(Context & context,const char * caseName,const char * description,bool isVertexCase,DataType varType,VectorAccessType writeAccess,VectorAccessType readAccess)740*35238bceSAndroid Build Coastguard Worker static ShaderIndexingCase *createVectorSubscriptCase(Context &context, const char *caseName, const char *description,
741*35238bceSAndroid Build Coastguard Worker                                                      bool isVertexCase, DataType varType, VectorAccessType writeAccess,
742*35238bceSAndroid Build Coastguard Worker                                                      VectorAccessType readAccess)
743*35238bceSAndroid Build Coastguard Worker {
744*35238bceSAndroid Build Coastguard Worker     std::ostringstream vtx;
745*35238bceSAndroid Build Coastguard Worker     std::ostringstream frag;
746*35238bceSAndroid Build Coastguard Worker     std::ostringstream &op = isVertexCase ? vtx : frag;
747*35238bceSAndroid Build Coastguard Worker 
748*35238bceSAndroid Build Coastguard Worker     int vecLen             = getDataTypeScalarSize(varType);
749*35238bceSAndroid Build Coastguard Worker     const char *vecLenName = getIntUniformName(vecLen);
750*35238bceSAndroid Build Coastguard Worker 
751*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_position;\n";
752*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_coords;\n";
753*35238bceSAndroid Build Coastguard Worker 
754*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
755*35238bceSAndroid Build Coastguard Worker     {
756*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec3 v_color;\n";
757*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec3 v_color;\n";
758*35238bceSAndroid Build Coastguard Worker     }
759*35238bceSAndroid Build Coastguard Worker     else
760*35238bceSAndroid Build Coastguard Worker     {
761*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec4 v_coords;\n";
762*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec4 v_coords;\n";
763*35238bceSAndroid Build Coastguard Worker     }
764*35238bceSAndroid Build Coastguard Worker 
765*35238bceSAndroid Build Coastguard Worker     if (writeAccess == SUBSCRIPT_DYNAMIC || readAccess == SUBSCRIPT_DYNAMIC)
766*35238bceSAndroid Build Coastguard Worker     {
767*35238bceSAndroid Build Coastguard Worker         op << "uniform mediump int ui_zero";
768*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 2)
769*35238bceSAndroid Build Coastguard Worker             op << ", ui_one";
770*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 3)
771*35238bceSAndroid Build Coastguard Worker             op << ", ui_two";
772*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 4)
773*35238bceSAndroid Build Coastguard Worker             op << ", ui_three";
774*35238bceSAndroid Build Coastguard Worker         op << ";\n";
775*35238bceSAndroid Build Coastguard Worker     }
776*35238bceSAndroid Build Coastguard Worker 
777*35238bceSAndroid Build Coastguard Worker     if (writeAccess == SUBSCRIPT_DYNAMIC_LOOP || readAccess == SUBSCRIPT_DYNAMIC_LOOP)
778*35238bceSAndroid Build Coastguard Worker         op << "uniform mediump int " << vecLenName << ";\n";
779*35238bceSAndroid Build Coastguard Worker 
780*35238bceSAndroid Build Coastguard Worker     vtx << "\n";
781*35238bceSAndroid Build Coastguard Worker     vtx << "void main()\n";
782*35238bceSAndroid Build Coastguard Worker     vtx << "{\n";
783*35238bceSAndroid Build Coastguard Worker     vtx << "    gl_Position = a_position;\n";
784*35238bceSAndroid Build Coastguard Worker 
785*35238bceSAndroid Build Coastguard Worker     frag << "\n";
786*35238bceSAndroid Build Coastguard Worker     frag << "void main()\n";
787*35238bceSAndroid Build Coastguard Worker     frag << "{\n";
788*35238bceSAndroid Build Coastguard Worker 
789*35238bceSAndroid Build Coastguard Worker     // Write vector.
790*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
791*35238bceSAndroid Build Coastguard Worker         op << "    ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
792*35238bceSAndroid Build Coastguard Worker     else
793*35238bceSAndroid Build Coastguard Worker         op << "    ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";
794*35238bceSAndroid Build Coastguard Worker 
795*35238bceSAndroid Build Coastguard Worker     op << "    ${PRECISION} ${VAR_TYPE} tmp;\n";
796*35238bceSAndroid Build Coastguard Worker     if (writeAccess == DIRECT)
797*35238bceSAndroid Build Coastguard Worker         op << "    tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n";
798*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == COMPONENT)
799*35238bceSAndroid Build Coastguard Worker     {
800*35238bceSAndroid Build Coastguard Worker         op << "    tmp.x = coords.x;\n";
801*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 2)
802*35238bceSAndroid Build Coastguard Worker             op << "    tmp.y = coords.y * 0.5;\n";
803*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 3)
804*35238bceSAndroid Build Coastguard Worker             op << "    tmp.z = coords.z * 0.25;\n";
805*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 4)
806*35238bceSAndroid Build Coastguard Worker             op << "    tmp.w = coords.w * 0.125;\n";
807*35238bceSAndroid Build Coastguard Worker     }
808*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == SUBSCRIPT_STATIC)
809*35238bceSAndroid Build Coastguard Worker     {
810*35238bceSAndroid Build Coastguard Worker         op << "    tmp[0] = coords.x;\n";
811*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 2)
812*35238bceSAndroid Build Coastguard Worker             op << "    tmp[1] = coords.y * 0.5;\n";
813*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 3)
814*35238bceSAndroid Build Coastguard Worker             op << "    tmp[2] = coords.z * 0.25;\n";
815*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 4)
816*35238bceSAndroid Build Coastguard Worker             op << "    tmp[3] = coords.w * 0.125;\n";
817*35238bceSAndroid Build Coastguard Worker     }
818*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == SUBSCRIPT_DYNAMIC)
819*35238bceSAndroid Build Coastguard Worker     {
820*35238bceSAndroid Build Coastguard Worker         op << "    tmp[ui_zero]  = coords.x;\n";
821*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 2)
822*35238bceSAndroid Build Coastguard Worker             op << "    tmp[ui_one]   = coords.y * 0.5;\n";
823*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 3)
824*35238bceSAndroid Build Coastguard Worker             op << "    tmp[ui_two]   = coords.z * 0.25;\n";
825*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 4)
826*35238bceSAndroid Build Coastguard Worker             op << "    tmp[ui_three] = coords.w * 0.125;\n";
827*35238bceSAndroid Build Coastguard Worker     }
828*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == SUBSCRIPT_STATIC_LOOP)
829*35238bceSAndroid Build Coastguard Worker     {
830*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < " << vecLen << "; i++)\n";
831*35238bceSAndroid Build Coastguard Worker         op << "    {\n";
832*35238bceSAndroid Build Coastguard Worker         op << "        tmp[i] = coords.x;\n";
833*35238bceSAndroid Build Coastguard Worker         op << "        coords = coords.${ROT_SWIZZLE} * 0.5;\n";
834*35238bceSAndroid Build Coastguard Worker         op << "    }\n";
835*35238bceSAndroid Build Coastguard Worker     }
836*35238bceSAndroid Build Coastguard Worker     else
837*35238bceSAndroid Build Coastguard Worker     {
838*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(writeAccess == SUBSCRIPT_DYNAMIC_LOOP);
839*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < " << vecLenName << "; i++)\n";
840*35238bceSAndroid Build Coastguard Worker         op << "    {\n";
841*35238bceSAndroid Build Coastguard Worker         op << "        tmp[i] = coords.x;\n";
842*35238bceSAndroid Build Coastguard Worker         op << "        coords = coords.${ROT_SWIZZLE} * 0.5;\n";
843*35238bceSAndroid Build Coastguard Worker         op << "    }\n";
844*35238bceSAndroid Build Coastguard Worker     }
845*35238bceSAndroid Build Coastguard Worker 
846*35238bceSAndroid Build Coastguard Worker     // Read vector.
847*35238bceSAndroid Build Coastguard Worker     op << "    ${PRECISION} float res = 0.0;\n";
848*35238bceSAndroid Build Coastguard Worker     if (readAccess == DIRECT)
849*35238bceSAndroid Build Coastguard Worker         op << "    res = dot(tmp, ${VAR_TYPE}(1.0));\n";
850*35238bceSAndroid Build Coastguard Worker     else if (readAccess == COMPONENT)
851*35238bceSAndroid Build Coastguard Worker     {
852*35238bceSAndroid Build Coastguard Worker         op << "    res += tmp.x;\n";
853*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 2)
854*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp.y;\n";
855*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 3)
856*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp.z;\n";
857*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 4)
858*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp.w;\n";
859*35238bceSAndroid Build Coastguard Worker     }
860*35238bceSAndroid Build Coastguard Worker     else if (readAccess == SUBSCRIPT_STATIC)
861*35238bceSAndroid Build Coastguard Worker     {
862*35238bceSAndroid Build Coastguard Worker         op << "    res += tmp[0];\n";
863*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 2)
864*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[1];\n";
865*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 3)
866*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[2];\n";
867*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 4)
868*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[3];\n";
869*35238bceSAndroid Build Coastguard Worker     }
870*35238bceSAndroid Build Coastguard Worker     else if (readAccess == SUBSCRIPT_DYNAMIC)
871*35238bceSAndroid Build Coastguard Worker     {
872*35238bceSAndroid Build Coastguard Worker         op << "    res += tmp[ui_zero];\n";
873*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 2)
874*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[ui_one];\n";
875*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 3)
876*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[ui_two];\n";
877*35238bceSAndroid Build Coastguard Worker         if (vecLen >= 4)
878*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[ui_three];\n";
879*35238bceSAndroid Build Coastguard Worker     }
880*35238bceSAndroid Build Coastguard Worker     else if (readAccess == SUBSCRIPT_STATIC_LOOP)
881*35238bceSAndroid Build Coastguard Worker     {
882*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < " << vecLen << "; i++)\n";
883*35238bceSAndroid Build Coastguard Worker         op << "        res += tmp[i];\n";
884*35238bceSAndroid Build Coastguard Worker     }
885*35238bceSAndroid Build Coastguard Worker     else
886*35238bceSAndroid Build Coastguard Worker     {
887*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(readAccess == SUBSCRIPT_DYNAMIC_LOOP);
888*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < " << vecLenName << "; i++)\n";
889*35238bceSAndroid Build Coastguard Worker         op << "        res += tmp[i];\n";
890*35238bceSAndroid Build Coastguard Worker     }
891*35238bceSAndroid Build Coastguard Worker 
892*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
893*35238bceSAndroid Build Coastguard Worker     {
894*35238bceSAndroid Build Coastguard Worker         vtx << "    v_color = vec3(res);\n";
895*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = vec4(v_color, 1.0);\n";
896*35238bceSAndroid Build Coastguard Worker     }
897*35238bceSAndroid Build Coastguard Worker     else
898*35238bceSAndroid Build Coastguard Worker     {
899*35238bceSAndroid Build Coastguard Worker         vtx << "    v_coords = a_coords;\n";
900*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = vec4(vec3(res), 1.0);\n";
901*35238bceSAndroid Build Coastguard Worker     }
902*35238bceSAndroid Build Coastguard Worker 
903*35238bceSAndroid Build Coastguard Worker     vtx << "}\n";
904*35238bceSAndroid Build Coastguard Worker     frag << "}\n";
905*35238bceSAndroid Build Coastguard Worker 
906*35238bceSAndroid Build Coastguard Worker     // Fill in shader templates.
907*35238bceSAndroid Build Coastguard Worker     static const char *s_swizzles[5]    = {"", "x", "xy", "xyz", "xyzw"};
908*35238bceSAndroid Build Coastguard Worker     static const char *s_rotSwizzles[5] = {"", "x", "yx", "yzx", "yzwx"};
909*35238bceSAndroid Build Coastguard Worker 
910*35238bceSAndroid Build Coastguard Worker     map<string, string> params;
911*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
912*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("PRECISION", "mediump"));
913*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("SWIZZLE", s_swizzles[vecLen]));
914*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("ROT_SWIZZLE", s_rotSwizzles[vecLen]));
915*35238bceSAndroid Build Coastguard Worker 
916*35238bceSAndroid Build Coastguard Worker     StringTemplate vertTemplate(vtx.str().c_str());
917*35238bceSAndroid Build Coastguard Worker     StringTemplate fragTemplate(frag.str().c_str());
918*35238bceSAndroid Build Coastguard Worker     string vertexShaderSource   = vertTemplate.specialize(params);
919*35238bceSAndroid Build Coastguard Worker     string fragmentShaderSource = fragTemplate.specialize(params);
920*35238bceSAndroid Build Coastguard Worker 
921*35238bceSAndroid Build Coastguard Worker     ShaderEvalFunc evalFunc = getVectorSubscriptEvalFunc(varType);
922*35238bceSAndroid Build Coastguard Worker     uint32_t requirements   = 0;
923*35238bceSAndroid Build Coastguard Worker 
924*35238bceSAndroid Build Coastguard Worker     if (readAccess == SUBSCRIPT_DYNAMIC || writeAccess == SUBSCRIPT_DYNAMIC)
925*35238bceSAndroid Build Coastguard Worker         requirements |= REQUIREMENT_UNIFORM_INDEXING;
926*35238bceSAndroid Build Coastguard Worker 
927*35238bceSAndroid Build Coastguard Worker     if (readAccess == SUBSCRIPT_DYNAMIC_LOOP || writeAccess == SUBSCRIPT_DYNAMIC_LOOP)
928*35238bceSAndroid Build Coastguard Worker         requirements |= (isVertexCase ? REQUIREMENT_VERTEX_UNIFORM_LOOPS : REQUIREMENT_FRAGMENT_UNIFORM_LOOPS) |
929*35238bceSAndroid Build Coastguard Worker                         REQUIREMENT_UNIFORM_INDEXING;
930*35238bceSAndroid Build Coastguard Worker 
931*35238bceSAndroid Build Coastguard Worker     return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, requirements,
932*35238bceSAndroid Build Coastguard Worker                                   vertexShaderSource.c_str(), fragmentShaderSource.c_str());
933*35238bceSAndroid Build Coastguard Worker }
934*35238bceSAndroid Build Coastguard Worker 
935*35238bceSAndroid Build Coastguard Worker // MATRIX SUBSCRIPT.
936*35238bceSAndroid Build Coastguard Worker 
evalSubscriptMat2(ShaderEvalContext & c)937*35238bceSAndroid Build Coastguard Worker void evalSubscriptMat2(ShaderEvalContext &c)
938*35238bceSAndroid Build Coastguard Worker {
939*35238bceSAndroid Build Coastguard Worker     c.color.xy() = c.coords.swizzle(0, 1) + 0.5f * c.coords.swizzle(1, 2);
940*35238bceSAndroid Build Coastguard Worker }
evalSubscriptMat3(ShaderEvalContext & c)941*35238bceSAndroid Build Coastguard Worker void evalSubscriptMat3(ShaderEvalContext &c)
942*35238bceSAndroid Build Coastguard Worker {
943*35238bceSAndroid Build Coastguard Worker     c.color.xyz() = c.coords.swizzle(0, 1, 2) + 0.5f * c.coords.swizzle(1, 2, 3) + 0.25f * c.coords.swizzle(2, 3, 0);
944*35238bceSAndroid Build Coastguard Worker }
evalSubscriptMat4(ShaderEvalContext & c)945*35238bceSAndroid Build Coastguard Worker void evalSubscriptMat4(ShaderEvalContext &c)
946*35238bceSAndroid Build Coastguard Worker {
947*35238bceSAndroid Build Coastguard Worker     c.color = c.coords + 0.5f * c.coords.swizzle(1, 2, 3, 0) + 0.25f * c.coords.swizzle(2, 3, 0, 1) +
948*35238bceSAndroid Build Coastguard Worker               0.125f * c.coords.swizzle(3, 0, 1, 2);
949*35238bceSAndroid Build Coastguard Worker }
950*35238bceSAndroid Build Coastguard Worker 
getMatrixSubscriptEvalFunc(DataType dataType)951*35238bceSAndroid Build Coastguard Worker static ShaderEvalFunc getMatrixSubscriptEvalFunc(DataType dataType)
952*35238bceSAndroid Build Coastguard Worker {
953*35238bceSAndroid Build Coastguard Worker     if (dataType == TYPE_FLOAT_MAT2)
954*35238bceSAndroid Build Coastguard Worker         return evalSubscriptMat2;
955*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_MAT3)
956*35238bceSAndroid Build Coastguard Worker         return evalSubscriptMat3;
957*35238bceSAndroid Build Coastguard Worker     else if (dataType == TYPE_FLOAT_MAT4)
958*35238bceSAndroid Build Coastguard Worker         return evalSubscriptMat4;
959*35238bceSAndroid Build Coastguard Worker 
960*35238bceSAndroid Build Coastguard Worker     DE_FATAL("Invalid data type.");
961*35238bceSAndroid Build Coastguard Worker     return NULL;
962*35238bceSAndroid Build Coastguard Worker }
963*35238bceSAndroid Build Coastguard Worker 
createMatrixSubscriptCase(Context & context,const char * caseName,const char * description,bool isVertexCase,DataType varType,IndexAccessType writeAccess,IndexAccessType readAccess)964*35238bceSAndroid Build Coastguard Worker static ShaderIndexingCase *createMatrixSubscriptCase(Context &context, const char *caseName, const char *description,
965*35238bceSAndroid Build Coastguard Worker                                                      bool isVertexCase, DataType varType, IndexAccessType writeAccess,
966*35238bceSAndroid Build Coastguard Worker                                                      IndexAccessType readAccess)
967*35238bceSAndroid Build Coastguard Worker {
968*35238bceSAndroid Build Coastguard Worker     std::ostringstream vtx;
969*35238bceSAndroid Build Coastguard Worker     std::ostringstream frag;
970*35238bceSAndroid Build Coastguard Worker     std::ostringstream &op = isVertexCase ? vtx : frag;
971*35238bceSAndroid Build Coastguard Worker 
972*35238bceSAndroid Build Coastguard Worker     int matSize             = getDataTypeMatrixNumRows(varType);
973*35238bceSAndroid Build Coastguard Worker     const char *matSizeName = getIntUniformName(matSize);
974*35238bceSAndroid Build Coastguard Worker     DataType vecType        = getDataTypeFloatVec(matSize);
975*35238bceSAndroid Build Coastguard Worker 
976*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_position;\n";
977*35238bceSAndroid Build Coastguard Worker     vtx << "attribute highp vec4 a_coords;\n";
978*35238bceSAndroid Build Coastguard Worker 
979*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
980*35238bceSAndroid Build Coastguard Worker     {
981*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec4 v_color;\n";
982*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec4 v_color;\n";
983*35238bceSAndroid Build Coastguard Worker     }
984*35238bceSAndroid Build Coastguard Worker     else
985*35238bceSAndroid Build Coastguard Worker     {
986*35238bceSAndroid Build Coastguard Worker         vtx << "varying mediump vec4 v_coords;\n";
987*35238bceSAndroid Build Coastguard Worker         frag << "varying mediump vec4 v_coords;\n";
988*35238bceSAndroid Build Coastguard Worker     }
989*35238bceSAndroid Build Coastguard Worker 
990*35238bceSAndroid Build Coastguard Worker     if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
991*35238bceSAndroid Build Coastguard Worker     {
992*35238bceSAndroid Build Coastguard Worker         op << "uniform mediump int ui_zero";
993*35238bceSAndroid Build Coastguard Worker         if (matSize >= 2)
994*35238bceSAndroid Build Coastguard Worker             op << ", ui_one";
995*35238bceSAndroid Build Coastguard Worker         if (matSize >= 3)
996*35238bceSAndroid Build Coastguard Worker             op << ", ui_two";
997*35238bceSAndroid Build Coastguard Worker         if (matSize >= 4)
998*35238bceSAndroid Build Coastguard Worker             op << ", ui_three";
999*35238bceSAndroid Build Coastguard Worker         op << ";\n";
1000*35238bceSAndroid Build Coastguard Worker     }
1001*35238bceSAndroid Build Coastguard Worker 
1002*35238bceSAndroid Build Coastguard Worker     if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
1003*35238bceSAndroid Build Coastguard Worker         op << "uniform mediump int " << matSizeName << ";\n";
1004*35238bceSAndroid Build Coastguard Worker 
1005*35238bceSAndroid Build Coastguard Worker     vtx << "\n";
1006*35238bceSAndroid Build Coastguard Worker     vtx << "void main()\n";
1007*35238bceSAndroid Build Coastguard Worker     vtx << "{\n";
1008*35238bceSAndroid Build Coastguard Worker     vtx << "    gl_Position = a_position;\n";
1009*35238bceSAndroid Build Coastguard Worker 
1010*35238bceSAndroid Build Coastguard Worker     frag << "\n";
1011*35238bceSAndroid Build Coastguard Worker     frag << "void main()\n";
1012*35238bceSAndroid Build Coastguard Worker     frag << "{\n";
1013*35238bceSAndroid Build Coastguard Worker 
1014*35238bceSAndroid Build Coastguard Worker     // Write matrix.
1015*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
1016*35238bceSAndroid Build Coastguard Worker         op << "    ${PRECISION} vec4 coords = a_coords;\n";
1017*35238bceSAndroid Build Coastguard Worker     else
1018*35238bceSAndroid Build Coastguard Worker         op << "    ${PRECISION} vec4 coords = v_coords;\n";
1019*35238bceSAndroid Build Coastguard Worker 
1020*35238bceSAndroid Build Coastguard Worker     op << "    ${PRECISION} ${MAT_TYPE} tmp;\n";
1021*35238bceSAndroid Build Coastguard Worker     if (writeAccess == INDEXACCESS_STATIC)
1022*35238bceSAndroid Build Coastguard Worker     {
1023*35238bceSAndroid Build Coastguard Worker         op << "    tmp[0] = ${VEC_TYPE}(coords);\n";
1024*35238bceSAndroid Build Coastguard Worker         if (matSize >= 2)
1025*35238bceSAndroid Build Coastguard Worker             op << "    tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
1026*35238bceSAndroid Build Coastguard Worker         if (matSize >= 3)
1027*35238bceSAndroid Build Coastguard Worker             op << "    tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
1028*35238bceSAndroid Build Coastguard Worker         if (matSize >= 4)
1029*35238bceSAndroid Build Coastguard Worker             op << "    tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
1030*35238bceSAndroid Build Coastguard Worker     }
1031*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == INDEXACCESS_DYNAMIC)
1032*35238bceSAndroid Build Coastguard Worker     {
1033*35238bceSAndroid Build Coastguard Worker         op << "    tmp[ui_zero]  = ${VEC_TYPE}(coords);\n";
1034*35238bceSAndroid Build Coastguard Worker         if (matSize >= 2)
1035*35238bceSAndroid Build Coastguard Worker             op << "    tmp[ui_one]   = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
1036*35238bceSAndroid Build Coastguard Worker         if (matSize >= 3)
1037*35238bceSAndroid Build Coastguard Worker             op << "    tmp[ui_two]   = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
1038*35238bceSAndroid Build Coastguard Worker         if (matSize >= 4)
1039*35238bceSAndroid Build Coastguard Worker             op << "    tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
1040*35238bceSAndroid Build Coastguard Worker     }
1041*35238bceSAndroid Build Coastguard Worker     else if (writeAccess == INDEXACCESS_STATIC_LOOP)
1042*35238bceSAndroid Build Coastguard Worker     {
1043*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < " << matSize << "; i++)\n";
1044*35238bceSAndroid Build Coastguard Worker         op << "    {\n";
1045*35238bceSAndroid Build Coastguard Worker         op << "        tmp[i] = ${VEC_TYPE}(coords);\n";
1046*35238bceSAndroid Build Coastguard Worker         op << "        coords = coords.yzwx * 0.5;\n";
1047*35238bceSAndroid Build Coastguard Worker         op << "    }\n";
1048*35238bceSAndroid Build Coastguard Worker     }
1049*35238bceSAndroid Build Coastguard Worker     else
1050*35238bceSAndroid Build Coastguard Worker     {
1051*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
1052*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < " << matSizeName << "; i++)\n";
1053*35238bceSAndroid Build Coastguard Worker         op << "    {\n";
1054*35238bceSAndroid Build Coastguard Worker         op << "        tmp[i] = ${VEC_TYPE}(coords);\n";
1055*35238bceSAndroid Build Coastguard Worker         op << "        coords = coords.yzwx * 0.5;\n";
1056*35238bceSAndroid Build Coastguard Worker         op << "    }\n";
1057*35238bceSAndroid Build Coastguard Worker     }
1058*35238bceSAndroid Build Coastguard Worker 
1059*35238bceSAndroid Build Coastguard Worker     // Read matrix.
1060*35238bceSAndroid Build Coastguard Worker     op << "    ${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n";
1061*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_STATIC)
1062*35238bceSAndroid Build Coastguard Worker     {
1063*35238bceSAndroid Build Coastguard Worker         op << "    res += tmp[0];\n";
1064*35238bceSAndroid Build Coastguard Worker         if (matSize >= 2)
1065*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[1];\n";
1066*35238bceSAndroid Build Coastguard Worker         if (matSize >= 3)
1067*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[2];\n";
1068*35238bceSAndroid Build Coastguard Worker         if (matSize >= 4)
1069*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[3];\n";
1070*35238bceSAndroid Build Coastguard Worker     }
1071*35238bceSAndroid Build Coastguard Worker     else if (readAccess == INDEXACCESS_DYNAMIC)
1072*35238bceSAndroid Build Coastguard Worker     {
1073*35238bceSAndroid Build Coastguard Worker         op << "    res += tmp[ui_zero];\n";
1074*35238bceSAndroid Build Coastguard Worker         if (matSize >= 2)
1075*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[ui_one];\n";
1076*35238bceSAndroid Build Coastguard Worker         if (matSize >= 3)
1077*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[ui_two];\n";
1078*35238bceSAndroid Build Coastguard Worker         if (matSize >= 4)
1079*35238bceSAndroid Build Coastguard Worker             op << "    res += tmp[ui_three];\n";
1080*35238bceSAndroid Build Coastguard Worker     }
1081*35238bceSAndroid Build Coastguard Worker     else if (readAccess == INDEXACCESS_STATIC_LOOP)
1082*35238bceSAndroid Build Coastguard Worker     {
1083*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < " << matSize << "; i++)\n";
1084*35238bceSAndroid Build Coastguard Worker         op << "        res += tmp[i];\n";
1085*35238bceSAndroid Build Coastguard Worker     }
1086*35238bceSAndroid Build Coastguard Worker     else
1087*35238bceSAndroid Build Coastguard Worker     {
1088*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
1089*35238bceSAndroid Build Coastguard Worker         op << "    for (int i = 0; i < " << matSizeName << "; i++)\n";
1090*35238bceSAndroid Build Coastguard Worker         op << "        res += tmp[i];\n";
1091*35238bceSAndroid Build Coastguard Worker     }
1092*35238bceSAndroid Build Coastguard Worker 
1093*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
1094*35238bceSAndroid Build Coastguard Worker     {
1095*35238bceSAndroid Build Coastguard Worker         vtx << "    v_color = vec4(res${PADDING});\n";
1096*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = v_color;\n";
1097*35238bceSAndroid Build Coastguard Worker     }
1098*35238bceSAndroid Build Coastguard Worker     else
1099*35238bceSAndroid Build Coastguard Worker     {
1100*35238bceSAndroid Build Coastguard Worker         vtx << "    v_coords = a_coords;\n";
1101*35238bceSAndroid Build Coastguard Worker         frag << "    gl_FragColor = vec4(res${PADDING});\n";
1102*35238bceSAndroid Build Coastguard Worker     }
1103*35238bceSAndroid Build Coastguard Worker 
1104*35238bceSAndroid Build Coastguard Worker     vtx << "}\n";
1105*35238bceSAndroid Build Coastguard Worker     frag << "}\n";
1106*35238bceSAndroid Build Coastguard Worker 
1107*35238bceSAndroid Build Coastguard Worker     // Fill in shader templates.
1108*35238bceSAndroid Build Coastguard Worker     map<string, string> params;
1109*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("MAT_TYPE", getDataTypeName(varType)));
1110*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("VEC_TYPE", getDataTypeName(vecType)));
1111*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("PRECISION", "mediump"));
1112*35238bceSAndroid Build Coastguard Worker 
1113*35238bceSAndroid Build Coastguard Worker     if (matSize == 2)
1114*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
1115*35238bceSAndroid Build Coastguard Worker     else if (matSize == 3)
1116*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ", 1.0"));
1117*35238bceSAndroid Build Coastguard Worker     else
1118*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("PADDING", ""));
1119*35238bceSAndroid Build Coastguard Worker 
1120*35238bceSAndroid Build Coastguard Worker     StringTemplate vertTemplate(vtx.str().c_str());
1121*35238bceSAndroid Build Coastguard Worker     StringTemplate fragTemplate(frag.str().c_str());
1122*35238bceSAndroid Build Coastguard Worker     string vertexShaderSource   = vertTemplate.specialize(params);
1123*35238bceSAndroid Build Coastguard Worker     string fragmentShaderSource = fragTemplate.specialize(params);
1124*35238bceSAndroid Build Coastguard Worker 
1125*35238bceSAndroid Build Coastguard Worker     ShaderEvalFunc evalFunc = getMatrixSubscriptEvalFunc(varType);
1126*35238bceSAndroid Build Coastguard Worker     uint32_t requirements   = 0;
1127*35238bceSAndroid Build Coastguard Worker 
1128*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_DYNAMIC || writeAccess == INDEXACCESS_DYNAMIC)
1129*35238bceSAndroid Build Coastguard Worker         requirements |= REQUIREMENT_UNIFORM_INDEXING;
1130*35238bceSAndroid Build Coastguard Worker 
1131*35238bceSAndroid Build Coastguard Worker     if (readAccess == INDEXACCESS_DYNAMIC_LOOP || writeAccess == INDEXACCESS_DYNAMIC_LOOP)
1132*35238bceSAndroid Build Coastguard Worker         requirements |= (isVertexCase ? REQUIREMENT_VERTEX_UNIFORM_LOOPS : REQUIREMENT_FRAGMENT_UNIFORM_LOOPS) |
1133*35238bceSAndroid Build Coastguard Worker                         REQUIREMENT_UNIFORM_INDEXING;
1134*35238bceSAndroid Build Coastguard Worker 
1135*35238bceSAndroid Build Coastguard Worker     return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, requirements,
1136*35238bceSAndroid Build Coastguard Worker                                   vertexShaderSource.c_str(), fragmentShaderSource.c_str());
1137*35238bceSAndroid Build Coastguard Worker }
1138*35238bceSAndroid Build Coastguard Worker 
1139*35238bceSAndroid Build Coastguard Worker // ShaderIndexingTests.
1140*35238bceSAndroid Build Coastguard Worker 
ShaderIndexingTests(Context & context)1141*35238bceSAndroid Build Coastguard Worker ShaderIndexingTests::ShaderIndexingTests(Context &context) : TestCaseGroup(context, "indexing", "Indexing Tests")
1142*35238bceSAndroid Build Coastguard Worker {
1143*35238bceSAndroid Build Coastguard Worker }
1144*35238bceSAndroid Build Coastguard Worker 
~ShaderIndexingTests(void)1145*35238bceSAndroid Build Coastguard Worker ShaderIndexingTests::~ShaderIndexingTests(void)
1146*35238bceSAndroid Build Coastguard Worker {
1147*35238bceSAndroid Build Coastguard Worker }
1148*35238bceSAndroid Build Coastguard Worker 
init(void)1149*35238bceSAndroid Build Coastguard Worker void ShaderIndexingTests::init(void)
1150*35238bceSAndroid Build Coastguard Worker {
1151*35238bceSAndroid Build Coastguard Worker     static const ShaderType s_shaderTypes[] = {SHADERTYPE_VERTEX, SHADERTYPE_FRAGMENT};
1152*35238bceSAndroid Build Coastguard Worker 
1153*35238bceSAndroid Build Coastguard Worker     static const DataType s_floatAndVecTypes[] = {TYPE_FLOAT, TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4};
1154*35238bceSAndroid Build Coastguard Worker 
1155*35238bceSAndroid Build Coastguard Worker     // Varying array access cases.
1156*35238bceSAndroid Build Coastguard Worker     {
1157*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *varyingGroup = new TestCaseGroup(m_context, "varying_array", "Varying array access tests.");
1158*35238bceSAndroid Build Coastguard Worker         addChild(varyingGroup);
1159*35238bceSAndroid Build Coastguard Worker 
1160*35238bceSAndroid Build Coastguard Worker         for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1161*35238bceSAndroid Build Coastguard Worker         {
1162*35238bceSAndroid Build Coastguard Worker             DataType varType = s_floatAndVecTypes[typeNdx];
1163*35238bceSAndroid Build Coastguard Worker             for (int vertAccess = 0; vertAccess < INDEXACCESS_CONST; vertAccess++)
1164*35238bceSAndroid Build Coastguard Worker             {
1165*35238bceSAndroid Build Coastguard Worker                 for (int fragAccess = 0; fragAccess < INDEXACCESS_CONST; fragAccess++)
1166*35238bceSAndroid Build Coastguard Worker                 {
1167*35238bceSAndroid Build Coastguard Worker                     const char *vertAccessName = getIndexAccessTypeName((IndexAccessType)vertAccess);
1168*35238bceSAndroid Build Coastguard Worker                     const char *fragAccessName = getIndexAccessTypeName((IndexAccessType)fragAccess);
1169*35238bceSAndroid Build Coastguard Worker                     string name =
1170*35238bceSAndroid Build Coastguard Worker                         string(getDataTypeName(varType)) + "_" + vertAccessName + "_write_" + fragAccessName + "_read";
1171*35238bceSAndroid Build Coastguard Worker                     string desc = string("Varying array with ") + vertAccessName + " write in vertex shader and " +
1172*35238bceSAndroid Build Coastguard Worker                                   fragAccessName + " read in fragment shader.";
1173*35238bceSAndroid Build Coastguard Worker                     varyingGroup->addChild(createVaryingArrayCase(m_context, name.c_str(), desc.c_str(), varType,
1174*35238bceSAndroid Build Coastguard Worker                                                                   (IndexAccessType)vertAccess,
1175*35238bceSAndroid Build Coastguard Worker                                                                   (IndexAccessType)fragAccess));
1176*35238bceSAndroid Build Coastguard Worker                 }
1177*35238bceSAndroid Build Coastguard Worker             }
1178*35238bceSAndroid Build Coastguard Worker         }
1179*35238bceSAndroid Build Coastguard Worker     }
1180*35238bceSAndroid Build Coastguard Worker 
1181*35238bceSAndroid Build Coastguard Worker     // Uniform array access cases.
1182*35238bceSAndroid Build Coastguard Worker     {
1183*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *uniformGroup = new TestCaseGroup(m_context, "uniform_array", "Uniform array access tests.");
1184*35238bceSAndroid Build Coastguard Worker         addChild(uniformGroup);
1185*35238bceSAndroid Build Coastguard Worker 
1186*35238bceSAndroid Build Coastguard Worker         for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1187*35238bceSAndroid Build Coastguard Worker         {
1188*35238bceSAndroid Build Coastguard Worker             DataType varType = s_floatAndVecTypes[typeNdx];
1189*35238bceSAndroid Build Coastguard Worker             for (int readAccess = 0; readAccess < INDEXACCESS_CONST; readAccess++)
1190*35238bceSAndroid Build Coastguard Worker             {
1191*35238bceSAndroid Build Coastguard Worker                 const char *readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
1192*35238bceSAndroid Build Coastguard Worker                 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1193*35238bceSAndroid Build Coastguard Worker                 {
1194*35238bceSAndroid Build Coastguard Worker                     ShaderType shaderType      = s_shaderTypes[shaderTypeNdx];
1195*35238bceSAndroid Build Coastguard Worker                     const char *shaderTypeName = getShaderTypeName(shaderType);
1196*35238bceSAndroid Build Coastguard Worker                     string name = string(getDataTypeName(varType)) + "_" + readAccessName + "_read_" + shaderTypeName;
1197*35238bceSAndroid Build Coastguard Worker                     string desc =
1198*35238bceSAndroid Build Coastguard Worker                         string("Uniform array with ") + readAccessName + " read in " + shaderTypeName + " shader.";
1199*35238bceSAndroid Build Coastguard Worker                     bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1200*35238bceSAndroid Build Coastguard Worker                     uniformGroup->addChild(createUniformArrayCase(m_context, name.c_str(), desc.c_str(), isVertexCase,
1201*35238bceSAndroid Build Coastguard Worker                                                                   varType, (IndexAccessType)readAccess));
1202*35238bceSAndroid Build Coastguard Worker                 }
1203*35238bceSAndroid Build Coastguard Worker             }
1204*35238bceSAndroid Build Coastguard Worker         }
1205*35238bceSAndroid Build Coastguard Worker     }
1206*35238bceSAndroid Build Coastguard Worker 
1207*35238bceSAndroid Build Coastguard Worker     // Temporary array access cases.
1208*35238bceSAndroid Build Coastguard Worker     {
1209*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *tmpGroup = new TestCaseGroup(m_context, "tmp_array", "Temporary array access tests.");
1210*35238bceSAndroid Build Coastguard Worker         addChild(tmpGroup);
1211*35238bceSAndroid Build Coastguard Worker 
1212*35238bceSAndroid Build Coastguard Worker         for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1213*35238bceSAndroid Build Coastguard Worker         {
1214*35238bceSAndroid Build Coastguard Worker             DataType varType = s_floatAndVecTypes[typeNdx];
1215*35238bceSAndroid Build Coastguard Worker             for (int writeAccess = 0; writeAccess < INDEXACCESS_LAST; writeAccess++)
1216*35238bceSAndroid Build Coastguard Worker             {
1217*35238bceSAndroid Build Coastguard Worker                 for (int readAccess = 0; readAccess < INDEXACCESS_CONST; readAccess++)
1218*35238bceSAndroid Build Coastguard Worker                 {
1219*35238bceSAndroid Build Coastguard Worker                     const char *writeAccessName = getIndexAccessTypeName((IndexAccessType)writeAccess);
1220*35238bceSAndroid Build Coastguard Worker                     const char *readAccessName  = getIndexAccessTypeName((IndexAccessType)readAccess);
1221*35238bceSAndroid Build Coastguard Worker 
1222*35238bceSAndroid Build Coastguard Worker                     for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1223*35238bceSAndroid Build Coastguard Worker                     {
1224*35238bceSAndroid Build Coastguard Worker                         ShaderType shaderType      = s_shaderTypes[shaderTypeNdx];
1225*35238bceSAndroid Build Coastguard Worker                         const char *shaderTypeName = getShaderTypeName(shaderType);
1226*35238bceSAndroid Build Coastguard Worker                         string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" +
1227*35238bceSAndroid Build Coastguard Worker                                       readAccessName + "_read_" + shaderTypeName;
1228*35238bceSAndroid Build Coastguard Worker                         string desc = string("Temporary array with ") + writeAccessName + " write and " +
1229*35238bceSAndroid Build Coastguard Worker                                       readAccessName + " read in " + shaderTypeName + " shader.";
1230*35238bceSAndroid Build Coastguard Worker                         bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1231*35238bceSAndroid Build Coastguard Worker                         tmpGroup->addChild(createTmpArrayCase(m_context, name.c_str(), desc.c_str(), isVertexCase,
1232*35238bceSAndroid Build Coastguard Worker                                                               varType, (IndexAccessType)writeAccess,
1233*35238bceSAndroid Build Coastguard Worker                                                               (IndexAccessType)readAccess));
1234*35238bceSAndroid Build Coastguard Worker                     }
1235*35238bceSAndroid Build Coastguard Worker                 }
1236*35238bceSAndroid Build Coastguard Worker             }
1237*35238bceSAndroid Build Coastguard Worker         }
1238*35238bceSAndroid Build Coastguard Worker     }
1239*35238bceSAndroid Build Coastguard Worker 
1240*35238bceSAndroid Build Coastguard Worker     // Vector indexing with subscripts.
1241*35238bceSAndroid Build Coastguard Worker     {
1242*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *vecGroup = new TestCaseGroup(m_context, "vector_subscript", "Vector subscript indexing.");
1243*35238bceSAndroid Build Coastguard Worker         addChild(vecGroup);
1244*35238bceSAndroid Build Coastguard Worker 
1245*35238bceSAndroid Build Coastguard Worker         static const DataType s_vectorTypes[] = {TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4};
1246*35238bceSAndroid Build Coastguard Worker 
1247*35238bceSAndroid Build Coastguard Worker         for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_vectorTypes); typeNdx++)
1248*35238bceSAndroid Build Coastguard Worker         {
1249*35238bceSAndroid Build Coastguard Worker             DataType varType = s_vectorTypes[typeNdx];
1250*35238bceSAndroid Build Coastguard Worker             for (int writeAccess = 0; writeAccess < VECTORACCESS_LAST; writeAccess++)
1251*35238bceSAndroid Build Coastguard Worker             {
1252*35238bceSAndroid Build Coastguard Worker                 for (int readAccess = 0; readAccess < VECTORACCESS_LAST; readAccess++)
1253*35238bceSAndroid Build Coastguard Worker                 {
1254*35238bceSAndroid Build Coastguard Worker                     const char *writeAccessName = getVectorAccessTypeName((VectorAccessType)writeAccess);
1255*35238bceSAndroid Build Coastguard Worker                     const char *readAccessName  = getVectorAccessTypeName((VectorAccessType)readAccess);
1256*35238bceSAndroid Build Coastguard Worker 
1257*35238bceSAndroid Build Coastguard Worker                     for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1258*35238bceSAndroid Build Coastguard Worker                     {
1259*35238bceSAndroid Build Coastguard Worker                         ShaderType shaderType      = s_shaderTypes[shaderTypeNdx];
1260*35238bceSAndroid Build Coastguard Worker                         const char *shaderTypeName = getShaderTypeName(shaderType);
1261*35238bceSAndroid Build Coastguard Worker                         string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" +
1262*35238bceSAndroid Build Coastguard Worker                                       readAccessName + "_read_" + shaderTypeName;
1263*35238bceSAndroid Build Coastguard Worker                         string desc = string("Vector subscript access with ") + writeAccessName + " write and " +
1264*35238bceSAndroid Build Coastguard Worker                                       readAccessName + " read in " + shaderTypeName + " shader.";
1265*35238bceSAndroid Build Coastguard Worker                         bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1266*35238bceSAndroid Build Coastguard Worker                         vecGroup->addChild(
1267*35238bceSAndroid Build Coastguard Worker                             createVectorSubscriptCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType,
1268*35238bceSAndroid Build Coastguard Worker                                                       (VectorAccessType)writeAccess, (VectorAccessType)readAccess));
1269*35238bceSAndroid Build Coastguard Worker                     }
1270*35238bceSAndroid Build Coastguard Worker                 }
1271*35238bceSAndroid Build Coastguard Worker             }
1272*35238bceSAndroid Build Coastguard Worker         }
1273*35238bceSAndroid Build Coastguard Worker     }
1274*35238bceSAndroid Build Coastguard Worker 
1275*35238bceSAndroid Build Coastguard Worker     // Matrix indexing with subscripts.
1276*35238bceSAndroid Build Coastguard Worker     {
1277*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *matGroup = new TestCaseGroup(m_context, "matrix_subscript", "Matrix subscript indexing.");
1278*35238bceSAndroid Build Coastguard Worker         addChild(matGroup);
1279*35238bceSAndroid Build Coastguard Worker 
1280*35238bceSAndroid Build Coastguard Worker         static const DataType s_matrixTypes[] = {TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT4};
1281*35238bceSAndroid Build Coastguard Worker 
1282*35238bceSAndroid Build Coastguard Worker         for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_matrixTypes); typeNdx++)
1283*35238bceSAndroid Build Coastguard Worker         {
1284*35238bceSAndroid Build Coastguard Worker             DataType varType = s_matrixTypes[typeNdx];
1285*35238bceSAndroid Build Coastguard Worker             for (int writeAccess = 0; writeAccess < INDEXACCESS_CONST; writeAccess++)
1286*35238bceSAndroid Build Coastguard Worker             {
1287*35238bceSAndroid Build Coastguard Worker                 for (int readAccess = 0; readAccess < INDEXACCESS_CONST; readAccess++)
1288*35238bceSAndroid Build Coastguard Worker                 {
1289*35238bceSAndroid Build Coastguard Worker                     const char *writeAccessName = getIndexAccessTypeName((IndexAccessType)writeAccess);
1290*35238bceSAndroid Build Coastguard Worker                     const char *readAccessName  = getIndexAccessTypeName((IndexAccessType)readAccess);
1291*35238bceSAndroid Build Coastguard Worker 
1292*35238bceSAndroid Build Coastguard Worker                     for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1293*35238bceSAndroid Build Coastguard Worker                     {
1294*35238bceSAndroid Build Coastguard Worker                         ShaderType shaderType      = s_shaderTypes[shaderTypeNdx];
1295*35238bceSAndroid Build Coastguard Worker                         const char *shaderTypeName = getShaderTypeName(shaderType);
1296*35238bceSAndroid Build Coastguard Worker                         string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" +
1297*35238bceSAndroid Build Coastguard Worker                                       readAccessName + "_read_" + shaderTypeName;
1298*35238bceSAndroid Build Coastguard Worker                         string desc = string("Vector subscript access with ") + writeAccessName + " write and " +
1299*35238bceSAndroid Build Coastguard Worker                                       readAccessName + " read in " + shaderTypeName + " shader.";
1300*35238bceSAndroid Build Coastguard Worker                         bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1301*35238bceSAndroid Build Coastguard Worker                         matGroup->addChild(
1302*35238bceSAndroid Build Coastguard Worker                             createMatrixSubscriptCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType,
1303*35238bceSAndroid Build Coastguard Worker                                                       (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
1304*35238bceSAndroid Build Coastguard Worker                     }
1305*35238bceSAndroid Build Coastguard Worker                 }
1306*35238bceSAndroid Build Coastguard Worker             }
1307*35238bceSAndroid Build Coastguard Worker         }
1308*35238bceSAndroid Build Coastguard Worker     }
1309*35238bceSAndroid Build Coastguard Worker }
1310*35238bceSAndroid Build Coastguard Worker 
1311*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1312*35238bceSAndroid Build Coastguard Worker } // namespace gles2
1313*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1314