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