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