xref: /aosp_15_r20/external/deqp/modules/gles3/performance/es3pShaderCompilationCases.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Shader compilation performance tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es3pShaderCompilationCases.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuMatrix.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuPlatform.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuCPUWarmup.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluTexture.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "deClock.h"
40*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker #include <map>
46*35238bceSAndroid Build Coastguard Worker #include <algorithm>
47*35238bceSAndroid Build Coastguard Worker #include <limits>
48*35238bceSAndroid Build Coastguard Worker #include <iomanip>
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker using std::string;
51*35238bceSAndroid Build Coastguard Worker using std::vector;
52*35238bceSAndroid Build Coastguard Worker using tcu::Mat3;
53*35238bceSAndroid Build Coastguard Worker using tcu::Mat4;
54*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
55*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
56*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
57*35238bceSAndroid Build Coastguard Worker using namespace glw; // GL types
58*35238bceSAndroid Build Coastguard Worker 
59*35238bceSAndroid Build Coastguard Worker namespace deqp
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker 
62*35238bceSAndroid Build Coastguard Worker namespace gles3
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker namespace Performance
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker static const bool WARMUP_CPU_AT_BEGINNING_OF_CASE    = false;
69*35238bceSAndroid Build Coastguard Worker static const bool WARMUP_CPU_BEFORE_EACH_MEASUREMENT = true;
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker static const int MAX_VIEWPORT_WIDTH  = 64;
72*35238bceSAndroid Build Coastguard Worker static const int MAX_VIEWPORT_HEIGHT = 64;
73*35238bceSAndroid Build Coastguard Worker 
74*35238bceSAndroid Build Coastguard Worker static const int DEFAULT_MINIMUM_MEASUREMENT_COUNT              = 15;
75*35238bceSAndroid Build Coastguard Worker static const float RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD = 0.05f;
76*35238bceSAndroid Build Coastguard Worker 
77*35238bceSAndroid Build Coastguard Worker // Texture size for the light shader and texture lookup shader cases.
78*35238bceSAndroid Build Coastguard Worker static const int TEXTURE_WIDTH  = 64;
79*35238bceSAndroid Build Coastguard Worker static const int TEXTURE_HEIGHT = 64;
80*35238bceSAndroid Build Coastguard Worker 
81*35238bceSAndroid Build Coastguard Worker template <typename T>
toStringWithPadding(T value,int minLength)82*35238bceSAndroid Build Coastguard Worker inline string toStringWithPadding(T value, int minLength)
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker     std::ostringstream s;
85*35238bceSAndroid Build Coastguard Worker     s << std::setfill('0') << std::setw(minLength) << value;
86*35238bceSAndroid Build Coastguard Worker     return s.str();
87*35238bceSAndroid Build Coastguard Worker }
88*35238bceSAndroid Build Coastguard Worker 
89*35238bceSAndroid Build Coastguard Worker // Add some whitespace and comments to str. They should depend on uniqueNumber.
strWithWhiteSpaceAndComments(const string & str,uint32_t uniqueNumber)90*35238bceSAndroid Build Coastguard Worker static string strWithWhiteSpaceAndComments(const string &str, uint32_t uniqueNumber)
91*35238bceSAndroid Build Coastguard Worker {
92*35238bceSAndroid Build Coastguard Worker     string res("");
93*35238bceSAndroid Build Coastguard Worker 
94*35238bceSAndroid Build Coastguard Worker     // Find the first newline.
95*35238bceSAndroid Build Coastguard Worker     int firstLineEndNdx = 0;
96*35238bceSAndroid Build Coastguard Worker     while (firstLineEndNdx < (int)str.size() && str[firstLineEndNdx] != '\n')
97*35238bceSAndroid Build Coastguard Worker     {
98*35238bceSAndroid Build Coastguard Worker         res += str[firstLineEndNdx];
99*35238bceSAndroid Build Coastguard Worker         firstLineEndNdx++;
100*35238bceSAndroid Build Coastguard Worker     }
101*35238bceSAndroid Build Coastguard Worker     res += '\n';
102*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(firstLineEndNdx < (int)str.size());
103*35238bceSAndroid Build Coastguard Worker 
104*35238bceSAndroid Build Coastguard Worker     // Add the whitespaces and comments just after the first line.
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker     de::Random rnd(uniqueNumber);
107*35238bceSAndroid Build Coastguard Worker     int numWS = rnd.getInt(10, 20);
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numWS; i++)
110*35238bceSAndroid Build Coastguard Worker         res += " \t\n"[rnd.getInt(0, 2)];
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker     res += "/* unique comment " + de::toString(uniqueNumber) + " */\n";
113*35238bceSAndroid Build Coastguard Worker     res += "// unique comment " + de::toString(uniqueNumber) + "\n";
114*35238bceSAndroid Build Coastguard Worker 
115*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numWS; i++)
116*35238bceSAndroid Build Coastguard Worker         res += " \t\n"[rnd.getInt(0, 2)];
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker     // Add the rest of the string.
119*35238bceSAndroid Build Coastguard Worker     res.append(&str.c_str()[firstLineEndNdx + 1]);
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker     return res;
122*35238bceSAndroid Build Coastguard Worker }
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker //! Helper for computing relative magnitudes while avoiding division by zero.
hackySafeRelativeResult(float x,float y)125*35238bceSAndroid Build Coastguard Worker static float hackySafeRelativeResult(float x, float y)
126*35238bceSAndroid Build Coastguard Worker {
127*35238bceSAndroid Build Coastguard Worker     // \note A possible case is that x is standard deviation, and y is average
128*35238bceSAndroid Build Coastguard Worker     //         (or similarly for median or some such). So, if y is 0, that
129*35238bceSAndroid Build Coastguard Worker     //         probably means that x is also 0(ish) (because in practice we're
130*35238bceSAndroid Build Coastguard Worker     //         dealing with non-negative values, in which case an average of 0
131*35238bceSAndroid Build Coastguard Worker     //         implies that the samples are all 0 - note that the same isn't
132*35238bceSAndroid Build Coastguard Worker     //         strictly true for things like median) so a relative result of 0
133*35238bceSAndroid Build Coastguard Worker     //         wouldn't be that far from the truth.
134*35238bceSAndroid Build Coastguard Worker     return y == 0.0f ? 0.0f : x / y;
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker 
137*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatAverage(const vector<T> & v)138*35238bceSAndroid Build Coastguard Worker static float vectorFloatAverage(const vector<T> &v)
139*35238bceSAndroid Build Coastguard Worker {
140*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!v.empty());
141*35238bceSAndroid Build Coastguard Worker     float result = 0.0f;
142*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)v.size(); i++)
143*35238bceSAndroid Build Coastguard Worker         result += (float)v[i];
144*35238bceSAndroid Build Coastguard Worker     return result / (float)v.size();
145*35238bceSAndroid Build Coastguard Worker }
146*35238bceSAndroid Build Coastguard Worker 
147*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatMedian(const vector<T> & v)148*35238bceSAndroid Build Coastguard Worker static float vectorFloatMedian(const vector<T> &v)
149*35238bceSAndroid Build Coastguard Worker {
150*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!v.empty());
151*35238bceSAndroid Build Coastguard Worker     vector<T> temp = v;
152*35238bceSAndroid Build Coastguard Worker     std::sort(temp.begin(), temp.end());
153*35238bceSAndroid Build Coastguard Worker     return temp.size() % 2 == 0 ? 0.5f * ((float)temp[temp.size() / 2 - 1] + (float)temp[temp.size() / 2]) :
154*35238bceSAndroid Build Coastguard Worker                                   (float)temp[temp.size() / 2];
155*35238bceSAndroid Build Coastguard Worker }
156*35238bceSAndroid Build Coastguard Worker 
157*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatMinimum(const vector<T> & v)158*35238bceSAndroid Build Coastguard Worker static float vectorFloatMinimum(const vector<T> &v)
159*35238bceSAndroid Build Coastguard Worker {
160*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!v.empty());
161*35238bceSAndroid Build Coastguard Worker     return (float)*std::min_element(v.begin(), v.end());
162*35238bceSAndroid Build Coastguard Worker }
163*35238bceSAndroid Build Coastguard Worker 
164*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatMaximum(const vector<T> & v)165*35238bceSAndroid Build Coastguard Worker static float vectorFloatMaximum(const vector<T> &v)
166*35238bceSAndroid Build Coastguard Worker {
167*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!v.empty());
168*35238bceSAndroid Build Coastguard Worker     return (float)*std::max_element(v.begin(), v.end());
169*35238bceSAndroid Build Coastguard Worker }
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatStandardDeviation(const vector<T> & v)172*35238bceSAndroid Build Coastguard Worker static float vectorFloatStandardDeviation(const vector<T> &v)
173*35238bceSAndroid Build Coastguard Worker {
174*35238bceSAndroid Build Coastguard Worker     float average = vectorFloatAverage(v);
175*35238bceSAndroid Build Coastguard Worker     float result  = 0.0f;
176*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)v.size(); i++)
177*35238bceSAndroid Build Coastguard Worker     {
178*35238bceSAndroid Build Coastguard Worker         float d = (float)v[i] - average;
179*35238bceSAndroid Build Coastguard Worker         result += d * d;
180*35238bceSAndroid Build Coastguard Worker     }
181*35238bceSAndroid Build Coastguard Worker     return deFloatSqrt(result / (float)v.size());
182*35238bceSAndroid Build Coastguard Worker }
183*35238bceSAndroid Build Coastguard Worker 
184*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatRelativeStandardDeviation(const vector<T> & v)185*35238bceSAndroid Build Coastguard Worker static float vectorFloatRelativeStandardDeviation(const vector<T> &v)
186*35238bceSAndroid Build Coastguard Worker {
187*35238bceSAndroid Build Coastguard Worker     return hackySafeRelativeResult(vectorFloatStandardDeviation(v), vectorFloatAverage(v));
188*35238bceSAndroid Build Coastguard Worker }
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatMedianAbsoluteDeviation(const vector<T> & v)191*35238bceSAndroid Build Coastguard Worker static float vectorFloatMedianAbsoluteDeviation(const vector<T> &v)
192*35238bceSAndroid Build Coastguard Worker {
193*35238bceSAndroid Build Coastguard Worker     float median = vectorFloatMedian(v);
194*35238bceSAndroid Build Coastguard Worker     vector<float> absoluteDeviations(v.size());
195*35238bceSAndroid Build Coastguard Worker 
196*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)v.size(); i++)
197*35238bceSAndroid Build Coastguard Worker         absoluteDeviations[i] = deFloatAbs((float)v[i] - median);
198*35238bceSAndroid Build Coastguard Worker 
199*35238bceSAndroid Build Coastguard Worker     return vectorFloatMedian(absoluteDeviations);
200*35238bceSAndroid Build Coastguard Worker }
201*35238bceSAndroid Build Coastguard Worker 
202*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatRelativeMedianAbsoluteDeviation(const vector<T> & v)203*35238bceSAndroid Build Coastguard Worker static float vectorFloatRelativeMedianAbsoluteDeviation(const vector<T> &v)
204*35238bceSAndroid Build Coastguard Worker {
205*35238bceSAndroid Build Coastguard Worker     return hackySafeRelativeResult(vectorFloatMedianAbsoluteDeviation(v), vectorFloatMedian(v));
206*35238bceSAndroid Build Coastguard Worker }
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatMaximumMinusMinimum(const vector<T> & v)209*35238bceSAndroid Build Coastguard Worker static float vectorFloatMaximumMinusMinimum(const vector<T> &v)
210*35238bceSAndroid Build Coastguard Worker {
211*35238bceSAndroid Build Coastguard Worker     return vectorFloatMaximum(v) - vectorFloatMinimum(v);
212*35238bceSAndroid Build Coastguard Worker }
213*35238bceSAndroid Build Coastguard Worker 
214*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatRelativeMaximumMinusMinimum(const vector<T> & v)215*35238bceSAndroid Build Coastguard Worker static float vectorFloatRelativeMaximumMinusMinimum(const vector<T> &v)
216*35238bceSAndroid Build Coastguard Worker {
217*35238bceSAndroid Build Coastguard Worker     return hackySafeRelativeResult(vectorFloatMaximumMinusMinimum(v), vectorFloatMaximum(v));
218*35238bceSAndroid Build Coastguard Worker }
219*35238bceSAndroid Build Coastguard Worker 
220*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorLowestPercentage(const vector<T> & v,float factor)221*35238bceSAndroid Build Coastguard Worker static vector<T> vectorLowestPercentage(const vector<T> &v, float factor)
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(0.0f < factor && factor <= 1.0f);
224*35238bceSAndroid Build Coastguard Worker 
225*35238bceSAndroid Build Coastguard Worker     int targetSize = (int)(deFloatCeil(factor * (float)v.size()));
226*35238bceSAndroid Build Coastguard Worker     vector<T> temp = v;
227*35238bceSAndroid Build Coastguard Worker     std::sort(temp.begin(), temp.end());
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker     while ((int)temp.size() > targetSize)
230*35238bceSAndroid Build Coastguard Worker         temp.pop_back();
231*35238bceSAndroid Build Coastguard Worker 
232*35238bceSAndroid Build Coastguard Worker     return temp;
233*35238bceSAndroid Build Coastguard Worker }
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker template <typename T>
vectorFloatFirstQuartile(const vector<T> & v)236*35238bceSAndroid Build Coastguard Worker static float vectorFloatFirstQuartile(const vector<T> &v)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker     return vectorFloatMedian(vectorLowestPercentage(v, 0.5f));
239*35238bceSAndroid Build Coastguard Worker }
240*35238bceSAndroid Build Coastguard Worker 
241*35238bceSAndroid Build Coastguard Worker // Helper function for combining 4 tcu::Vec4's into one tcu::Vector<float, 16>.
combineVec4ToVec16(const Vec4 & a0,const Vec4 & a1,const Vec4 & a2,const Vec4 & a3)242*35238bceSAndroid Build Coastguard Worker static tcu::Vector<float, 16> combineVec4ToVec16(const Vec4 &a0, const Vec4 &a1, const Vec4 &a2, const Vec4 &a3)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker     tcu::Vector<float, 16> result;
245*35238bceSAndroid Build Coastguard Worker 
246*35238bceSAndroid Build Coastguard Worker     for (int vecNdx = 0; vecNdx < 4; vecNdx++)
247*35238bceSAndroid Build Coastguard Worker     {
248*35238bceSAndroid Build Coastguard Worker         const Vec4 &srcVec = vecNdx == 0 ? a0 : vecNdx == 1 ? a1 : vecNdx == 2 ? a2 : a3;
249*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 4; i++)
250*35238bceSAndroid Build Coastguard Worker             result[vecNdx * 4 + i] = srcVec[i];
251*35238bceSAndroid Build Coastguard Worker     }
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker     return result;
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker // Helper function for extending an n-sized (n <= 16) vector to a 16-sized vector (padded with zeros).
257*35238bceSAndroid Build Coastguard Worker template <int Size>
vecTo16(const tcu::Vector<float,Size> & vec)258*35238bceSAndroid Build Coastguard Worker static tcu::Vector<float, 16> vecTo16(const tcu::Vector<float, Size> &vec)
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(Size <= 16);
261*35238bceSAndroid Build Coastguard Worker 
262*35238bceSAndroid Build Coastguard Worker     tcu::Vector<float, 16> res(0.0f);
263*35238bceSAndroid Build Coastguard Worker 
264*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < Size; i++)
265*35238bceSAndroid Build Coastguard Worker         res[i] = vec[i];
266*35238bceSAndroid Build Coastguard Worker 
267*35238bceSAndroid Build Coastguard Worker     return res;
268*35238bceSAndroid Build Coastguard Worker }
269*35238bceSAndroid Build Coastguard Worker 
270*35238bceSAndroid Build Coastguard Worker // Helper function for extending an n-sized (n <= 16) array to a 16-sized vector (padded with zeros).
271*35238bceSAndroid Build Coastguard Worker template <int Size>
arrTo16(const tcu::Array<float,Size> & arr)272*35238bceSAndroid Build Coastguard Worker static tcu::Vector<float, 16> arrTo16(const tcu::Array<float, Size> &arr)
273*35238bceSAndroid Build Coastguard Worker {
274*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(Size <= 16);
275*35238bceSAndroid Build Coastguard Worker 
276*35238bceSAndroid Build Coastguard Worker     tcu::Vector<float, 16> res(0.0f);
277*35238bceSAndroid Build Coastguard Worker 
278*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < Size; i++)
279*35238bceSAndroid Build Coastguard Worker         res[i] = arr[i];
280*35238bceSAndroid Build Coastguard Worker 
281*35238bceSAndroid Build Coastguard Worker     return res;
282*35238bceSAndroid Build Coastguard Worker }
283*35238bceSAndroid Build Coastguard Worker 
getShaderInfoLog(const glw::Functions & gl,uint32_t shader)284*35238bceSAndroid Build Coastguard Worker static string getShaderInfoLog(const glw::Functions &gl, uint32_t shader)
285*35238bceSAndroid Build Coastguard Worker {
286*35238bceSAndroid Build Coastguard Worker     string result;
287*35238bceSAndroid Build Coastguard Worker     int infoLogLen = 0;
288*35238bceSAndroid Build Coastguard Worker     vector<char> infoLogBuf;
289*35238bceSAndroid Build Coastguard Worker 
290*35238bceSAndroid Build Coastguard Worker     gl.getShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
291*35238bceSAndroid Build Coastguard Worker     infoLogBuf.resize(infoLogLen + 1);
292*35238bceSAndroid Build Coastguard Worker     gl.getShaderInfoLog(shader, infoLogLen + 1, DE_NULL, &infoLogBuf[0]);
293*35238bceSAndroid Build Coastguard Worker     result = &infoLogBuf[0];
294*35238bceSAndroid Build Coastguard Worker 
295*35238bceSAndroid Build Coastguard Worker     return result;
296*35238bceSAndroid Build Coastguard Worker }
297*35238bceSAndroid Build Coastguard Worker 
getProgramInfoLog(const glw::Functions & gl,uint32_t program)298*35238bceSAndroid Build Coastguard Worker static string getProgramInfoLog(const glw::Functions &gl, uint32_t program)
299*35238bceSAndroid Build Coastguard Worker {
300*35238bceSAndroid Build Coastguard Worker     string result;
301*35238bceSAndroid Build Coastguard Worker     int infoLogLen = 0;
302*35238bceSAndroid Build Coastguard Worker     vector<char> infoLogBuf;
303*35238bceSAndroid Build Coastguard Worker 
304*35238bceSAndroid Build Coastguard Worker     gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen);
305*35238bceSAndroid Build Coastguard Worker     infoLogBuf.resize(infoLogLen + 1);
306*35238bceSAndroid Build Coastguard Worker     gl.getProgramInfoLog(program, infoLogLen + 1, DE_NULL, &infoLogBuf[0]);
307*35238bceSAndroid Build Coastguard Worker     result = &infoLogBuf[0];
308*35238bceSAndroid Build Coastguard Worker 
309*35238bceSAndroid Build Coastguard Worker     return result;
310*35238bceSAndroid Build Coastguard Worker }
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker enum LightType
313*35238bceSAndroid Build Coastguard Worker {
314*35238bceSAndroid Build Coastguard Worker     LIGHT_DIRECTIONAL = 0,
315*35238bceSAndroid Build Coastguard Worker     LIGHT_POINT,
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker     LIGHT_LAST,
318*35238bceSAndroid Build Coastguard Worker };
319*35238bceSAndroid Build Coastguard Worker 
320*35238bceSAndroid Build Coastguard Worker enum LoopType
321*35238bceSAndroid Build Coastguard Worker {
322*35238bceSAndroid Build Coastguard Worker     LOOP_TYPE_STATIC = 0,
323*35238bceSAndroid Build Coastguard Worker     LOOP_TYPE_UNIFORM,
324*35238bceSAndroid Build Coastguard Worker     LOOP_TYPE_DYNAMIC,
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker     LOOP_LAST
327*35238bceSAndroid Build Coastguard Worker };
328*35238bceSAndroid Build Coastguard Worker 
329*35238bceSAndroid Build Coastguard Worker // For texture lookup cases: which texture lookups are inside a conditional statement.
330*35238bceSAndroid Build Coastguard Worker enum ConditionalUsage
331*35238bceSAndroid Build Coastguard Worker {
332*35238bceSAndroid Build Coastguard Worker     CONDITIONAL_USAGE_NONE = 0,    // No conditional statements.
333*35238bceSAndroid Build Coastguard Worker     CONDITIONAL_USAGE_FIRST_HALF,  // First numLookUps/2 lookups are inside a conditional statement.
334*35238bceSAndroid Build Coastguard Worker     CONDITIONAL_USAGE_EVERY_OTHER, // First, third etc. lookups are inside conditional statements.
335*35238bceSAndroid Build Coastguard Worker 
336*35238bceSAndroid Build Coastguard Worker     CONDITIONAL_USAGE_LAST
337*35238bceSAndroid Build Coastguard Worker };
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker enum ConditionalType
340*35238bceSAndroid Build Coastguard Worker {
341*35238bceSAndroid Build Coastguard Worker     CONDITIONAL_TYPE_STATIC = 0,
342*35238bceSAndroid Build Coastguard Worker     CONDITIONAL_TYPE_UNIFORM,
343*35238bceSAndroid Build Coastguard Worker     CONDITIONAL_TYPE_DYNAMIC,
344*35238bceSAndroid Build Coastguard Worker 
345*35238bceSAndroid Build Coastguard Worker     CONDITIONAL_TYPE_LAST
346*35238bceSAndroid Build Coastguard Worker };
347*35238bceSAndroid Build Coastguard Worker 
348*35238bceSAndroid Build Coastguard Worker // For the invalid shader compilation tests; what kind of invalidity a shader shall contain.
349*35238bceSAndroid Build Coastguard Worker enum ShaderValidity
350*35238bceSAndroid Build Coastguard Worker {
351*35238bceSAndroid Build Coastguard Worker     SHADER_VALIDITY_VALID = 0,
352*35238bceSAndroid Build Coastguard Worker     SHADER_VALIDITY_INVALID_CHAR,
353*35238bceSAndroid Build Coastguard Worker     SHADER_VALIDITY_SEMANTIC_ERROR,
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker     SHADER_VALIDITY_LAST
356*35238bceSAndroid Build Coastguard Worker };
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker class ShaderCompilerCase : public TestCase
359*35238bceSAndroid Build Coastguard Worker {
360*35238bceSAndroid Build Coastguard Worker public:
361*35238bceSAndroid Build Coastguard Worker     struct AttribSpec
362*35238bceSAndroid Build Coastguard Worker     {
363*35238bceSAndroid Build Coastguard Worker         string name;
364*35238bceSAndroid Build Coastguard Worker         tcu::Vector<float, 16> value;
365*35238bceSAndroid Build Coastguard Worker 
AttribSpecdeqp::gles3::Performance::ShaderCompilerCase::AttribSpec366*35238bceSAndroid Build Coastguard Worker         AttribSpec(const string &n, const tcu::Vector<float, 16> &v) : name(n), value(v)
367*35238bceSAndroid Build Coastguard Worker         {
368*35238bceSAndroid Build Coastguard Worker         }
369*35238bceSAndroid Build Coastguard Worker     };
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker     struct UniformSpec
372*35238bceSAndroid Build Coastguard Worker     {
373*35238bceSAndroid Build Coastguard Worker         enum Type
374*35238bceSAndroid Build Coastguard Worker         {
375*35238bceSAndroid Build Coastguard Worker             TYPE_FLOAT = 0,
376*35238bceSAndroid Build Coastguard Worker             TYPE_VEC2,
377*35238bceSAndroid Build Coastguard Worker             TYPE_VEC3,
378*35238bceSAndroid Build Coastguard Worker             TYPE_VEC4,
379*35238bceSAndroid Build Coastguard Worker 
380*35238bceSAndroid Build Coastguard Worker             TYPE_MAT3,
381*35238bceSAndroid Build Coastguard Worker             TYPE_MAT4,
382*35238bceSAndroid Build Coastguard Worker 
383*35238bceSAndroid Build Coastguard Worker             TYPE_TEXTURE_UNIT,
384*35238bceSAndroid Build Coastguard Worker 
385*35238bceSAndroid Build Coastguard Worker             TYPE_LAST
386*35238bceSAndroid Build Coastguard Worker         };
387*35238bceSAndroid Build Coastguard Worker 
388*35238bceSAndroid Build Coastguard Worker         string name;
389*35238bceSAndroid Build Coastguard Worker         Type type;
390*35238bceSAndroid Build Coastguard Worker         tcu::Vector<float, 16> value;
391*35238bceSAndroid Build Coastguard Worker 
UniformSpecdeqp::gles3::Performance::ShaderCompilerCase::UniformSpec392*35238bceSAndroid Build Coastguard Worker         UniformSpec(const string &n, Type t, float v) : name(n), type(t), value(v)
393*35238bceSAndroid Build Coastguard Worker         {
394*35238bceSAndroid Build Coastguard Worker         }
UniformSpecdeqp::gles3::Performance::ShaderCompilerCase::UniformSpec395*35238bceSAndroid Build Coastguard Worker         UniformSpec(const string &n, Type t, const tcu::Vector<float, 16> &v) : name(n), type(t), value(v)
396*35238bceSAndroid Build Coastguard Worker         {
397*35238bceSAndroid Build Coastguard Worker         }
398*35238bceSAndroid Build Coastguard Worker     };
399*35238bceSAndroid Build Coastguard Worker 
400*35238bceSAndroid Build Coastguard Worker     ShaderCompilerCase(Context &context, const char *name, const char *description, int caseID, bool avoidCache,
401*35238bceSAndroid Build Coastguard Worker                        bool addWhitespaceAndComments);
402*35238bceSAndroid Build Coastguard Worker     ~ShaderCompilerCase(void);
403*35238bceSAndroid Build Coastguard Worker 
404*35238bceSAndroid Build Coastguard Worker     void init(void);
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
407*35238bceSAndroid Build Coastguard Worker 
408*35238bceSAndroid Build Coastguard Worker protected:
409*35238bceSAndroid Build Coastguard Worker     struct ProgramContext
410*35238bceSAndroid Build Coastguard Worker     {
411*35238bceSAndroid Build Coastguard Worker         string vertShaderSource;
412*35238bceSAndroid Build Coastguard Worker         string fragShaderSource;
413*35238bceSAndroid Build Coastguard Worker         vector<AttribSpec> vertexAttributes;
414*35238bceSAndroid Build Coastguard Worker         vector<UniformSpec> uniforms;
415*35238bceSAndroid Build Coastguard Worker     };
416*35238bceSAndroid Build Coastguard Worker 
417*35238bceSAndroid Build Coastguard Worker     uint32_t getSpecializationID(int measurementNdx)
418*35238bceSAndroid Build Coastguard Worker         const; // Return an ID that depends on the case ID, current measurement index and time; used to specialize attribute names etc. (avoid shader caching).
419*35238bceSAndroid Build Coastguard Worker     virtual ProgramContext generateShaderData(int measurementNdx)
420*35238bceSAndroid Build Coastguard Worker         const = 0; // Generate shader sources and inputs. Attribute etc. names depend on above name specialization.
421*35238bceSAndroid Build Coastguard Worker 
422*35238bceSAndroid Build Coastguard Worker private:
423*35238bceSAndroid Build Coastguard Worker     struct Measurement
424*35238bceSAndroid Build Coastguard Worker     {
425*35238bceSAndroid Build Coastguard Worker         // \note All times in microseconds. 32-bit integers would probably suffice (would need over an hour of test case runtime to overflow), but better safe than sorry.
426*35238bceSAndroid Build Coastguard Worker         int64_t sourceSetTime;
427*35238bceSAndroid Build Coastguard Worker         int64_t vertexCompileTime;
428*35238bceSAndroid Build Coastguard Worker         int64_t fragmentCompileTime;
429*35238bceSAndroid Build Coastguard Worker         int64_t programLinkTime;
430*35238bceSAndroid Build Coastguard Worker         int64_t firstInputSetTime;
431*35238bceSAndroid Build Coastguard Worker         int64_t firstDrawTime;
432*35238bceSAndroid Build Coastguard Worker 
433*35238bceSAndroid Build Coastguard Worker         int64_t secondInputSetTime;
434*35238bceSAndroid Build Coastguard Worker         int64_t secondDrawTime;
435*35238bceSAndroid Build Coastguard Worker 
firstPhasedeqp::gles3::Performance::ShaderCompilerCase::Measurement436*35238bceSAndroid Build Coastguard Worker         int64_t firstPhase(void) const
437*35238bceSAndroid Build Coastguard Worker         {
438*35238bceSAndroid Build Coastguard Worker             return sourceSetTime + vertexCompileTime + fragmentCompileTime + programLinkTime + firstInputSetTime +
439*35238bceSAndroid Build Coastguard Worker                    firstDrawTime;
440*35238bceSAndroid Build Coastguard Worker         }
secondPhasedeqp::gles3::Performance::ShaderCompilerCase::Measurement441*35238bceSAndroid Build Coastguard Worker         int64_t secondPhase(void) const
442*35238bceSAndroid Build Coastguard Worker         {
443*35238bceSAndroid Build Coastguard Worker             return secondInputSetTime + secondDrawTime;
444*35238bceSAndroid Build Coastguard Worker         }
445*35238bceSAndroid Build Coastguard Worker 
totalTimeWithoutDrawdeqp::gles3::Performance::ShaderCompilerCase::Measurement446*35238bceSAndroid Build Coastguard Worker         int64_t totalTimeWithoutDraw(void) const
447*35238bceSAndroid Build Coastguard Worker         {
448*35238bceSAndroid Build Coastguard Worker             return firstPhase() - de::min(secondPhase(), firstInputSetTime + firstDrawTime);
449*35238bceSAndroid Build Coastguard Worker         }
450*35238bceSAndroid Build Coastguard Worker 
Measurementdeqp::gles3::Performance::ShaderCompilerCase::Measurement451*35238bceSAndroid Build Coastguard Worker         Measurement(int64_t sourceSetTime_, int64_t vertexCompileTime_, int64_t fragmentCompileTime_,
452*35238bceSAndroid Build Coastguard Worker                     int64_t programLinkTime_, int64_t firstInputSetTime_, int64_t firstDrawTime_,
453*35238bceSAndroid Build Coastguard Worker                     int64_t secondInputSetTime_, int64_t secondDrawTime_)
454*35238bceSAndroid Build Coastguard Worker             : sourceSetTime(sourceSetTime_)
455*35238bceSAndroid Build Coastguard Worker             , vertexCompileTime(vertexCompileTime_)
456*35238bceSAndroid Build Coastguard Worker             , fragmentCompileTime(fragmentCompileTime_)
457*35238bceSAndroid Build Coastguard Worker             , programLinkTime(programLinkTime_)
458*35238bceSAndroid Build Coastguard Worker             , firstInputSetTime(firstInputSetTime_)
459*35238bceSAndroid Build Coastguard Worker             , firstDrawTime(firstDrawTime_)
460*35238bceSAndroid Build Coastguard Worker             , secondInputSetTime(secondInputSetTime_)
461*35238bceSAndroid Build Coastguard Worker             , secondDrawTime(secondDrawTime_)
462*35238bceSAndroid Build Coastguard Worker         {
463*35238bceSAndroid Build Coastguard Worker         }
464*35238bceSAndroid Build Coastguard Worker     };
465*35238bceSAndroid Build Coastguard Worker 
466*35238bceSAndroid Build Coastguard Worker     struct ShadersAndProgram
467*35238bceSAndroid Build Coastguard Worker     {
468*35238bceSAndroid Build Coastguard Worker         uint32_t vertShader;
469*35238bceSAndroid Build Coastguard Worker         uint32_t fragShader;
470*35238bceSAndroid Build Coastguard Worker         uint32_t program;
471*35238bceSAndroid Build Coastguard Worker     };
472*35238bceSAndroid Build Coastguard Worker 
473*35238bceSAndroid Build Coastguard Worker     struct Logs
474*35238bceSAndroid Build Coastguard Worker     {
475*35238bceSAndroid Build Coastguard Worker         string vert;
476*35238bceSAndroid Build Coastguard Worker         string frag;
477*35238bceSAndroid Build Coastguard Worker         string link;
478*35238bceSAndroid Build Coastguard Worker     };
479*35238bceSAndroid Build Coastguard Worker 
480*35238bceSAndroid Build Coastguard Worker     struct BuildInfo
481*35238bceSAndroid Build Coastguard Worker     {
482*35238bceSAndroid Build Coastguard Worker         bool vertCompileSuccess;
483*35238bceSAndroid Build Coastguard Worker         bool fragCompileSuccess;
484*35238bceSAndroid Build Coastguard Worker         bool linkSuccess;
485*35238bceSAndroid Build Coastguard Worker 
486*35238bceSAndroid Build Coastguard Worker         Logs logs;
487*35238bceSAndroid Build Coastguard Worker     };
488*35238bceSAndroid Build Coastguard Worker 
489*35238bceSAndroid Build Coastguard Worker     ShadersAndProgram createShadersAndProgram(void) const;
490*35238bceSAndroid Build Coastguard Worker     void setShaderSources(uint32_t vertShader, uint32_t fragShader, const ProgramContext &) const;
491*35238bceSAndroid Build Coastguard Worker     bool compileShader(uint32_t shader) const;
492*35238bceSAndroid Build Coastguard Worker     bool linkAndUseProgram(uint32_t program) const;
493*35238bceSAndroid Build Coastguard Worker     void setShaderInputs(uint32_t program, const ProgramContext &) const; // Set attribute pointers and uniforms.
494*35238bceSAndroid Build Coastguard Worker     void draw(void) const;                                                // Clear, draw and finish.
495*35238bceSAndroid Build Coastguard Worker     void cleanup(const ShadersAndProgram &, const ProgramContext &, bool linkSuccess) const; // Do GL deinitializations.
496*35238bceSAndroid Build Coastguard Worker 
497*35238bceSAndroid Build Coastguard Worker     Logs getLogs(const ShadersAndProgram &) const;
498*35238bceSAndroid Build Coastguard Worker     void logProgramData(const BuildInfo &, const ProgramContext &) const;
499*35238bceSAndroid Build Coastguard Worker     bool goodEnoughMeasurements(const vector<Measurement> &measurements) const;
500*35238bceSAndroid Build Coastguard Worker 
501*35238bceSAndroid Build Coastguard Worker     int m_viewportWidth;
502*35238bceSAndroid Build Coastguard Worker     int m_viewportHeight;
503*35238bceSAndroid Build Coastguard Worker 
504*35238bceSAndroid Build Coastguard Worker     bool m_avoidCache; // If true, avoid caching between measurements as well (and not only between test cases).
505*35238bceSAndroid Build Coastguard Worker     bool
506*35238bceSAndroid Build Coastguard Worker         m_addWhitespaceAndComments; // If true, add random whitespace and comments to the source (good caching should ignore those).
507*35238bceSAndroid Build Coastguard Worker     uint32_t m_startHash; // A hash from case id and time, at the time of construction.
508*35238bceSAndroid Build Coastguard Worker 
509*35238bceSAndroid Build Coastguard Worker     int m_minimumMeasurementCount;
510*35238bceSAndroid Build Coastguard Worker     int m_maximumMeasurementCount;
511*35238bceSAndroid Build Coastguard Worker };
512*35238bceSAndroid Build Coastguard Worker 
513*35238bceSAndroid Build Coastguard Worker class ShaderCompilerLightCase : public ShaderCompilerCase
514*35238bceSAndroid Build Coastguard Worker {
515*35238bceSAndroid Build Coastguard Worker public:
516*35238bceSAndroid Build Coastguard Worker     ShaderCompilerLightCase(Context &context, const char *name, const char *description, int caseID, bool avoidCache,
517*35238bceSAndroid Build Coastguard Worker                             bool addWhitespaceAndComments, bool isVertexCase, int numLights, LightType lightType);
518*35238bceSAndroid Build Coastguard Worker     ~ShaderCompilerLightCase(void);
519*35238bceSAndroid Build Coastguard Worker 
520*35238bceSAndroid Build Coastguard Worker     void init(void);
521*35238bceSAndroid Build Coastguard Worker     void deinit(void);
522*35238bceSAndroid Build Coastguard Worker 
523*35238bceSAndroid Build Coastguard Worker protected:
524*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderData(int measurementNdx) const;
525*35238bceSAndroid Build Coastguard Worker 
526*35238bceSAndroid Build Coastguard Worker private:
527*35238bceSAndroid Build Coastguard Worker     int m_numLights;
528*35238bceSAndroid Build Coastguard Worker     bool m_isVertexCase;
529*35238bceSAndroid Build Coastguard Worker     LightType m_lightType;
530*35238bceSAndroid Build Coastguard Worker     glu::Texture2D *m_texture;
531*35238bceSAndroid Build Coastguard Worker };
532*35238bceSAndroid Build Coastguard Worker 
533*35238bceSAndroid Build Coastguard Worker class ShaderCompilerTextureCase : public ShaderCompilerCase
534*35238bceSAndroid Build Coastguard Worker {
535*35238bceSAndroid Build Coastguard Worker public:
536*35238bceSAndroid Build Coastguard Worker     ShaderCompilerTextureCase(Context &context, const char *name, const char *description, int caseID, bool avoidCache,
537*35238bceSAndroid Build Coastguard Worker                               bool addWhitespaceAndComments, int numLookups, ConditionalUsage conditionalUsage,
538*35238bceSAndroid Build Coastguard Worker                               ConditionalType conditionalType);
539*35238bceSAndroid Build Coastguard Worker     ~ShaderCompilerTextureCase(void);
540*35238bceSAndroid Build Coastguard Worker 
541*35238bceSAndroid Build Coastguard Worker     void init(void);
542*35238bceSAndroid Build Coastguard Worker     void deinit(void);
543*35238bceSAndroid Build Coastguard Worker 
544*35238bceSAndroid Build Coastguard Worker protected:
545*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderData(int measurementNdx) const;
546*35238bceSAndroid Build Coastguard Worker 
547*35238bceSAndroid Build Coastguard Worker private:
548*35238bceSAndroid Build Coastguard Worker     int m_numLookups;
549*35238bceSAndroid Build Coastguard Worker     vector<glu::Texture2D *> m_textures;
550*35238bceSAndroid Build Coastguard Worker     ConditionalUsage m_conditionalUsage;
551*35238bceSAndroid Build Coastguard Worker     ConditionalType m_conditionalType;
552*35238bceSAndroid Build Coastguard Worker };
553*35238bceSAndroid Build Coastguard Worker 
554*35238bceSAndroid Build Coastguard Worker class ShaderCompilerLoopCase : public ShaderCompilerCase
555*35238bceSAndroid Build Coastguard Worker {
556*35238bceSAndroid Build Coastguard Worker public:
557*35238bceSAndroid Build Coastguard Worker     ShaderCompilerLoopCase(Context &context, const char *name, const char *description, int caseID, bool avoidCache,
558*35238bceSAndroid Build Coastguard Worker                            bool addWhitespaceAndComments, bool isVertexCase, LoopType type, int numLoopIterations,
559*35238bceSAndroid Build Coastguard Worker                            int nestingDepth);
560*35238bceSAndroid Build Coastguard Worker     ~ShaderCompilerLoopCase(void);
561*35238bceSAndroid Build Coastguard Worker 
562*35238bceSAndroid Build Coastguard Worker protected:
563*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderData(int measurementNdx) const;
564*35238bceSAndroid Build Coastguard Worker 
565*35238bceSAndroid Build Coastguard Worker private:
566*35238bceSAndroid Build Coastguard Worker     int m_numLoopIterations;
567*35238bceSAndroid Build Coastguard Worker     int m_nestingDepth;
568*35238bceSAndroid Build Coastguard Worker     bool m_isVertexCase;
569*35238bceSAndroid Build Coastguard Worker     LoopType m_type;
570*35238bceSAndroid Build Coastguard Worker };
571*35238bceSAndroid Build Coastguard Worker 
572*35238bceSAndroid Build Coastguard Worker class ShaderCompilerOperCase : public ShaderCompilerCase
573*35238bceSAndroid Build Coastguard Worker {
574*35238bceSAndroid Build Coastguard Worker public:
575*35238bceSAndroid Build Coastguard Worker     ShaderCompilerOperCase(Context &context, const char *name, const char *description, int caseID, bool avoidCache,
576*35238bceSAndroid Build Coastguard Worker                            bool addWhitespaceAndComments, bool isVertexCase, const char *oper, int numOperations);
577*35238bceSAndroid Build Coastguard Worker     ~ShaderCompilerOperCase(void);
578*35238bceSAndroid Build Coastguard Worker 
579*35238bceSAndroid Build Coastguard Worker protected:
580*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderData(int measurementNdx) const;
581*35238bceSAndroid Build Coastguard Worker 
582*35238bceSAndroid Build Coastguard Worker private:
583*35238bceSAndroid Build Coastguard Worker     string m_oper;
584*35238bceSAndroid Build Coastguard Worker     int m_numOperations;
585*35238bceSAndroid Build Coastguard Worker     bool m_isVertexCase;
586*35238bceSAndroid Build Coastguard Worker };
587*35238bceSAndroid Build Coastguard Worker 
588*35238bceSAndroid Build Coastguard Worker class ShaderCompilerMandelbrotCase : public ShaderCompilerCase
589*35238bceSAndroid Build Coastguard Worker {
590*35238bceSAndroid Build Coastguard Worker public:
591*35238bceSAndroid Build Coastguard Worker     ShaderCompilerMandelbrotCase(Context &context, const char *name, const char *description, int caseID,
592*35238bceSAndroid Build Coastguard Worker                                  bool avoidCache, bool addWhitespaceAndComments, int numFractalIterations);
593*35238bceSAndroid Build Coastguard Worker     ~ShaderCompilerMandelbrotCase(void);
594*35238bceSAndroid Build Coastguard Worker 
595*35238bceSAndroid Build Coastguard Worker protected:
596*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderData(int measurementNdx) const;
597*35238bceSAndroid Build Coastguard Worker 
598*35238bceSAndroid Build Coastguard Worker private:
599*35238bceSAndroid Build Coastguard Worker     int m_numFractalIterations;
600*35238bceSAndroid Build Coastguard Worker };
601*35238bceSAndroid Build Coastguard Worker 
602*35238bceSAndroid Build Coastguard Worker class InvalidShaderCompilerCase : public TestCase
603*35238bceSAndroid Build Coastguard Worker {
604*35238bceSAndroid Build Coastguard Worker public:
605*35238bceSAndroid Build Coastguard Worker     // \note Similar to the ShaderValidity enum, but doesn't have a VALID type.
606*35238bceSAndroid Build Coastguard Worker     enum InvalidityType
607*35238bceSAndroid Build Coastguard Worker     {
608*35238bceSAndroid Build Coastguard Worker         INVALIDITY_INVALID_CHAR = 0,
609*35238bceSAndroid Build Coastguard Worker         INVALIDITY_SEMANTIC_ERROR,
610*35238bceSAndroid Build Coastguard Worker 
611*35238bceSAndroid Build Coastguard Worker         INVALIDITY_LAST
612*35238bceSAndroid Build Coastguard Worker     };
613*35238bceSAndroid Build Coastguard Worker 
614*35238bceSAndroid Build Coastguard Worker     InvalidShaderCompilerCase(Context &context, const char *name, const char *description, int caseID,
615*35238bceSAndroid Build Coastguard Worker                               InvalidityType invalidityType);
616*35238bceSAndroid Build Coastguard Worker     ~InvalidShaderCompilerCase(void);
617*35238bceSAndroid Build Coastguard Worker 
618*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
619*35238bceSAndroid Build Coastguard Worker 
620*35238bceSAndroid Build Coastguard Worker protected:
621*35238bceSAndroid Build Coastguard Worker     struct ProgramContext
622*35238bceSAndroid Build Coastguard Worker     {
623*35238bceSAndroid Build Coastguard Worker         string vertShaderSource;
624*35238bceSAndroid Build Coastguard Worker         string fragShaderSource;
625*35238bceSAndroid Build Coastguard Worker     };
626*35238bceSAndroid Build Coastguard Worker 
627*35238bceSAndroid Build Coastguard Worker     uint32_t getSpecializationID(int measurementNdx)
628*35238bceSAndroid Build Coastguard Worker         const; // Return an ID that depends on the case ID, current measurement index and time; used to specialize attribute names etc. (avoid shader caching).
629*35238bceSAndroid Build Coastguard Worker     virtual ProgramContext generateShaderSources(int measurementNdx)
630*35238bceSAndroid Build Coastguard Worker         const = 0; // Generate shader sources. Attribute etc. names depend on above name specialization.
631*35238bceSAndroid Build Coastguard Worker 
632*35238bceSAndroid Build Coastguard Worker     InvalidityType m_invalidityType;
633*35238bceSAndroid Build Coastguard Worker 
634*35238bceSAndroid Build Coastguard Worker private:
635*35238bceSAndroid Build Coastguard Worker     struct Measurement
636*35238bceSAndroid Build Coastguard Worker     {
637*35238bceSAndroid Build Coastguard Worker         // \note All times in microseconds. 32-bit integers would probably suffice (would need over an hour of test case runtime to overflow), but better safe than sorry.
638*35238bceSAndroid Build Coastguard Worker         int64_t sourceSetTime;
639*35238bceSAndroid Build Coastguard Worker         int64_t vertexCompileTime;
640*35238bceSAndroid Build Coastguard Worker         int64_t fragmentCompileTime;
641*35238bceSAndroid Build Coastguard Worker 
totalTimedeqp::gles3::Performance::InvalidShaderCompilerCase::Measurement642*35238bceSAndroid Build Coastguard Worker         int64_t totalTime(void) const
643*35238bceSAndroid Build Coastguard Worker         {
644*35238bceSAndroid Build Coastguard Worker             return sourceSetTime + vertexCompileTime + fragmentCompileTime;
645*35238bceSAndroid Build Coastguard Worker         }
646*35238bceSAndroid Build Coastguard Worker 
Measurementdeqp::gles3::Performance::InvalidShaderCompilerCase::Measurement647*35238bceSAndroid Build Coastguard Worker         Measurement(int64_t sourceSetTime_, int64_t vertexCompileTime_, int64_t fragmentCompileTime_)
648*35238bceSAndroid Build Coastguard Worker             : sourceSetTime(sourceSetTime_)
649*35238bceSAndroid Build Coastguard Worker             , vertexCompileTime(vertexCompileTime_)
650*35238bceSAndroid Build Coastguard Worker             , fragmentCompileTime(fragmentCompileTime_)
651*35238bceSAndroid Build Coastguard Worker         {
652*35238bceSAndroid Build Coastguard Worker         }
653*35238bceSAndroid Build Coastguard Worker     };
654*35238bceSAndroid Build Coastguard Worker 
655*35238bceSAndroid Build Coastguard Worker     struct Shaders
656*35238bceSAndroid Build Coastguard Worker     {
657*35238bceSAndroid Build Coastguard Worker         uint32_t vertShader;
658*35238bceSAndroid Build Coastguard Worker         uint32_t fragShader;
659*35238bceSAndroid Build Coastguard Worker     };
660*35238bceSAndroid Build Coastguard Worker 
661*35238bceSAndroid Build Coastguard Worker     struct Logs
662*35238bceSAndroid Build Coastguard Worker     {
663*35238bceSAndroid Build Coastguard Worker         string vert;
664*35238bceSAndroid Build Coastguard Worker         string frag;
665*35238bceSAndroid Build Coastguard Worker     };
666*35238bceSAndroid Build Coastguard Worker 
667*35238bceSAndroid Build Coastguard Worker     struct BuildInfo
668*35238bceSAndroid Build Coastguard Worker     {
669*35238bceSAndroid Build Coastguard Worker         bool vertCompileSuccess;
670*35238bceSAndroid Build Coastguard Worker         bool fragCompileSuccess;
671*35238bceSAndroid Build Coastguard Worker 
672*35238bceSAndroid Build Coastguard Worker         Logs logs;
673*35238bceSAndroid Build Coastguard Worker     };
674*35238bceSAndroid Build Coastguard Worker 
675*35238bceSAndroid Build Coastguard Worker     Shaders createShaders(void) const;
676*35238bceSAndroid Build Coastguard Worker     void setShaderSources(const Shaders &, const ProgramContext &) const;
677*35238bceSAndroid Build Coastguard Worker     bool compileShader(uint32_t shader) const;
678*35238bceSAndroid Build Coastguard Worker     void cleanup(const Shaders &) const;
679*35238bceSAndroid Build Coastguard Worker 
680*35238bceSAndroid Build Coastguard Worker     Logs getLogs(const Shaders &) const;
681*35238bceSAndroid Build Coastguard Worker     void logProgramData(const BuildInfo &, const ProgramContext &) const;
682*35238bceSAndroid Build Coastguard Worker     bool goodEnoughMeasurements(const vector<Measurement> &measurements) const;
683*35238bceSAndroid Build Coastguard Worker 
684*35238bceSAndroid Build Coastguard Worker     uint32_t m_startHash; // A hash from case id and time, at the time of construction.
685*35238bceSAndroid Build Coastguard Worker 
686*35238bceSAndroid Build Coastguard Worker     int m_minimumMeasurementCount;
687*35238bceSAndroid Build Coastguard Worker     int m_maximumMeasurementCount;
688*35238bceSAndroid Build Coastguard Worker };
689*35238bceSAndroid Build Coastguard Worker 
690*35238bceSAndroid Build Coastguard Worker class InvalidShaderCompilerLightCase : public InvalidShaderCompilerCase
691*35238bceSAndroid Build Coastguard Worker {
692*35238bceSAndroid Build Coastguard Worker public:
693*35238bceSAndroid Build Coastguard Worker     InvalidShaderCompilerLightCase(Context &context, const char *name, const char *description, int caseID,
694*35238bceSAndroid Build Coastguard Worker                                    InvalidityType invalidityType, bool isVertexCase, int numLights,
695*35238bceSAndroid Build Coastguard Worker                                    LightType lightType);
696*35238bceSAndroid Build Coastguard Worker     ~InvalidShaderCompilerLightCase(void);
697*35238bceSAndroid Build Coastguard Worker 
698*35238bceSAndroid Build Coastguard Worker protected:
699*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderSources(int measurementNdx) const;
700*35238bceSAndroid Build Coastguard Worker 
701*35238bceSAndroid Build Coastguard Worker private:
702*35238bceSAndroid Build Coastguard Worker     bool m_isVertexCase;
703*35238bceSAndroid Build Coastguard Worker     int m_numLights;
704*35238bceSAndroid Build Coastguard Worker     LightType m_lightType;
705*35238bceSAndroid Build Coastguard Worker };
706*35238bceSAndroid Build Coastguard Worker 
707*35238bceSAndroid Build Coastguard Worker class InvalidShaderCompilerTextureCase : public InvalidShaderCompilerCase
708*35238bceSAndroid Build Coastguard Worker {
709*35238bceSAndroid Build Coastguard Worker public:
710*35238bceSAndroid Build Coastguard Worker     InvalidShaderCompilerTextureCase(Context &context, const char *name, const char *description, int caseID,
711*35238bceSAndroid Build Coastguard Worker                                      InvalidityType invalidityType, int numLookups, ConditionalUsage conditionalUsage,
712*35238bceSAndroid Build Coastguard Worker                                      ConditionalType conditionalType);
713*35238bceSAndroid Build Coastguard Worker     ~InvalidShaderCompilerTextureCase(void);
714*35238bceSAndroid Build Coastguard Worker 
715*35238bceSAndroid Build Coastguard Worker protected:
716*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderSources(int measurementNdx) const;
717*35238bceSAndroid Build Coastguard Worker 
718*35238bceSAndroid Build Coastguard Worker private:
719*35238bceSAndroid Build Coastguard Worker     int m_numLookups;
720*35238bceSAndroid Build Coastguard Worker     ConditionalUsage m_conditionalUsage;
721*35238bceSAndroid Build Coastguard Worker     ConditionalType m_conditionalType;
722*35238bceSAndroid Build Coastguard Worker };
723*35238bceSAndroid Build Coastguard Worker 
724*35238bceSAndroid Build Coastguard Worker class InvalidShaderCompilerLoopCase : public InvalidShaderCompilerCase
725*35238bceSAndroid Build Coastguard Worker {
726*35238bceSAndroid Build Coastguard Worker public:
727*35238bceSAndroid Build Coastguard Worker     InvalidShaderCompilerLoopCase(Context &context, const char *name, const char *description, int caseID,
728*35238bceSAndroid Build Coastguard Worker                                   InvalidityType invalidityType, bool, LoopType type, int numLoopIterations,
729*35238bceSAndroid Build Coastguard Worker                                   int nestingDepth);
730*35238bceSAndroid Build Coastguard Worker     ~InvalidShaderCompilerLoopCase(void);
731*35238bceSAndroid Build Coastguard Worker 
732*35238bceSAndroid Build Coastguard Worker protected:
733*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderSources(int measurementNdx) const;
734*35238bceSAndroid Build Coastguard Worker 
735*35238bceSAndroid Build Coastguard Worker private:
736*35238bceSAndroid Build Coastguard Worker     bool m_isVertexCase;
737*35238bceSAndroid Build Coastguard Worker     int m_numLoopIterations;
738*35238bceSAndroid Build Coastguard Worker     int m_nestingDepth;
739*35238bceSAndroid Build Coastguard Worker     LoopType m_type;
740*35238bceSAndroid Build Coastguard Worker };
741*35238bceSAndroid Build Coastguard Worker 
742*35238bceSAndroid Build Coastguard Worker class InvalidShaderCompilerOperCase : public InvalidShaderCompilerCase
743*35238bceSAndroid Build Coastguard Worker {
744*35238bceSAndroid Build Coastguard Worker public:
745*35238bceSAndroid Build Coastguard Worker     InvalidShaderCompilerOperCase(Context &context, const char *name, const char *description, int caseID,
746*35238bceSAndroid Build Coastguard Worker                                   InvalidityType invalidityType, bool isVertexCase, const char *oper,
747*35238bceSAndroid Build Coastguard Worker                                   int numOperations);
748*35238bceSAndroid Build Coastguard Worker     ~InvalidShaderCompilerOperCase(void);
749*35238bceSAndroid Build Coastguard Worker 
750*35238bceSAndroid Build Coastguard Worker protected:
751*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderSources(int measurementNdx) const;
752*35238bceSAndroid Build Coastguard Worker 
753*35238bceSAndroid Build Coastguard Worker private:
754*35238bceSAndroid Build Coastguard Worker     bool m_isVertexCase;
755*35238bceSAndroid Build Coastguard Worker     string m_oper;
756*35238bceSAndroid Build Coastguard Worker     int m_numOperations;
757*35238bceSAndroid Build Coastguard Worker };
758*35238bceSAndroid Build Coastguard Worker 
759*35238bceSAndroid Build Coastguard Worker class InvalidShaderCompilerMandelbrotCase : public InvalidShaderCompilerCase
760*35238bceSAndroid Build Coastguard Worker {
761*35238bceSAndroid Build Coastguard Worker public:
762*35238bceSAndroid Build Coastguard Worker     InvalidShaderCompilerMandelbrotCase(Context &context, const char *name, const char *description, int caseID,
763*35238bceSAndroid Build Coastguard Worker                                         InvalidityType invalidityType, int numFractalIterations);
764*35238bceSAndroid Build Coastguard Worker     ~InvalidShaderCompilerMandelbrotCase(void);
765*35238bceSAndroid Build Coastguard Worker 
766*35238bceSAndroid Build Coastguard Worker protected:
767*35238bceSAndroid Build Coastguard Worker     ProgramContext generateShaderSources(int measurementNdx) const;
768*35238bceSAndroid Build Coastguard Worker 
769*35238bceSAndroid Build Coastguard Worker private:
770*35238bceSAndroid Build Coastguard Worker     int m_numFractalIterations;
771*35238bceSAndroid Build Coastguard Worker };
772*35238bceSAndroid Build Coastguard Worker 
getNameSpecialization(uint32_t id)773*35238bceSAndroid Build Coastguard Worker static string getNameSpecialization(uint32_t id)
774*35238bceSAndroid Build Coastguard Worker {
775*35238bceSAndroid Build Coastguard Worker     return "_" + toStringWithPadding(id, 10);
776*35238bceSAndroid Build Coastguard Worker }
777*35238bceSAndroid Build Coastguard Worker 
778*35238bceSAndroid Build Coastguard Worker // Substitute StringTemplate parameters for attribute/uniform/varying name and constant expression specialization as well as possible shader compilation error causes.
specializeShaderSource(const string & shaderSourceTemplate,uint32_t cacheAvoidanceID,ShaderValidity validity)779*35238bceSAndroid Build Coastguard Worker static string specializeShaderSource(const string &shaderSourceTemplate, uint32_t cacheAvoidanceID,
780*35238bceSAndroid Build Coastguard Worker                                      ShaderValidity validity)
781*35238bceSAndroid Build Coastguard Worker {
782*35238bceSAndroid Build Coastguard Worker     std::map<string, string> params;
783*35238bceSAndroid Build Coastguard Worker     params["NAME_SPEC"] = getNameSpecialization(cacheAvoidanceID);
784*35238bceSAndroid Build Coastguard Worker     params["FLOAT01"]   = de::floatToString((float)cacheAvoidanceID / (float)(std::numeric_limits<uint32_t>::max()), 6);
785*35238bceSAndroid Build Coastguard Worker     params["SEMANTIC_ERROR"] = validity != SHADER_VALIDITY_SEMANTIC_ERROR ? "" : "\tfloat invalid = sin(1.0, 2.0);\n";
786*35238bceSAndroid Build Coastguard Worker     params["INVALID_CHAR"] =
787*35238bceSAndroid Build Coastguard Worker         validity != SHADER_VALIDITY_INVALID_CHAR ?
788*35238bceSAndroid Build Coastguard Worker             "" :
789*35238bceSAndroid Build Coastguard Worker             "@\n"; // \note Some implementations crash when the invalid character is the last character in the source, so use newline.
790*35238bceSAndroid Build Coastguard Worker 
791*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(shaderSourceTemplate).specialize(params);
792*35238bceSAndroid Build Coastguard Worker }
793*35238bceSAndroid Build Coastguard Worker 
794*35238bceSAndroid Build Coastguard Worker // Function for generating the vertex shader of a (directional or point) light case.
lightVertexTemplate(int numLights,bool isVertexCase,LightType lightType)795*35238bceSAndroid Build Coastguard Worker static string lightVertexTemplate(int numLights, bool isVertexCase, LightType lightType)
796*35238bceSAndroid Build Coastguard Worker {
797*35238bceSAndroid Build Coastguard Worker     string resultTemplate;
798*35238bceSAndroid Build Coastguard Worker 
799*35238bceSAndroid Build Coastguard Worker     resultTemplate += "#version 300 es\n"
800*35238bceSAndroid Build Coastguard Worker                       "in highp vec4 a_position${NAME_SPEC};\n"
801*35238bceSAndroid Build Coastguard Worker                       "in mediump vec3 a_normal${NAME_SPEC};\n"
802*35238bceSAndroid Build Coastguard Worker                       "in mediump vec4 a_texCoord0${NAME_SPEC};\n"
803*35238bceSAndroid Build Coastguard Worker                       "uniform mediump vec3 u_material_ambientColor${NAME_SPEC};\n"
804*35238bceSAndroid Build Coastguard Worker                       "uniform mediump vec4 u_material_diffuseColor${NAME_SPEC};\n"
805*35238bceSAndroid Build Coastguard Worker                       "uniform mediump vec3 u_material_emissiveColor${NAME_SPEC};\n"
806*35238bceSAndroid Build Coastguard Worker                       "uniform mediump vec3 u_material_specularColor${NAME_SPEC};\n"
807*35238bceSAndroid Build Coastguard Worker                       "uniform mediump float u_material_shininess${NAME_SPEC};\n";
808*35238bceSAndroid Build Coastguard Worker 
809*35238bceSAndroid Build Coastguard Worker     for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
810*35238bceSAndroid Build Coastguard Worker     {
811*35238bceSAndroid Build Coastguard Worker         string ndxStr = de::toString(lightNdx);
812*35238bceSAndroid Build Coastguard Worker 
813*35238bceSAndroid Build Coastguard Worker         resultTemplate += "uniform mediump vec3 u_light" + ndxStr +
814*35238bceSAndroid Build Coastguard Worker                           "_color${NAME_SPEC};\n"
815*35238bceSAndroid Build Coastguard Worker                           "uniform mediump vec3 u_light" +
816*35238bceSAndroid Build Coastguard Worker                           ndxStr + "_direction${NAME_SPEC};\n";
817*35238bceSAndroid Build Coastguard Worker 
818*35238bceSAndroid Build Coastguard Worker         if (lightType == LIGHT_POINT)
819*35238bceSAndroid Build Coastguard Worker             resultTemplate += "uniform mediump vec4 u_light" + ndxStr +
820*35238bceSAndroid Build Coastguard Worker                               "_position${NAME_SPEC};\n"
821*35238bceSAndroid Build Coastguard Worker                               "uniform mediump float u_light" +
822*35238bceSAndroid Build Coastguard Worker                               ndxStr +
823*35238bceSAndroid Build Coastguard Worker                               "_constantAttenuation${NAME_SPEC};\n"
824*35238bceSAndroid Build Coastguard Worker                               "uniform mediump float u_light" +
825*35238bceSAndroid Build Coastguard Worker                               ndxStr +
826*35238bceSAndroid Build Coastguard Worker                               "_linearAttenuation${NAME_SPEC};\n"
827*35238bceSAndroid Build Coastguard Worker                               "uniform mediump float u_light" +
828*35238bceSAndroid Build Coastguard Worker                               ndxStr + "_quadraticAttenuation${NAME_SPEC};\n";
829*35238bceSAndroid Build Coastguard Worker     }
830*35238bceSAndroid Build Coastguard Worker 
831*35238bceSAndroid Build Coastguard Worker     resultTemplate += "uniform highp mat4 u_mvpMatrix${NAME_SPEC};\n"
832*35238bceSAndroid Build Coastguard Worker                       "uniform highp mat4 u_modelViewMatrix${NAME_SPEC};\n"
833*35238bceSAndroid Build Coastguard Worker                       "uniform mediump mat3 u_normalMatrix${NAME_SPEC};\n"
834*35238bceSAndroid Build Coastguard Worker                       "uniform mediump mat4 u_texCoordMatrix0${NAME_SPEC};\n"
835*35238bceSAndroid Build Coastguard Worker                       "out mediump vec4 v_color${NAME_SPEC};\n"
836*35238bceSAndroid Build Coastguard Worker                       "out mediump vec2 v_texCoord0${NAME_SPEC};\n";
837*35238bceSAndroid Build Coastguard Worker 
838*35238bceSAndroid Build Coastguard Worker     if (!isVertexCase)
839*35238bceSAndroid Build Coastguard Worker     {
840*35238bceSAndroid Build Coastguard Worker         resultTemplate += "out mediump vec3 v_eyeNormal${NAME_SPEC};\n";
841*35238bceSAndroid Build Coastguard Worker 
842*35238bceSAndroid Build Coastguard Worker         if (lightType == LIGHT_POINT)
843*35238bceSAndroid Build Coastguard Worker             resultTemplate += "out mediump vec3 v_directionToLight${NAME_SPEC}[" + de::toString(numLights) +
844*35238bceSAndroid Build Coastguard Worker                               "];\n"
845*35238bceSAndroid Build Coastguard Worker                               "out mediump float v_distanceToLight${NAME_SPEC}[" +
846*35238bceSAndroid Build Coastguard Worker                               de::toString(numLights) + "];\n";
847*35238bceSAndroid Build Coastguard Worker     }
848*35238bceSAndroid Build Coastguard Worker 
849*35238bceSAndroid Build Coastguard Worker     resultTemplate +=
850*35238bceSAndroid Build Coastguard Worker         "mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
851*35238bceSAndroid Build Coastguard Worker         "{\n"
852*35238bceSAndroid Build Coastguard Worker         "    return vec3(to.xyz * from.w - from.xyz * to.w);\n"
853*35238bceSAndroid Build Coastguard Worker         "}\n"
854*35238bceSAndroid Build Coastguard Worker         "\n"
855*35238bceSAndroid Build Coastguard Worker         "mediump vec3 computeLighting (\n"
856*35238bceSAndroid Build Coastguard Worker         "    mediump vec3 directionToLight,\n"
857*35238bceSAndroid Build Coastguard Worker         "    mediump vec3 halfVector,\n"
858*35238bceSAndroid Build Coastguard Worker         "    mediump vec3 normal,\n"
859*35238bceSAndroid Build Coastguard Worker         "    mediump vec3 lightColor,\n"
860*35238bceSAndroid Build Coastguard Worker         "    mediump vec3 diffuseColor,\n"
861*35238bceSAndroid Build Coastguard Worker         "    mediump vec3 specularColor,\n"
862*35238bceSAndroid Build Coastguard Worker         "    mediump float shininess)\n"
863*35238bceSAndroid Build Coastguard Worker         "{\n"
864*35238bceSAndroid Build Coastguard Worker         "    mediump float normalDotDirection  = max(dot(normal, directionToLight), 0.0);\n"
865*35238bceSAndroid Build Coastguard Worker         "    mediump vec3  color               = normalDotDirection * diffuseColor * lightColor;\n"
866*35238bceSAndroid Build Coastguard Worker         "\n"
867*35238bceSAndroid Build Coastguard Worker         "    if (normalDotDirection != 0.0)\n"
868*35238bceSAndroid Build Coastguard Worker         "        color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
869*35238bceSAndroid Build Coastguard Worker         "\n"
870*35238bceSAndroid Build Coastguard Worker         "    return color;\n"
871*35238bceSAndroid Build Coastguard Worker         "}\n"
872*35238bceSAndroid Build Coastguard Worker         "\n";
873*35238bceSAndroid Build Coastguard Worker 
874*35238bceSAndroid Build Coastguard Worker     if (lightType == LIGHT_POINT)
875*35238bceSAndroid Build Coastguard Worker         resultTemplate +=
876*35238bceSAndroid Build Coastguard Worker             "mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump "
877*35238bceSAndroid Build Coastguard Worker             "float linearAtt, mediump float quadraticAtt)\n"
878*35238bceSAndroid Build Coastguard Worker             "{\n"
879*35238bceSAndroid Build Coastguard Worker             "    return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
880*35238bceSAndroid Build Coastguard Worker             "}\n"
881*35238bceSAndroid Build Coastguard Worker             "\n";
882*35238bceSAndroid Build Coastguard Worker 
883*35238bceSAndroid Build Coastguard Worker     resultTemplate +=
884*35238bceSAndroid Build Coastguard Worker         "void main (void)\n"
885*35238bceSAndroid Build Coastguard Worker         "{\n"
886*35238bceSAndroid Build Coastguard Worker         "    highp vec4 position = a_position${NAME_SPEC};\n"
887*35238bceSAndroid Build Coastguard Worker         "    highp vec3 normal = a_normal${NAME_SPEC};\n"
888*35238bceSAndroid Build Coastguard Worker         "    gl_Position = u_mvpMatrix${NAME_SPEC} * position * (0.95 + 0.05*${FLOAT01});\n"
889*35238bceSAndroid Build Coastguard Worker         "    v_texCoord0${NAME_SPEC} = (u_texCoordMatrix0${NAME_SPEC} * a_texCoord0${NAME_SPEC}).xy;\n"
890*35238bceSAndroid Build Coastguard Worker         "    mediump vec4 color = vec4(u_material_emissiveColor${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.a);\n"
891*35238bceSAndroid Build Coastguard Worker         "\n"
892*35238bceSAndroid Build Coastguard Worker         "    highp vec4 eyePosition = u_modelViewMatrix${NAME_SPEC} * position;\n"
893*35238bceSAndroid Build Coastguard Worker         "    mediump vec3 eyeNormal = normalize(u_normalMatrix${NAME_SPEC} * normal);\n";
894*35238bceSAndroid Build Coastguard Worker 
895*35238bceSAndroid Build Coastguard Worker     if (!isVertexCase)
896*35238bceSAndroid Build Coastguard Worker         resultTemplate += "\tv_eyeNormal${NAME_SPEC} = eyeNormal;\n";
897*35238bceSAndroid Build Coastguard Worker 
898*35238bceSAndroid Build Coastguard Worker     resultTemplate += "\n";
899*35238bceSAndroid Build Coastguard Worker 
900*35238bceSAndroid Build Coastguard Worker     for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
901*35238bceSAndroid Build Coastguard Worker     {
902*35238bceSAndroid Build Coastguard Worker         string ndxStr = de::toString(lightNdx);
903*35238bceSAndroid Build Coastguard Worker 
904*35238bceSAndroid Build Coastguard Worker         resultTemplate += "    /* Light " + ndxStr + " */\n";
905*35238bceSAndroid Build Coastguard Worker 
906*35238bceSAndroid Build Coastguard Worker         if (lightType == LIGHT_POINT)
907*35238bceSAndroid Build Coastguard Worker         {
908*35238bceSAndroid Build Coastguard Worker             resultTemplate +=
909*35238bceSAndroid Build Coastguard Worker                 "    mediump float distanceToLight" + ndxStr + " = distance(eyePosition, u_light" + ndxStr +
910*35238bceSAndroid Build Coastguard Worker                 "_position${NAME_SPEC});\n"
911*35238bceSAndroid Build Coastguard Worker                 "    mediump vec3 directionToLight" +
912*35238bceSAndroid Build Coastguard Worker                 ndxStr + " = normalize(direction(eyePosition, u_light" + ndxStr + "_position${NAME_SPEC}));\n";
913*35238bceSAndroid Build Coastguard Worker 
914*35238bceSAndroid Build Coastguard Worker             if (isVertexCase)
915*35238bceSAndroid Build Coastguard Worker                 resultTemplate += "    mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr +
916*35238bceSAndroid Build Coastguard Worker                                   " + vec3(0.0, 0.0, 1.0));\n"
917*35238bceSAndroid Build Coastguard Worker                                   "    color.rgb += computeLighting(directionToLight" +
918*35238bceSAndroid Build Coastguard Worker                                   ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr +
919*35238bceSAndroid Build Coastguard Worker                                   "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, "
920*35238bceSAndroid Build Coastguard Worker                                   "u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC}) * "
921*35238bceSAndroid Build Coastguard Worker                                   "computeDistanceAttenuation(distanceToLight" +
922*35238bceSAndroid Build Coastguard Worker                                   ndxStr + ", u_light" + ndxStr +
923*35238bceSAndroid Build Coastguard Worker                                   "_constantAttenuation${NAME_SPEC}, "
924*35238bceSAndroid Build Coastguard Worker                                   "u_light" +
925*35238bceSAndroid Build Coastguard Worker                                   ndxStr + "_linearAttenuation${NAME_SPEC}, u_light" + ndxStr +
926*35238bceSAndroid Build Coastguard Worker                                   "_quadraticAttenuation${NAME_SPEC});\n";
927*35238bceSAndroid Build Coastguard Worker             else
928*35238bceSAndroid Build Coastguard Worker                 resultTemplate += "    v_directionToLight${NAME_SPEC}[" + ndxStr + "] = directionToLight" + ndxStr +
929*35238bceSAndroid Build Coastguard Worker                                   ";\n"
930*35238bceSAndroid Build Coastguard Worker                                   "    v_distanceToLight${NAME_SPEC}[" +
931*35238bceSAndroid Build Coastguard Worker                                   ndxStr + "]  = distanceToLight" + ndxStr + ";\n";
932*35238bceSAndroid Build Coastguard Worker         }
933*35238bceSAndroid Build Coastguard Worker         else if (lightType == LIGHT_DIRECTIONAL)
934*35238bceSAndroid Build Coastguard Worker         {
935*35238bceSAndroid Build Coastguard Worker             if (isVertexCase)
936*35238bceSAndroid Build Coastguard Worker                 resultTemplate += "    mediump vec3 directionToLight" + ndxStr + " = -u_light" + ndxStr +
937*35238bceSAndroid Build Coastguard Worker                                   "_direction${NAME_SPEC};\n"
938*35238bceSAndroid Build Coastguard Worker                                   "    mediump vec3 halfVector" +
939*35238bceSAndroid Build Coastguard Worker                                   ndxStr + " = normalize(directionToLight" + ndxStr +
940*35238bceSAndroid Build Coastguard Worker                                   " + vec3(0.0, 0.0, 1.0));\n"
941*35238bceSAndroid Build Coastguard Worker                                   "    color.rgb += computeLighting(directionToLight" +
942*35238bceSAndroid Build Coastguard Worker                                   ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr +
943*35238bceSAndroid Build Coastguard Worker                                   "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, "
944*35238bceSAndroid Build Coastguard Worker                                   "u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC});\n";
945*35238bceSAndroid Build Coastguard Worker         }
946*35238bceSAndroid Build Coastguard Worker         else
947*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
948*35238bceSAndroid Build Coastguard Worker 
949*35238bceSAndroid Build Coastguard Worker         resultTemplate += "\n";
950*35238bceSAndroid Build Coastguard Worker     }
951*35238bceSAndroid Build Coastguard Worker 
952*35238bceSAndroid Build Coastguard Worker     resultTemplate += "    v_color${NAME_SPEC} = color;\n"
953*35238bceSAndroid Build Coastguard Worker                       "${SEMANTIC_ERROR}"
954*35238bceSAndroid Build Coastguard Worker                       "}\n"
955*35238bceSAndroid Build Coastguard Worker                       "${INVALID_CHAR}";
956*35238bceSAndroid Build Coastguard Worker 
957*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
958*35238bceSAndroid Build Coastguard Worker }
959*35238bceSAndroid Build Coastguard Worker 
960*35238bceSAndroid Build Coastguard Worker // Function for generating the fragment shader of a (directional or point) light case.
lightFragmentTemplate(int numLights,bool isVertexCase,LightType lightType)961*35238bceSAndroid Build Coastguard Worker static string lightFragmentTemplate(int numLights, bool isVertexCase, LightType lightType)
962*35238bceSAndroid Build Coastguard Worker {
963*35238bceSAndroid Build Coastguard Worker     string resultTemplate;
964*35238bceSAndroid Build Coastguard Worker 
965*35238bceSAndroid Build Coastguard Worker     resultTemplate += "#version 300 es\n"
966*35238bceSAndroid Build Coastguard Worker                       "layout(location = 0) out mediump vec4 o_color;\n";
967*35238bceSAndroid Build Coastguard Worker 
968*35238bceSAndroid Build Coastguard Worker     if (!isVertexCase)
969*35238bceSAndroid Build Coastguard Worker     {
970*35238bceSAndroid Build Coastguard Worker         resultTemplate += "uniform mediump vec3 u_material_ambientColor${NAME_SPEC};\n"
971*35238bceSAndroid Build Coastguard Worker                           "uniform mediump vec4 u_material_diffuseColor${NAME_SPEC};\n"
972*35238bceSAndroid Build Coastguard Worker                           "uniform mediump vec3 u_material_emissiveColor${NAME_SPEC};\n"
973*35238bceSAndroid Build Coastguard Worker                           "uniform mediump vec3 u_material_specularColor${NAME_SPEC};\n"
974*35238bceSAndroid Build Coastguard Worker                           "uniform mediump float u_material_shininess${NAME_SPEC};\n";
975*35238bceSAndroid Build Coastguard Worker 
976*35238bceSAndroid Build Coastguard Worker         for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
977*35238bceSAndroid Build Coastguard Worker         {
978*35238bceSAndroid Build Coastguard Worker             string ndxStr = de::toString(lightNdx);
979*35238bceSAndroid Build Coastguard Worker 
980*35238bceSAndroid Build Coastguard Worker             resultTemplate += "uniform mediump vec3 u_light" + ndxStr +
981*35238bceSAndroid Build Coastguard Worker                               "_color${NAME_SPEC};\n"
982*35238bceSAndroid Build Coastguard Worker                               "uniform mediump vec3 u_light" +
983*35238bceSAndroid Build Coastguard Worker                               ndxStr + "_direction${NAME_SPEC};\n";
984*35238bceSAndroid Build Coastguard Worker 
985*35238bceSAndroid Build Coastguard Worker             if (lightType == LIGHT_POINT)
986*35238bceSAndroid Build Coastguard Worker                 resultTemplate += "uniform mediump vec4 u_light" + ndxStr +
987*35238bceSAndroid Build Coastguard Worker                                   "_position${NAME_SPEC};\n"
988*35238bceSAndroid Build Coastguard Worker                                   "uniform mediump float u_light" +
989*35238bceSAndroid Build Coastguard Worker                                   ndxStr +
990*35238bceSAndroid Build Coastguard Worker                                   "_constantAttenuation${NAME_SPEC};\n"
991*35238bceSAndroid Build Coastguard Worker                                   "uniform mediump float u_light" +
992*35238bceSAndroid Build Coastguard Worker                                   ndxStr +
993*35238bceSAndroid Build Coastguard Worker                                   "_linearAttenuation${NAME_SPEC};\n"
994*35238bceSAndroid Build Coastguard Worker                                   "uniform mediump float u_light" +
995*35238bceSAndroid Build Coastguard Worker                                   ndxStr + "_quadraticAttenuation${NAME_SPEC};\n";
996*35238bceSAndroid Build Coastguard Worker         }
997*35238bceSAndroid Build Coastguard Worker     }
998*35238bceSAndroid Build Coastguard Worker 
999*35238bceSAndroid Build Coastguard Worker     resultTemplate += "uniform sampler2D u_sampler0${NAME_SPEC};\n"
1000*35238bceSAndroid Build Coastguard Worker                       "in mediump vec4 v_color${NAME_SPEC};\n"
1001*35238bceSAndroid Build Coastguard Worker                       "in mediump vec2 v_texCoord0${NAME_SPEC};\n";
1002*35238bceSAndroid Build Coastguard Worker 
1003*35238bceSAndroid Build Coastguard Worker     if (!isVertexCase)
1004*35238bceSAndroid Build Coastguard Worker     {
1005*35238bceSAndroid Build Coastguard Worker         resultTemplate += "in mediump vec3 v_eyeNormal${NAME_SPEC};\n";
1006*35238bceSAndroid Build Coastguard Worker 
1007*35238bceSAndroid Build Coastguard Worker         if (lightType == LIGHT_POINT)
1008*35238bceSAndroid Build Coastguard Worker             resultTemplate += "in mediump vec3 v_directionToLight${NAME_SPEC}[" + de::toString(numLights) +
1009*35238bceSAndroid Build Coastguard Worker                               "];\n"
1010*35238bceSAndroid Build Coastguard Worker                               "in mediump float v_distanceToLight${NAME_SPEC}[" +
1011*35238bceSAndroid Build Coastguard Worker                               de::toString(numLights) + "];\n";
1012*35238bceSAndroid Build Coastguard Worker 
1013*35238bceSAndroid Build Coastguard Worker         resultTemplate += "mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
1014*35238bceSAndroid Build Coastguard Worker                           "{\n"
1015*35238bceSAndroid Build Coastguard Worker                           "    return vec3(to.xyz * from.w - from.xyz * to.w);\n"
1016*35238bceSAndroid Build Coastguard Worker                           "}\n"
1017*35238bceSAndroid Build Coastguard Worker                           "\n";
1018*35238bceSAndroid Build Coastguard Worker 
1019*35238bceSAndroid Build Coastguard Worker         resultTemplate +=
1020*35238bceSAndroid Build Coastguard Worker             "mediump vec3 computeLighting (\n"
1021*35238bceSAndroid Build Coastguard Worker             "    mediump vec3 directionToLight,\n"
1022*35238bceSAndroid Build Coastguard Worker             "    mediump vec3 halfVector,\n"
1023*35238bceSAndroid Build Coastguard Worker             "    mediump vec3 normal,\n"
1024*35238bceSAndroid Build Coastguard Worker             "    mediump vec3 lightColor,\n"
1025*35238bceSAndroid Build Coastguard Worker             "    mediump vec3 diffuseColor,\n"
1026*35238bceSAndroid Build Coastguard Worker             "    mediump vec3 specularColor,\n"
1027*35238bceSAndroid Build Coastguard Worker             "    mediump float shininess)\n"
1028*35238bceSAndroid Build Coastguard Worker             "{\n"
1029*35238bceSAndroid Build Coastguard Worker             "    mediump float normalDotDirection  = max(dot(normal, directionToLight), 0.0);\n"
1030*35238bceSAndroid Build Coastguard Worker             "    mediump vec3  color               = normalDotDirection * diffuseColor * lightColor;\n"
1031*35238bceSAndroid Build Coastguard Worker             "\n"
1032*35238bceSAndroid Build Coastguard Worker             "    if (normalDotDirection != 0.0)\n"
1033*35238bceSAndroid Build Coastguard Worker             "        color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
1034*35238bceSAndroid Build Coastguard Worker             "\n"
1035*35238bceSAndroid Build Coastguard Worker             "    return color;\n"
1036*35238bceSAndroid Build Coastguard Worker             "}\n"
1037*35238bceSAndroid Build Coastguard Worker             "\n";
1038*35238bceSAndroid Build Coastguard Worker 
1039*35238bceSAndroid Build Coastguard Worker         if (lightType == LIGHT_POINT)
1040*35238bceSAndroid Build Coastguard Worker             resultTemplate +=
1041*35238bceSAndroid Build Coastguard Worker                 "mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump "
1042*35238bceSAndroid Build Coastguard Worker                 "float linearAtt, mediump float quadraticAtt)\n"
1043*35238bceSAndroid Build Coastguard Worker                 "{\n"
1044*35238bceSAndroid Build Coastguard Worker                 "    return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
1045*35238bceSAndroid Build Coastguard Worker                 "}\n"
1046*35238bceSAndroid Build Coastguard Worker                 "\n";
1047*35238bceSAndroid Build Coastguard Worker     }
1048*35238bceSAndroid Build Coastguard Worker 
1049*35238bceSAndroid Build Coastguard Worker     resultTemplate += "void main (void)\n"
1050*35238bceSAndroid Build Coastguard Worker                       "{\n"
1051*35238bceSAndroid Build Coastguard Worker                       "    mediump vec2 texCoord0 = v_texCoord0${NAME_SPEC}.xy;\n"
1052*35238bceSAndroid Build Coastguard Worker                       "    mediump vec4 color = v_color${NAME_SPEC};\n";
1053*35238bceSAndroid Build Coastguard Worker 
1054*35238bceSAndroid Build Coastguard Worker     if (!isVertexCase)
1055*35238bceSAndroid Build Coastguard Worker     {
1056*35238bceSAndroid Build Coastguard Worker         resultTemplate += "    mediump vec3 eyeNormal = normalize(v_eyeNormal${NAME_SPEC});\n"
1057*35238bceSAndroid Build Coastguard Worker                           "\n";
1058*35238bceSAndroid Build Coastguard Worker 
1059*35238bceSAndroid Build Coastguard Worker         for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
1060*35238bceSAndroid Build Coastguard Worker         {
1061*35238bceSAndroid Build Coastguard Worker             string ndxStr = de::toString(lightNdx);
1062*35238bceSAndroid Build Coastguard Worker 
1063*35238bceSAndroid Build Coastguard Worker             resultTemplate += "    /* Light " + ndxStr + " */\n";
1064*35238bceSAndroid Build Coastguard Worker 
1065*35238bceSAndroid Build Coastguard Worker             if (lightType == LIGHT_POINT)
1066*35238bceSAndroid Build Coastguard Worker                 resultTemplate += "    mediump vec3 directionToLight" + ndxStr +
1067*35238bceSAndroid Build Coastguard Worker                                   " = normalize(v_directionToLight${NAME_SPEC}[" + ndxStr +
1068*35238bceSAndroid Build Coastguard Worker                                   "]);\n"
1069*35238bceSAndroid Build Coastguard Worker                                   "    mediump float distanceToLight" +
1070*35238bceSAndroid Build Coastguard Worker                                   ndxStr + " = v_distanceToLight${NAME_SPEC}[" + ndxStr +
1071*35238bceSAndroid Build Coastguard Worker                                   "];\n"
1072*35238bceSAndroid Build Coastguard Worker                                   "    mediump vec3 halfVector" +
1073*35238bceSAndroid Build Coastguard Worker                                   ndxStr + " = normalize(directionToLight" + ndxStr +
1074*35238bceSAndroid Build Coastguard Worker                                   " + vec3(0.0, 0.0, 1.0));\n"
1075*35238bceSAndroid Build Coastguard Worker                                   "    color.rgb += computeLighting(directionToLight" +
1076*35238bceSAndroid Build Coastguard Worker                                   ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr +
1077*35238bceSAndroid Build Coastguard Worker                                   "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, "
1078*35238bceSAndroid Build Coastguard Worker                                   "u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC}) * "
1079*35238bceSAndroid Build Coastguard Worker                                   "computeDistanceAttenuation(distanceToLight" +
1080*35238bceSAndroid Build Coastguard Worker                                   ndxStr + ", u_light" + ndxStr +
1081*35238bceSAndroid Build Coastguard Worker                                   "_constantAttenuation${NAME_SPEC}, "
1082*35238bceSAndroid Build Coastguard Worker                                   "u_light" +
1083*35238bceSAndroid Build Coastguard Worker                                   ndxStr + "_linearAttenuation${NAME_SPEC}, u_light" + ndxStr +
1084*35238bceSAndroid Build Coastguard Worker                                   "_quadraticAttenuation${NAME_SPEC});\n"
1085*35238bceSAndroid Build Coastguard Worker                                   "\n";
1086*35238bceSAndroid Build Coastguard Worker             else if (lightType == LIGHT_DIRECTIONAL)
1087*35238bceSAndroid Build Coastguard Worker                 resultTemplate += "    mediump vec3 directionToLight" + ndxStr + " = -u_light" + ndxStr +
1088*35238bceSAndroid Build Coastguard Worker                                   "_direction${NAME_SPEC};\n"
1089*35238bceSAndroid Build Coastguard Worker                                   "    mediump vec3 halfVector" +
1090*35238bceSAndroid Build Coastguard Worker                                   ndxStr + " = normalize(directionToLight" + ndxStr +
1091*35238bceSAndroid Build Coastguard Worker                                   " + vec3(0.0, 0.0, 1.0));\n"
1092*35238bceSAndroid Build Coastguard Worker                                   "    color.rgb += computeLighting(directionToLight" +
1093*35238bceSAndroid Build Coastguard Worker                                   ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr +
1094*35238bceSAndroid Build Coastguard Worker                                   "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, "
1095*35238bceSAndroid Build Coastguard Worker                                   "u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC});\n"
1096*35238bceSAndroid Build Coastguard Worker                                   "\n";
1097*35238bceSAndroid Build Coastguard Worker             else
1098*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1099*35238bceSAndroid Build Coastguard Worker         }
1100*35238bceSAndroid Build Coastguard Worker     }
1101*35238bceSAndroid Build Coastguard Worker 
1102*35238bceSAndroid Build Coastguard Worker     resultTemplate += "    color *= texture(u_sampler0${NAME_SPEC}, texCoord0);\n"
1103*35238bceSAndroid Build Coastguard Worker                       "    o_color = color + ${FLOAT01};\n"
1104*35238bceSAndroid Build Coastguard Worker                       "${SEMANTIC_ERROR}"
1105*35238bceSAndroid Build Coastguard Worker                       "}\n"
1106*35238bceSAndroid Build Coastguard Worker                       "${INVALID_CHAR}";
1107*35238bceSAndroid Build Coastguard Worker 
1108*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1109*35238bceSAndroid Build Coastguard Worker }
1110*35238bceSAndroid Build Coastguard Worker 
1111*35238bceSAndroid Build Coastguard Worker // Function for generating the shader attributes of a (directional or point) light case.
lightShaderAttributes(const string & nameSpecialization)1112*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::AttribSpec> lightShaderAttributes(const string &nameSpecialization)
1113*35238bceSAndroid Build Coastguard Worker {
1114*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::AttribSpec> result;
1115*35238bceSAndroid Build Coastguard Worker 
1116*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::AttribSpec(
1117*35238bceSAndroid Build Coastguard Worker         "a_position" + nameSpecialization,
1118*35238bceSAndroid Build Coastguard Worker         combineVec4ToVec16(Vec4(-1.0f, -1.0f, 0.0f, 1.0f), Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec4(1.0f, -1.0f, 0.0f, 1.0f),
1119*35238bceSAndroid Build Coastguard Worker                            Vec4(1.0f, 1.0f, 0.0f, 1.0f))));
1120*35238bceSAndroid Build Coastguard Worker 
1121*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::AttribSpec(
1122*35238bceSAndroid Build Coastguard Worker         "a_normal" + nameSpecialization,
1123*35238bceSAndroid Build Coastguard Worker         combineVec4ToVec16(Vec4(0.0f, 0.0f, -1.0f, 0.0f), Vec4(0.0f, 0.0f, -1.0f, 0.0f), Vec4(0.0f, 0.0f, -1.0f, 0.0f),
1124*35238bceSAndroid Build Coastguard Worker                            Vec4(0.0f, 0.0f, -1.0f, 0.0f))));
1125*35238bceSAndroid Build Coastguard Worker 
1126*35238bceSAndroid Build Coastguard Worker     result.push_back(
1127*35238bceSAndroid Build Coastguard Worker         ShaderCompilerCase::AttribSpec("a_texCoord0" + nameSpecialization,
1128*35238bceSAndroid Build Coastguard Worker                                        combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(1.0f, 0.0f, 0.0f, 0.0f),
1129*35238bceSAndroid Build Coastguard Worker                                                           Vec4(0.0f, 1.0f, 0.0f, 0.0f), Vec4(1.0f, 1.0f, 0.0f, 0.0f))));
1130*35238bceSAndroid Build Coastguard Worker 
1131*35238bceSAndroid Build Coastguard Worker     return result;
1132*35238bceSAndroid Build Coastguard Worker }
1133*35238bceSAndroid Build Coastguard Worker 
1134*35238bceSAndroid Build Coastguard Worker // Function for generating the shader uniforms of a (directional or point) light case.
lightShaderUniforms(const string & nameSpecialization,int numLights,LightType lightType)1135*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::UniformSpec> lightShaderUniforms(const string &nameSpecialization, int numLights,
1136*35238bceSAndroid Build Coastguard Worker                                                                    LightType lightType)
1137*35238bceSAndroid Build Coastguard Worker {
1138*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::UniformSpec> result;
1139*35238bceSAndroid Build Coastguard Worker 
1140*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_material_ambientColor" + nameSpecialization,
1141*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_VEC3,
1142*35238bceSAndroid Build Coastguard Worker                                                      vecTo16(Vec3(0.5f, 0.7f, 0.9f))));
1143*35238bceSAndroid Build Coastguard Worker 
1144*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_material_diffuseColor" + nameSpecialization,
1145*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_VEC4,
1146*35238bceSAndroid Build Coastguard Worker                                                      vecTo16(Vec4(0.3f, 0.4f, 0.5f, 1.0f))));
1147*35238bceSAndroid Build Coastguard Worker 
1148*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_material_emissiveColor" + nameSpecialization,
1149*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_VEC3,
1150*35238bceSAndroid Build Coastguard Worker                                                      vecTo16(Vec3(0.7f, 0.2f, 0.2f))));
1151*35238bceSAndroid Build Coastguard Worker 
1152*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_material_specularColor" + nameSpecialization,
1153*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_VEC3,
1154*35238bceSAndroid Build Coastguard Worker                                                      vecTo16(Vec3(0.2f, 0.6f, 1.0f))));
1155*35238bceSAndroid Build Coastguard Worker 
1156*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_material_shininess" + nameSpecialization,
1157*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_FLOAT, 0.8f));
1158*35238bceSAndroid Build Coastguard Worker 
1159*35238bceSAndroid Build Coastguard Worker     for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
1160*35238bceSAndroid Build Coastguard Worker     {
1161*35238bceSAndroid Build Coastguard Worker         string ndxStr = de::toString(lightNdx);
1162*35238bceSAndroid Build Coastguard Worker 
1163*35238bceSAndroid Build Coastguard Worker         result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_color" + nameSpecialization,
1164*35238bceSAndroid Build Coastguard Worker                                                          ShaderCompilerCase::UniformSpec::TYPE_VEC3,
1165*35238bceSAndroid Build Coastguard Worker                                                          vecTo16(Vec3(0.8f, 0.6f, 0.3f))));
1166*35238bceSAndroid Build Coastguard Worker 
1167*35238bceSAndroid Build Coastguard Worker         result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_direction" + nameSpecialization,
1168*35238bceSAndroid Build Coastguard Worker                                                          ShaderCompilerCase::UniformSpec::TYPE_VEC3,
1169*35238bceSAndroid Build Coastguard Worker                                                          vecTo16(Vec3(0.2f, 0.3f, 0.4f))));
1170*35238bceSAndroid Build Coastguard Worker 
1171*35238bceSAndroid Build Coastguard Worker         if (lightType == LIGHT_POINT)
1172*35238bceSAndroid Build Coastguard Worker         {
1173*35238bceSAndroid Build Coastguard Worker             result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_position" + nameSpecialization,
1174*35238bceSAndroid Build Coastguard Worker                                                              ShaderCompilerCase::UniformSpec::TYPE_VEC4,
1175*35238bceSAndroid Build Coastguard Worker                                                              vecTo16(Vec4(1.0f, 0.6f, 0.3f, 0.2f))));
1176*35238bceSAndroid Build Coastguard Worker 
1177*35238bceSAndroid Build Coastguard Worker             result.push_back(
1178*35238bceSAndroid Build Coastguard Worker                 ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_constantAttenuation" + nameSpecialization,
1179*35238bceSAndroid Build Coastguard Worker                                                 ShaderCompilerCase::UniformSpec::TYPE_FLOAT, 0.6f));
1180*35238bceSAndroid Build Coastguard Worker 
1181*35238bceSAndroid Build Coastguard Worker             result.push_back(
1182*35238bceSAndroid Build Coastguard Worker                 ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_linearAttenuation" + nameSpecialization,
1183*35238bceSAndroid Build Coastguard Worker                                                 ShaderCompilerCase::UniformSpec::TYPE_FLOAT, 0.5f));
1184*35238bceSAndroid Build Coastguard Worker 
1185*35238bceSAndroid Build Coastguard Worker             result.push_back(
1186*35238bceSAndroid Build Coastguard Worker                 ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_quadraticAttenuation" + nameSpecialization,
1187*35238bceSAndroid Build Coastguard Worker                                                 ShaderCompilerCase::UniformSpec::TYPE_FLOAT, 0.4f));
1188*35238bceSAndroid Build Coastguard Worker         }
1189*35238bceSAndroid Build Coastguard Worker     }
1190*35238bceSAndroid Build Coastguard Worker 
1191*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_mvpMatrix" + nameSpecialization,
1192*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_MAT4,
1193*35238bceSAndroid Build Coastguard Worker                                                      arrTo16(Mat4(1.0f).getColumnMajorData())));
1194*35238bceSAndroid Build Coastguard Worker 
1195*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_modelViewMatrix" + nameSpecialization,
1196*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_MAT4,
1197*35238bceSAndroid Build Coastguard Worker                                                      arrTo16(Mat4(1.0f).getColumnMajorData())));
1198*35238bceSAndroid Build Coastguard Worker 
1199*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_normalMatrix" + nameSpecialization,
1200*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_MAT3,
1201*35238bceSAndroid Build Coastguard Worker                                                      arrTo16(Mat3(1.0f).getColumnMajorData())));
1202*35238bceSAndroid Build Coastguard Worker 
1203*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_texCoordMatrix0" + nameSpecialization,
1204*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_MAT4,
1205*35238bceSAndroid Build Coastguard Worker                                                      arrTo16(Mat4(1.0f).getColumnMajorData())));
1206*35238bceSAndroid Build Coastguard Worker 
1207*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_sampler0" + nameSpecialization,
1208*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_TEXTURE_UNIT, 0.0f));
1209*35238bceSAndroid Build Coastguard Worker 
1210*35238bceSAndroid Build Coastguard Worker     return result;
1211*35238bceSAndroid Build Coastguard Worker }
1212*35238bceSAndroid Build Coastguard Worker 
1213*35238bceSAndroid Build Coastguard Worker // Function for generating a vertex shader with a for loop.
loopVertexTemplate(LoopType type,bool isVertexCase,int numLoopIterations,int nestingDepth)1214*35238bceSAndroid Build Coastguard Worker static string loopVertexTemplate(LoopType type, bool isVertexCase, int numLoopIterations, int nestingDepth)
1215*35238bceSAndroid Build Coastguard Worker {
1216*35238bceSAndroid Build Coastguard Worker     string resultTemplate;
1217*35238bceSAndroid Build Coastguard Worker     string loopBound = type == LOOP_TYPE_STATIC  ? de::toString(numLoopIterations) :
1218*35238bceSAndroid Build Coastguard Worker                        type == LOOP_TYPE_UNIFORM ? "int(u_loopBound${NAME_SPEC})" :
1219*35238bceSAndroid Build Coastguard Worker                        type == LOOP_TYPE_DYNAMIC ? "int(a_loopBound${NAME_SPEC})" :
1220*35238bceSAndroid Build Coastguard Worker                                                    "";
1221*35238bceSAndroid Build Coastguard Worker 
1222*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!loopBound.empty());
1223*35238bceSAndroid Build Coastguard Worker 
1224*35238bceSAndroid Build Coastguard Worker     resultTemplate += "#version 300 es\n"
1225*35238bceSAndroid Build Coastguard Worker                       "in highp vec4 a_position${NAME_SPEC};\n";
1226*35238bceSAndroid Build Coastguard Worker 
1227*35238bceSAndroid Build Coastguard Worker     if (type == LOOP_TYPE_DYNAMIC)
1228*35238bceSAndroid Build Coastguard Worker         resultTemplate += "in mediump float a_loopBound${NAME_SPEC};\n";
1229*35238bceSAndroid Build Coastguard Worker 
1230*35238bceSAndroid Build Coastguard Worker     resultTemplate += "in mediump vec4 a_value${NAME_SPEC};\n"
1231*35238bceSAndroid Build Coastguard Worker                       "out mediump vec4 v_value${NAME_SPEC};\n";
1232*35238bceSAndroid Build Coastguard Worker 
1233*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
1234*35238bceSAndroid Build Coastguard Worker     {
1235*35238bceSAndroid Build Coastguard Worker         if (type == LOOP_TYPE_UNIFORM)
1236*35238bceSAndroid Build Coastguard Worker             resultTemplate += "uniform mediump float u_loopBound${NAME_SPEC};\n";
1237*35238bceSAndroid Build Coastguard Worker 
1238*35238bceSAndroid Build Coastguard Worker         resultTemplate += "\n"
1239*35238bceSAndroid Build Coastguard Worker                           "void main()\n"
1240*35238bceSAndroid Build Coastguard Worker                           "{\n"
1241*35238bceSAndroid Build Coastguard Worker                           "    gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
1242*35238bceSAndroid Build Coastguard Worker                           "    mediump vec4 value = a_value${NAME_SPEC};\n";
1243*35238bceSAndroid Build Coastguard Worker 
1244*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < nestingDepth; i++)
1245*35238bceSAndroid Build Coastguard Worker         {
1246*35238bceSAndroid Build Coastguard Worker             string iterName = "i" + de::toString(i);
1247*35238bceSAndroid Build Coastguard Worker             resultTemplate += string(i + 1, '\t') + "for (int " + iterName + " = 0; " + iterName + " < " + loopBound +
1248*35238bceSAndroid Build Coastguard Worker                               "; " + iterName + "++)\n";
1249*35238bceSAndroid Build Coastguard Worker         }
1250*35238bceSAndroid Build Coastguard Worker 
1251*35238bceSAndroid Build Coastguard Worker         resultTemplate += string(nestingDepth + 1, '\t') + "value *= a_value${NAME_SPEC};\n";
1252*35238bceSAndroid Build Coastguard Worker 
1253*35238bceSAndroid Build Coastguard Worker         resultTemplate += "    v_value${NAME_SPEC} = value;\n";
1254*35238bceSAndroid Build Coastguard Worker     }
1255*35238bceSAndroid Build Coastguard Worker     else
1256*35238bceSAndroid Build Coastguard Worker     {
1257*35238bceSAndroid Build Coastguard Worker         if (type == LOOP_TYPE_DYNAMIC)
1258*35238bceSAndroid Build Coastguard Worker             resultTemplate += "out mediump float v_loopBound${NAME_SPEC};\n";
1259*35238bceSAndroid Build Coastguard Worker 
1260*35238bceSAndroid Build Coastguard Worker         resultTemplate += "\n"
1261*35238bceSAndroid Build Coastguard Worker                           "void main()\n"
1262*35238bceSAndroid Build Coastguard Worker                           "{\n"
1263*35238bceSAndroid Build Coastguard Worker                           "    gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
1264*35238bceSAndroid Build Coastguard Worker                           "    v_value${NAME_SPEC} = a_value${NAME_SPEC};\n";
1265*35238bceSAndroid Build Coastguard Worker 
1266*35238bceSAndroid Build Coastguard Worker         if (type == LOOP_TYPE_DYNAMIC)
1267*35238bceSAndroid Build Coastguard Worker             resultTemplate += "    v_loopBound${NAME_SPEC} = a_loopBound${NAME_SPEC};\n";
1268*35238bceSAndroid Build Coastguard Worker     }
1269*35238bceSAndroid Build Coastguard Worker 
1270*35238bceSAndroid Build Coastguard Worker     resultTemplate += "${SEMANTIC_ERROR}"
1271*35238bceSAndroid Build Coastguard Worker                       "}\n"
1272*35238bceSAndroid Build Coastguard Worker                       "${INVALID_CHAR}";
1273*35238bceSAndroid Build Coastguard Worker 
1274*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1275*35238bceSAndroid Build Coastguard Worker }
1276*35238bceSAndroid Build Coastguard Worker 
1277*35238bceSAndroid Build Coastguard Worker // Function for generating a fragment shader with a for loop.
loopFragmentTemplate(LoopType type,bool isVertexCase,int numLoopIterations,int nestingDepth)1278*35238bceSAndroid Build Coastguard Worker static string loopFragmentTemplate(LoopType type, bool isVertexCase, int numLoopIterations, int nestingDepth)
1279*35238bceSAndroid Build Coastguard Worker {
1280*35238bceSAndroid Build Coastguard Worker     string resultTemplate;
1281*35238bceSAndroid Build Coastguard Worker     string loopBound = type == LOOP_TYPE_STATIC  ? de::toString(numLoopIterations) :
1282*35238bceSAndroid Build Coastguard Worker                        type == LOOP_TYPE_UNIFORM ? "int(u_loopBound${NAME_SPEC})" :
1283*35238bceSAndroid Build Coastguard Worker                        type == LOOP_TYPE_DYNAMIC ? "int(v_loopBound${NAME_SPEC})" :
1284*35238bceSAndroid Build Coastguard Worker                                                    "";
1285*35238bceSAndroid Build Coastguard Worker 
1286*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!loopBound.empty());
1287*35238bceSAndroid Build Coastguard Worker 
1288*35238bceSAndroid Build Coastguard Worker     resultTemplate += "#version 300 es\n"
1289*35238bceSAndroid Build Coastguard Worker                       "layout(location = 0) out mediump vec4 o_color;\n"
1290*35238bceSAndroid Build Coastguard Worker                       "in mediump vec4 v_value${NAME_SPEC};\n";
1291*35238bceSAndroid Build Coastguard Worker 
1292*35238bceSAndroid Build Coastguard Worker     if (!isVertexCase)
1293*35238bceSAndroid Build Coastguard Worker     {
1294*35238bceSAndroid Build Coastguard Worker         if (type == LOOP_TYPE_DYNAMIC)
1295*35238bceSAndroid Build Coastguard Worker             resultTemplate += "in mediump float v_loopBound${NAME_SPEC};\n";
1296*35238bceSAndroid Build Coastguard Worker         else if (type == LOOP_TYPE_UNIFORM)
1297*35238bceSAndroid Build Coastguard Worker             resultTemplate += "uniform mediump float u_loopBound${NAME_SPEC};\n";
1298*35238bceSAndroid Build Coastguard Worker 
1299*35238bceSAndroid Build Coastguard Worker         resultTemplate += "\n"
1300*35238bceSAndroid Build Coastguard Worker                           "void main()\n"
1301*35238bceSAndroid Build Coastguard Worker                           "{\n"
1302*35238bceSAndroid Build Coastguard Worker                           "    mediump vec4 value = v_value${NAME_SPEC};\n";
1303*35238bceSAndroid Build Coastguard Worker 
1304*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < nestingDepth; i++)
1305*35238bceSAndroid Build Coastguard Worker         {
1306*35238bceSAndroid Build Coastguard Worker             string iterName = "i" + de::toString(i);
1307*35238bceSAndroid Build Coastguard Worker             resultTemplate += string(i + 1, '\t') + "for (int " + iterName + " = 0; " + iterName + " < " + loopBound +
1308*35238bceSAndroid Build Coastguard Worker                               "; " + iterName + "++)\n";
1309*35238bceSAndroid Build Coastguard Worker         }
1310*35238bceSAndroid Build Coastguard Worker 
1311*35238bceSAndroid Build Coastguard Worker         resultTemplate += string(nestingDepth + 1, '\t') + "value *= v_value${NAME_SPEC};\n";
1312*35238bceSAndroid Build Coastguard Worker 
1313*35238bceSAndroid Build Coastguard Worker         resultTemplate += "    o_color = value + ${FLOAT01};\n";
1314*35238bceSAndroid Build Coastguard Worker     }
1315*35238bceSAndroid Build Coastguard Worker     else
1316*35238bceSAndroid Build Coastguard Worker         resultTemplate += "\n"
1317*35238bceSAndroid Build Coastguard Worker                           "void main()\n"
1318*35238bceSAndroid Build Coastguard Worker                           "{\n"
1319*35238bceSAndroid Build Coastguard Worker                           "    o_color = v_value${NAME_SPEC} + ${FLOAT01};\n";
1320*35238bceSAndroid Build Coastguard Worker 
1321*35238bceSAndroid Build Coastguard Worker     resultTemplate += "${SEMANTIC_ERROR}"
1322*35238bceSAndroid Build Coastguard Worker                       "}\n"
1323*35238bceSAndroid Build Coastguard Worker                       "${INVALID_CHAR}";
1324*35238bceSAndroid Build Coastguard Worker 
1325*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1326*35238bceSAndroid Build Coastguard Worker }
1327*35238bceSAndroid Build Coastguard Worker 
1328*35238bceSAndroid Build Coastguard Worker // Function for generating the shader attributes for a loop case.
loopShaderAttributes(const string & nameSpecialization,LoopType type,int numLoopIterations)1329*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::AttribSpec> loopShaderAttributes(const string &nameSpecialization, LoopType type,
1330*35238bceSAndroid Build Coastguard Worker                                                                    int numLoopIterations)
1331*35238bceSAndroid Build Coastguard Worker {
1332*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::AttribSpec> result;
1333*35238bceSAndroid Build Coastguard Worker 
1334*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::AttribSpec(
1335*35238bceSAndroid Build Coastguard Worker         "a_position" + nameSpecialization,
1336*35238bceSAndroid Build Coastguard Worker         combineVec4ToVec16(Vec4(-1.0f, -1.0f, 0.0f, 1.0f), Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec4(1.0f, -1.0f, 0.0f, 1.0f),
1337*35238bceSAndroid Build Coastguard Worker                            Vec4(1.0f, 1.0f, 0.0f, 1.0f))));
1338*35238bceSAndroid Build Coastguard Worker 
1339*35238bceSAndroid Build Coastguard Worker     result.push_back(
1340*35238bceSAndroid Build Coastguard Worker         ShaderCompilerCase::AttribSpec("a_value" + nameSpecialization,
1341*35238bceSAndroid Build Coastguard Worker                                        combineVec4ToVec16(Vec4(1.0f, 1.0f, 1.0f, 1.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f),
1342*35238bceSAndroid Build Coastguard Worker                                                           Vec4(1.0f, 1.0f, 1.0f, 1.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f))));
1343*35238bceSAndroid Build Coastguard Worker 
1344*35238bceSAndroid Build Coastguard Worker     if (type == LOOP_TYPE_DYNAMIC)
1345*35238bceSAndroid Build Coastguard Worker         result.push_back(ShaderCompilerCase::AttribSpec(
1346*35238bceSAndroid Build Coastguard Worker             "a_loopBound" + nameSpecialization, combineVec4ToVec16(Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
1347*35238bceSAndroid Build Coastguard Worker                                                                    Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
1348*35238bceSAndroid Build Coastguard Worker                                                                    Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
1349*35238bceSAndroid Build Coastguard Worker                                                                    Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f))));
1350*35238bceSAndroid Build Coastguard Worker 
1351*35238bceSAndroid Build Coastguard Worker     return result;
1352*35238bceSAndroid Build Coastguard Worker }
1353*35238bceSAndroid Build Coastguard Worker 
loopShaderUniforms(const string & nameSpecialization,LoopType type,int numLoopIterations)1354*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::UniformSpec> loopShaderUniforms(const string &nameSpecialization, LoopType type,
1355*35238bceSAndroid Build Coastguard Worker                                                                   int numLoopIterations)
1356*35238bceSAndroid Build Coastguard Worker {
1357*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::UniformSpec> result;
1358*35238bceSAndroid Build Coastguard Worker 
1359*35238bceSAndroid Build Coastguard Worker     if (type == LOOP_TYPE_UNIFORM)
1360*35238bceSAndroid Build Coastguard Worker         result.push_back(ShaderCompilerCase::UniformSpec(
1361*35238bceSAndroid Build Coastguard Worker             "u_loopBound" + nameSpecialization, ShaderCompilerCase::UniformSpec::TYPE_FLOAT, (float)numLoopIterations));
1362*35238bceSAndroid Build Coastguard Worker 
1363*35238bceSAndroid Build Coastguard Worker     return result;
1364*35238bceSAndroid Build Coastguard Worker }
1365*35238bceSAndroid Build Coastguard Worker 
1366*35238bceSAndroid Build Coastguard Worker // Function for generating the shader attributes for a case with only one attribute value in addition to the position attribute.
singleValueShaderAttributes(const string & nameSpecialization)1367*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::AttribSpec> singleValueShaderAttributes(const string &nameSpecialization)
1368*35238bceSAndroid Build Coastguard Worker {
1369*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::AttribSpec> result;
1370*35238bceSAndroid Build Coastguard Worker 
1371*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::AttribSpec(
1372*35238bceSAndroid Build Coastguard Worker         "a_position" + nameSpecialization,
1373*35238bceSAndroid Build Coastguard Worker         combineVec4ToVec16(Vec4(-1.0f, -1.0f, 0.0f, 1.0f), Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec4(1.0f, -1.0f, 0.0f, 1.0f),
1374*35238bceSAndroid Build Coastguard Worker                            Vec4(1.0f, 1.0f, 0.0f, 1.0f))));
1375*35238bceSAndroid Build Coastguard Worker 
1376*35238bceSAndroid Build Coastguard Worker     result.push_back(
1377*35238bceSAndroid Build Coastguard Worker         ShaderCompilerCase::AttribSpec("a_value" + nameSpecialization,
1378*35238bceSAndroid Build Coastguard Worker                                        combineVec4ToVec16(Vec4(1.0f, 1.0f, 1.0f, 1.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f),
1379*35238bceSAndroid Build Coastguard Worker                                                           Vec4(1.0f, 1.0f, 1.0f, 1.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f))));
1380*35238bceSAndroid Build Coastguard Worker 
1381*35238bceSAndroid Build Coastguard Worker     return result;
1382*35238bceSAndroid Build Coastguard Worker }
1383*35238bceSAndroid Build Coastguard Worker 
1384*35238bceSAndroid Build Coastguard Worker // Function for generating a vertex shader with a binary operation chain.
binaryOpVertexTemplate(int numOperations,const char * op)1385*35238bceSAndroid Build Coastguard Worker static string binaryOpVertexTemplate(int numOperations, const char *op)
1386*35238bceSAndroid Build Coastguard Worker {
1387*35238bceSAndroid Build Coastguard Worker     string resultTemplate;
1388*35238bceSAndroid Build Coastguard Worker 
1389*35238bceSAndroid Build Coastguard Worker     resultTemplate += "#version 300 es\n"
1390*35238bceSAndroid Build Coastguard Worker                       "in highp vec4 a_position${NAME_SPEC};\n"
1391*35238bceSAndroid Build Coastguard Worker                       "in mediump vec4 a_value${NAME_SPEC};\n"
1392*35238bceSAndroid Build Coastguard Worker                       "out mediump vec4 v_value${NAME_SPEC};\n"
1393*35238bceSAndroid Build Coastguard Worker                       "\n"
1394*35238bceSAndroid Build Coastguard Worker                       "void main()\n"
1395*35238bceSAndroid Build Coastguard Worker                       "{\n"
1396*35238bceSAndroid Build Coastguard Worker                       "    gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
1397*35238bceSAndroid Build Coastguard Worker                       "    mediump vec4 value = ";
1398*35238bceSAndroid Build Coastguard Worker 
1399*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numOperations; i++)
1400*35238bceSAndroid Build Coastguard Worker         resultTemplate += string(i > 0 ? op : "") + "a_value${NAME_SPEC}";
1401*35238bceSAndroid Build Coastguard Worker 
1402*35238bceSAndroid Build Coastguard Worker     resultTemplate += ";\n"
1403*35238bceSAndroid Build Coastguard Worker                       "    v_value${NAME_SPEC} = value;\n"
1404*35238bceSAndroid Build Coastguard Worker                       "${SEMANTIC_ERROR}"
1405*35238bceSAndroid Build Coastguard Worker                       "}\n"
1406*35238bceSAndroid Build Coastguard Worker                       "${INVALID_CHAR}";
1407*35238bceSAndroid Build Coastguard Worker 
1408*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1409*35238bceSAndroid Build Coastguard Worker }
1410*35238bceSAndroid Build Coastguard Worker 
1411*35238bceSAndroid Build Coastguard Worker // Function for generating a fragment shader with a binary operation chain.
binaryOpFragmentTemplate(int numOperations,const char * op)1412*35238bceSAndroid Build Coastguard Worker static string binaryOpFragmentTemplate(int numOperations, const char *op)
1413*35238bceSAndroid Build Coastguard Worker {
1414*35238bceSAndroid Build Coastguard Worker     string resultTemplate;
1415*35238bceSAndroid Build Coastguard Worker 
1416*35238bceSAndroid Build Coastguard Worker     resultTemplate += "#version 300 es\n"
1417*35238bceSAndroid Build Coastguard Worker                       "layout(location = 0) out mediump vec4 o_color;\n"
1418*35238bceSAndroid Build Coastguard Worker                       "in mediump vec4 v_value${NAME_SPEC};\n"
1419*35238bceSAndroid Build Coastguard Worker                       "\n"
1420*35238bceSAndroid Build Coastguard Worker                       "void main()\n"
1421*35238bceSAndroid Build Coastguard Worker                       "{\n"
1422*35238bceSAndroid Build Coastguard Worker                       "    mediump vec4 value = ";
1423*35238bceSAndroid Build Coastguard Worker 
1424*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numOperations; i++)
1425*35238bceSAndroid Build Coastguard Worker         resultTemplate += string(i > 0 ? op : "") + "v_value${NAME_SPEC}";
1426*35238bceSAndroid Build Coastguard Worker 
1427*35238bceSAndroid Build Coastguard Worker     resultTemplate += ";\n"
1428*35238bceSAndroid Build Coastguard Worker                       "    o_color = value + ${FLOAT01};\n"
1429*35238bceSAndroid Build Coastguard Worker                       "${SEMANTIC_ERROR}"
1430*35238bceSAndroid Build Coastguard Worker                       "}\n"
1431*35238bceSAndroid Build Coastguard Worker                       "${INVALID_CHAR}";
1432*35238bceSAndroid Build Coastguard Worker 
1433*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1434*35238bceSAndroid Build Coastguard Worker }
1435*35238bceSAndroid Build Coastguard Worker 
1436*35238bceSAndroid Build Coastguard Worker // Function for generating a vertex that takes one attribute in addition to position and just passes it to the fragment shader as a varying.
singleVaryingVertexTemplate(void)1437*35238bceSAndroid Build Coastguard Worker static string singleVaryingVertexTemplate(void)
1438*35238bceSAndroid Build Coastguard Worker {
1439*35238bceSAndroid Build Coastguard Worker     const char *resultTemplate = "#version 300 es\n"
1440*35238bceSAndroid Build Coastguard Worker                                  "in highp vec4 a_position${NAME_SPEC};\n"
1441*35238bceSAndroid Build Coastguard Worker                                  "in mediump vec4 a_value${NAME_SPEC};\n"
1442*35238bceSAndroid Build Coastguard Worker                                  "out mediump vec4 v_value${NAME_SPEC};\n"
1443*35238bceSAndroid Build Coastguard Worker                                  "\n"
1444*35238bceSAndroid Build Coastguard Worker                                  "void main()\n"
1445*35238bceSAndroid Build Coastguard Worker                                  "{\n"
1446*35238bceSAndroid Build Coastguard Worker                                  "    gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
1447*35238bceSAndroid Build Coastguard Worker                                  "    v_value${NAME_SPEC} = a_value${NAME_SPEC};\n"
1448*35238bceSAndroid Build Coastguard Worker                                  "${SEMANTIC_ERROR}"
1449*35238bceSAndroid Build Coastguard Worker                                  "}\n"
1450*35238bceSAndroid Build Coastguard Worker                                  "${INVALID_CHAR}";
1451*35238bceSAndroid Build Coastguard Worker 
1452*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1453*35238bceSAndroid Build Coastguard Worker }
1454*35238bceSAndroid Build Coastguard Worker 
1455*35238bceSAndroid Build Coastguard Worker // Function for generating a fragment shader that takes a single varying and uses it as the color.
singleVaryingFragmentTemplate(void)1456*35238bceSAndroid Build Coastguard Worker static string singleVaryingFragmentTemplate(void)
1457*35238bceSAndroid Build Coastguard Worker {
1458*35238bceSAndroid Build Coastguard Worker     const char *resultTemplate = "#version 300 es\n"
1459*35238bceSAndroid Build Coastguard Worker                                  "layout(location = 0) out mediump vec4 o_color;\n"
1460*35238bceSAndroid Build Coastguard Worker                                  "in mediump vec4 v_value${NAME_SPEC};\n"
1461*35238bceSAndroid Build Coastguard Worker                                  "\n"
1462*35238bceSAndroid Build Coastguard Worker                                  "void main()\n"
1463*35238bceSAndroid Build Coastguard Worker                                  "{\n"
1464*35238bceSAndroid Build Coastguard Worker                                  "    o_color = v_value${NAME_SPEC} + ${FLOAT01};\n"
1465*35238bceSAndroid Build Coastguard Worker                                  "${SEMANTIC_ERROR}"
1466*35238bceSAndroid Build Coastguard Worker                                  "}\n"
1467*35238bceSAndroid Build Coastguard Worker                                  "${INVALID_CHAR}";
1468*35238bceSAndroid Build Coastguard Worker 
1469*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1470*35238bceSAndroid Build Coastguard Worker }
1471*35238bceSAndroid Build Coastguard Worker 
1472*35238bceSAndroid Build Coastguard Worker // Function for generating the vertex shader of a texture lookup case.
textureLookupVertexTemplate(ConditionalUsage conditionalUsage,ConditionalType conditionalType)1473*35238bceSAndroid Build Coastguard Worker static string textureLookupVertexTemplate(ConditionalUsage conditionalUsage, ConditionalType conditionalType)
1474*35238bceSAndroid Build Coastguard Worker {
1475*35238bceSAndroid Build Coastguard Worker     string resultTemplate;
1476*35238bceSAndroid Build Coastguard Worker     bool conditionVaryingNeeded =
1477*35238bceSAndroid Build Coastguard Worker         conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC;
1478*35238bceSAndroid Build Coastguard Worker 
1479*35238bceSAndroid Build Coastguard Worker     resultTemplate += "#version 300 es\n"
1480*35238bceSAndroid Build Coastguard Worker                       "in highp vec4 a_position${NAME_SPEC};\n"
1481*35238bceSAndroid Build Coastguard Worker                       "in mediump vec2 a_coords${NAME_SPEC};\n"
1482*35238bceSAndroid Build Coastguard Worker                       "out mediump vec2 v_coords${NAME_SPEC};\n";
1483*35238bceSAndroid Build Coastguard Worker 
1484*35238bceSAndroid Build Coastguard Worker     if (conditionVaryingNeeded)
1485*35238bceSAndroid Build Coastguard Worker         resultTemplate += "in mediump float a_condition${NAME_SPEC};\n"
1486*35238bceSAndroid Build Coastguard Worker                           "out mediump float v_condition${NAME_SPEC};\n";
1487*35238bceSAndroid Build Coastguard Worker 
1488*35238bceSAndroid Build Coastguard Worker     resultTemplate += "\n"
1489*35238bceSAndroid Build Coastguard Worker                       "void main()\n"
1490*35238bceSAndroid Build Coastguard Worker                       "{\n"
1491*35238bceSAndroid Build Coastguard Worker                       "    gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
1492*35238bceSAndroid Build Coastguard Worker                       "    v_coords${NAME_SPEC} = a_coords${NAME_SPEC};\n";
1493*35238bceSAndroid Build Coastguard Worker 
1494*35238bceSAndroid Build Coastguard Worker     if (conditionVaryingNeeded)
1495*35238bceSAndroid Build Coastguard Worker         resultTemplate += "    v_condition${NAME_SPEC} = a_condition${NAME_SPEC};\n";
1496*35238bceSAndroid Build Coastguard Worker 
1497*35238bceSAndroid Build Coastguard Worker     resultTemplate += "${SEMANTIC_ERROR}"
1498*35238bceSAndroid Build Coastguard Worker                       "}\n"
1499*35238bceSAndroid Build Coastguard Worker                       "${INVALID_CHAR}";
1500*35238bceSAndroid Build Coastguard Worker 
1501*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1502*35238bceSAndroid Build Coastguard Worker }
1503*35238bceSAndroid Build Coastguard Worker 
1504*35238bceSAndroid Build Coastguard Worker // Function for generating the fragment shader of a texture lookup case.
textureLookupFragmentTemplate(int numLookups,ConditionalUsage conditionalUsage,ConditionalType conditionalType)1505*35238bceSAndroid Build Coastguard Worker static string textureLookupFragmentTemplate(int numLookups, ConditionalUsage conditionalUsage,
1506*35238bceSAndroid Build Coastguard Worker                                             ConditionalType conditionalType)
1507*35238bceSAndroid Build Coastguard Worker {
1508*35238bceSAndroid Build Coastguard Worker     string resultTemplate;
1509*35238bceSAndroid Build Coastguard Worker 
1510*35238bceSAndroid Build Coastguard Worker     resultTemplate += "#version 300 es\n"
1511*35238bceSAndroid Build Coastguard Worker                       "layout(location = 0) out mediump vec4 o_color;\n"
1512*35238bceSAndroid Build Coastguard Worker                       "in mediump vec2 v_coords${NAME_SPEC};\n";
1513*35238bceSAndroid Build Coastguard Worker 
1514*35238bceSAndroid Build Coastguard Worker     if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC)
1515*35238bceSAndroid Build Coastguard Worker         resultTemplate += "in mediump float v_condition${NAME_SPEC};\n";
1516*35238bceSAndroid Build Coastguard Worker 
1517*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numLookups; i++)
1518*35238bceSAndroid Build Coastguard Worker         resultTemplate += "uniform sampler2D u_sampler" + de::toString(i) + "${NAME_SPEC};\n";
1519*35238bceSAndroid Build Coastguard Worker 
1520*35238bceSAndroid Build Coastguard Worker     if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_UNIFORM)
1521*35238bceSAndroid Build Coastguard Worker         resultTemplate += "uniform mediump float u_condition${NAME_SPEC};\n";
1522*35238bceSAndroid Build Coastguard Worker 
1523*35238bceSAndroid Build Coastguard Worker     resultTemplate += "\n"
1524*35238bceSAndroid Build Coastguard Worker                       "void main()\n"
1525*35238bceSAndroid Build Coastguard Worker                       "{\n"
1526*35238bceSAndroid Build Coastguard Worker                       "    mediump vec4 color = vec4(0.0);\n";
1527*35238bceSAndroid Build Coastguard Worker 
1528*35238bceSAndroid Build Coastguard Worker     const char *conditionalTerm = conditionalType == CONDITIONAL_TYPE_STATIC  ? "1.0 > 0.0" :
1529*35238bceSAndroid Build Coastguard Worker                                   conditionalType == CONDITIONAL_TYPE_UNIFORM ? "u_condition${NAME_SPEC} > 0.0" :
1530*35238bceSAndroid Build Coastguard Worker                                   conditionalType == CONDITIONAL_TYPE_DYNAMIC ? "v_condition${NAME_SPEC} > 0.0" :
1531*35238bceSAndroid Build Coastguard Worker                                                                                 DE_NULL;
1532*35238bceSAndroid Build Coastguard Worker 
1533*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(conditionalTerm != DE_NULL);
1534*35238bceSAndroid Build Coastguard Worker 
1535*35238bceSAndroid Build Coastguard Worker     if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF)
1536*35238bceSAndroid Build Coastguard Worker         resultTemplate += string("") + "    if (" + conditionalTerm +
1537*35238bceSAndroid Build Coastguard Worker                           ")\n"
1538*35238bceSAndroid Build Coastguard Worker                           "    {\n";
1539*35238bceSAndroid Build Coastguard Worker 
1540*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numLookups; i++)
1541*35238bceSAndroid Build Coastguard Worker     {
1542*35238bceSAndroid Build Coastguard Worker         if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF)
1543*35238bceSAndroid Build Coastguard Worker         {
1544*35238bceSAndroid Build Coastguard Worker             if (i < (numLookups + 1) / 2)
1545*35238bceSAndroid Build Coastguard Worker                 resultTemplate += "\t";
1546*35238bceSAndroid Build Coastguard Worker         }
1547*35238bceSAndroid Build Coastguard Worker         else if (conditionalUsage == CONDITIONAL_USAGE_EVERY_OTHER)
1548*35238bceSAndroid Build Coastguard Worker         {
1549*35238bceSAndroid Build Coastguard Worker             if (i % 2 == 0)
1550*35238bceSAndroid Build Coastguard Worker                 resultTemplate += string("") + "    if (" + conditionalTerm +
1551*35238bceSAndroid Build Coastguard Worker                                   ")\n"
1552*35238bceSAndroid Build Coastguard Worker                                   "\t";
1553*35238bceSAndroid Build Coastguard Worker         }
1554*35238bceSAndroid Build Coastguard Worker 
1555*35238bceSAndroid Build Coastguard Worker         resultTemplate += "    color += texture(u_sampler" + de::toString(i) + "${NAME_SPEC}, v_coords${NAME_SPEC});\n";
1556*35238bceSAndroid Build Coastguard Worker 
1557*35238bceSAndroid Build Coastguard Worker         if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF && i == (numLookups - 1) / 2)
1558*35238bceSAndroid Build Coastguard Worker             resultTemplate += "\t}\n";
1559*35238bceSAndroid Build Coastguard Worker     }
1560*35238bceSAndroid Build Coastguard Worker 
1561*35238bceSAndroid Build Coastguard Worker     resultTemplate += "    o_color = color/" + de::toString(numLookups) + ".0 + ${FLOAT01};\n" +
1562*35238bceSAndroid Build Coastguard Worker                       "${SEMANTIC_ERROR}"
1563*35238bceSAndroid Build Coastguard Worker                       "}\n"
1564*35238bceSAndroid Build Coastguard Worker                       "${INVALID_CHAR}";
1565*35238bceSAndroid Build Coastguard Worker 
1566*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1567*35238bceSAndroid Build Coastguard Worker }
1568*35238bceSAndroid Build Coastguard Worker 
1569*35238bceSAndroid Build Coastguard Worker // Function for generating the shader attributes of a texture lookup case.
textureLookupShaderAttributes(const string & nameSpecialization,ConditionalUsage conditionalUsage,ConditionalType conditionalType)1570*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::AttribSpec> textureLookupShaderAttributes(const string &nameSpecialization,
1571*35238bceSAndroid Build Coastguard Worker                                                                             ConditionalUsage conditionalUsage,
1572*35238bceSAndroid Build Coastguard Worker                                                                             ConditionalType conditionalType)
1573*35238bceSAndroid Build Coastguard Worker {
1574*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::AttribSpec> result;
1575*35238bceSAndroid Build Coastguard Worker 
1576*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::AttribSpec(
1577*35238bceSAndroid Build Coastguard Worker         "a_position" + nameSpecialization,
1578*35238bceSAndroid Build Coastguard Worker         combineVec4ToVec16(Vec4(-1.0f, -1.0f, 0.0f, 1.0f), Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec4(1.0f, -1.0f, 0.0f, 1.0f),
1579*35238bceSAndroid Build Coastguard Worker                            Vec4(1.0f, 1.0f, 0.0f, 1.0f))));
1580*35238bceSAndroid Build Coastguard Worker 
1581*35238bceSAndroid Build Coastguard Worker     result.push_back(
1582*35238bceSAndroid Build Coastguard Worker         ShaderCompilerCase::AttribSpec("a_coords" + nameSpecialization,
1583*35238bceSAndroid Build Coastguard Worker                                        combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(0.0f, 1.0f, 0.0f, 0.0f),
1584*35238bceSAndroid Build Coastguard Worker                                                           Vec4(1.0f, 0.0f, 0.0f, 0.0f), Vec4(1.0f, 1.0f, 0.0f, 0.0f))));
1585*35238bceSAndroid Build Coastguard Worker 
1586*35238bceSAndroid Build Coastguard Worker     if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC)
1587*35238bceSAndroid Build Coastguard Worker         result.push_back(ShaderCompilerCase::AttribSpec(
1588*35238bceSAndroid Build Coastguard Worker             "a_condition" + nameSpecialization, combineVec4ToVec16(Vec4(1.0f), Vec4(1.0f), Vec4(1.0f), Vec4(1.0f))));
1589*35238bceSAndroid Build Coastguard Worker 
1590*35238bceSAndroid Build Coastguard Worker     return result;
1591*35238bceSAndroid Build Coastguard Worker }
1592*35238bceSAndroid Build Coastguard Worker 
1593*35238bceSAndroid Build Coastguard Worker // Function for generating the shader uniforms of a texture lookup case.
textureLookupShaderUniforms(const string & nameSpecialization,int numLookups,ConditionalUsage conditionalUsage,ConditionalType conditionalType)1594*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::UniformSpec> textureLookupShaderUniforms(const string &nameSpecialization,
1595*35238bceSAndroid Build Coastguard Worker                                                                            int numLookups,
1596*35238bceSAndroid Build Coastguard Worker                                                                            ConditionalUsage conditionalUsage,
1597*35238bceSAndroid Build Coastguard Worker                                                                            ConditionalType conditionalType)
1598*35238bceSAndroid Build Coastguard Worker {
1599*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::UniformSpec> result;
1600*35238bceSAndroid Build Coastguard Worker 
1601*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numLookups; i++)
1602*35238bceSAndroid Build Coastguard Worker         result.push_back(ShaderCompilerCase::UniformSpec("u_sampler" + de::toString(i) + nameSpecialization,
1603*35238bceSAndroid Build Coastguard Worker                                                          ShaderCompilerCase::UniformSpec::TYPE_TEXTURE_UNIT, (float)i));
1604*35238bceSAndroid Build Coastguard Worker 
1605*35238bceSAndroid Build Coastguard Worker     if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_UNIFORM)
1606*35238bceSAndroid Build Coastguard Worker         result.push_back(ShaderCompilerCase::UniformSpec("u_condition" + nameSpecialization,
1607*35238bceSAndroid Build Coastguard Worker                                                          ShaderCompilerCase::UniformSpec::TYPE_FLOAT, 1.0f));
1608*35238bceSAndroid Build Coastguard Worker 
1609*35238bceSAndroid Build Coastguard Worker     return result;
1610*35238bceSAndroid Build Coastguard Worker }
1611*35238bceSAndroid Build Coastguard Worker 
mandelbrotVertexTemplate(void)1612*35238bceSAndroid Build Coastguard Worker static string mandelbrotVertexTemplate(void)
1613*35238bceSAndroid Build Coastguard Worker {
1614*35238bceSAndroid Build Coastguard Worker     const char *resultTemplate =
1615*35238bceSAndroid Build Coastguard Worker         "#version 300 es\n"
1616*35238bceSAndroid Build Coastguard Worker         "uniform highp mat4 u_mvp${NAME_SPEC};\n"
1617*35238bceSAndroid Build Coastguard Worker         "\n"
1618*35238bceSAndroid Build Coastguard Worker         "in highp vec4 a_vertex${NAME_SPEC};\n"
1619*35238bceSAndroid Build Coastguard Worker         "in highp vec4 a_coord${NAME_SPEC};\n"
1620*35238bceSAndroid Build Coastguard Worker         "\n"
1621*35238bceSAndroid Build Coastguard Worker         "out mediump vec2 v_coord${NAME_SPEC};\n"
1622*35238bceSAndroid Build Coastguard Worker         "\n"
1623*35238bceSAndroid Build Coastguard Worker         "void main(void)\n"
1624*35238bceSAndroid Build Coastguard Worker         "{\n"
1625*35238bceSAndroid Build Coastguard Worker         "    gl_Position = u_mvp${NAME_SPEC} * a_vertex${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
1626*35238bceSAndroid Build Coastguard Worker         "\n"
1627*35238bceSAndroid Build Coastguard Worker         "    float xMin = -2.0;\n"
1628*35238bceSAndroid Build Coastguard Worker         "    float xMax = +0.5;\n"
1629*35238bceSAndroid Build Coastguard Worker         "    float yMin = -1.5;\n"
1630*35238bceSAndroid Build Coastguard Worker         "    float yMax = +1.5;\n"
1631*35238bceSAndroid Build Coastguard Worker         "\n"
1632*35238bceSAndroid Build Coastguard Worker         "    v_coord${NAME_SPEC}.x = a_coord${NAME_SPEC}.x * (xMax - xMin) + xMin;\n"
1633*35238bceSAndroid Build Coastguard Worker         "    v_coord${NAME_SPEC}.y = a_coord${NAME_SPEC}.y * (yMax - yMin) + yMin;\n"
1634*35238bceSAndroid Build Coastguard Worker         "${SEMANTIC_ERROR}"
1635*35238bceSAndroid Build Coastguard Worker         "}\n"
1636*35238bceSAndroid Build Coastguard Worker         "${INVALID_CHAR}";
1637*35238bceSAndroid Build Coastguard Worker 
1638*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1639*35238bceSAndroid Build Coastguard Worker }
1640*35238bceSAndroid Build Coastguard Worker 
mandelbrotFragmentTemplate(int numFractalIterations)1641*35238bceSAndroid Build Coastguard Worker static string mandelbrotFragmentTemplate(int numFractalIterations)
1642*35238bceSAndroid Build Coastguard Worker {
1643*35238bceSAndroid Build Coastguard Worker     string resultTemplate = "#version 300 es\n"
1644*35238bceSAndroid Build Coastguard Worker                             "layout(location = 0) out mediump vec4 o_color;\n"
1645*35238bceSAndroid Build Coastguard Worker                             "in mediump vec2 v_coord${NAME_SPEC};\n"
1646*35238bceSAndroid Build Coastguard Worker                             "\n"
1647*35238bceSAndroid Build Coastguard Worker                             "precision mediump float;\n"
1648*35238bceSAndroid Build Coastguard Worker                             "\n"
1649*35238bceSAndroid Build Coastguard Worker                             "#define NUM_ITERS " +
1650*35238bceSAndroid Build Coastguard Worker                             de::toString(numFractalIterations) +
1651*35238bceSAndroid Build Coastguard Worker                             "\n"
1652*35238bceSAndroid Build Coastguard Worker                             "\n"
1653*35238bceSAndroid Build Coastguard Worker                             "void main (void)\n"
1654*35238bceSAndroid Build Coastguard Worker                             "{\n"
1655*35238bceSAndroid Build Coastguard Worker                             "    vec2 coords = v_coord${NAME_SPEC};\n"
1656*35238bceSAndroid Build Coastguard Worker                             "    float u_limit = 2.0 * 2.0;\n"
1657*35238bceSAndroid Build Coastguard Worker                             "    vec2 tmp = vec2(0, 0);\n"
1658*35238bceSAndroid Build Coastguard Worker                             "    int iter;\n"
1659*35238bceSAndroid Build Coastguard Worker                             "\n"
1660*35238bceSAndroid Build Coastguard Worker                             "    for (iter = 0; iter < NUM_ITERS; iter++)\n"
1661*35238bceSAndroid Build Coastguard Worker                             "    {\n"
1662*35238bceSAndroid Build Coastguard Worker                             "        tmp = vec2((tmp.x + tmp.y) * (tmp.x - tmp.y), 2.0 * (tmp.x * tmp.y)) + coords;\n"
1663*35238bceSAndroid Build Coastguard Worker                             "\n"
1664*35238bceSAndroid Build Coastguard Worker                             "        if (dot(tmp, tmp) > u_limit)\n"
1665*35238bceSAndroid Build Coastguard Worker                             "            break;\n"
1666*35238bceSAndroid Build Coastguard Worker                             "    }\n"
1667*35238bceSAndroid Build Coastguard Worker                             "\n"
1668*35238bceSAndroid Build Coastguard Worker                             "    vec3 color = vec3(float(iter) * (1.0 / float(NUM_ITERS)));\n"
1669*35238bceSAndroid Build Coastguard Worker                             "\n"
1670*35238bceSAndroid Build Coastguard Worker                             "    o_color = vec4(color, 1.0) + ${FLOAT01};\n"
1671*35238bceSAndroid Build Coastguard Worker                             "${SEMANTIC_ERROR}"
1672*35238bceSAndroid Build Coastguard Worker                             "}\n"
1673*35238bceSAndroid Build Coastguard Worker                             "${INVALID_CHAR}";
1674*35238bceSAndroid Build Coastguard Worker 
1675*35238bceSAndroid Build Coastguard Worker     return resultTemplate;
1676*35238bceSAndroid Build Coastguard Worker }
1677*35238bceSAndroid Build Coastguard Worker 
mandelbrotShaderAttributes(const string & nameSpecialization)1678*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::AttribSpec> mandelbrotShaderAttributes(const string &nameSpecialization)
1679*35238bceSAndroid Build Coastguard Worker {
1680*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::AttribSpec> result;
1681*35238bceSAndroid Build Coastguard Worker 
1682*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::AttribSpec(
1683*35238bceSAndroid Build Coastguard Worker         "a_vertex" + nameSpecialization,
1684*35238bceSAndroid Build Coastguard Worker         combineVec4ToVec16(Vec4(-1.0f, -1.0f, 0.0f, 1.0f), Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec4(1.0f, -1.0f, 0.0f, 1.0f),
1685*35238bceSAndroid Build Coastguard Worker                            Vec4(1.0f, 1.0f, 0.0f, 1.0f))));
1686*35238bceSAndroid Build Coastguard Worker 
1687*35238bceSAndroid Build Coastguard Worker     result.push_back(
1688*35238bceSAndroid Build Coastguard Worker         ShaderCompilerCase::AttribSpec("a_coord" + nameSpecialization,
1689*35238bceSAndroid Build Coastguard Worker                                        combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f),
1690*35238bceSAndroid Build Coastguard Worker                                                           Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(1.0f, 1.0f, 0.0f, 1.0f))));
1691*35238bceSAndroid Build Coastguard Worker 
1692*35238bceSAndroid Build Coastguard Worker     return result;
1693*35238bceSAndroid Build Coastguard Worker }
1694*35238bceSAndroid Build Coastguard Worker 
mandelbrotShaderUniforms(const string & nameSpecialization)1695*35238bceSAndroid Build Coastguard Worker static vector<ShaderCompilerCase::UniformSpec> mandelbrotShaderUniforms(const string &nameSpecialization)
1696*35238bceSAndroid Build Coastguard Worker {
1697*35238bceSAndroid Build Coastguard Worker     vector<ShaderCompilerCase::UniformSpec> result;
1698*35238bceSAndroid Build Coastguard Worker 
1699*35238bceSAndroid Build Coastguard Worker     result.push_back(ShaderCompilerCase::UniformSpec("u_mvp" + nameSpecialization,
1700*35238bceSAndroid Build Coastguard Worker                                                      ShaderCompilerCase::UniformSpec::TYPE_MAT4,
1701*35238bceSAndroid Build Coastguard Worker                                                      arrTo16(Mat4(1.0f).getColumnMajorData())));
1702*35238bceSAndroid Build Coastguard Worker 
1703*35238bceSAndroid Build Coastguard Worker     return result;
1704*35238bceSAndroid Build Coastguard Worker }
1705*35238bceSAndroid Build Coastguard Worker 
ShaderCompilerCase(Context & context,const char * name,const char * description,int caseID,bool avoidCache,bool addWhitespaceAndComments)1706*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::ShaderCompilerCase(Context &context, const char *name, const char *description, int caseID,
1707*35238bceSAndroid Build Coastguard Worker                                        bool avoidCache, bool addWhitespaceAndComments)
1708*35238bceSAndroid Build Coastguard Worker     : TestCase(context, tcu::NODETYPE_PERFORMANCE, name, description)
1709*35238bceSAndroid Build Coastguard Worker     , m_viewportWidth(0)
1710*35238bceSAndroid Build Coastguard Worker     , m_viewportHeight(0)
1711*35238bceSAndroid Build Coastguard Worker     , m_avoidCache(avoidCache)
1712*35238bceSAndroid Build Coastguard Worker     , m_addWhitespaceAndComments(addWhitespaceAndComments)
1713*35238bceSAndroid Build Coastguard Worker     , m_startHash((uint32_t)(deUint64Hash(deGetTime()) ^ deUint64Hash(deGetMicroseconds()) ^ deInt32Hash(caseID)))
1714*35238bceSAndroid Build Coastguard Worker {
1715*35238bceSAndroid Build Coastguard Worker     int cmdLineIterCount      = context.getTestContext().getCommandLine().getTestIterationCount();
1716*35238bceSAndroid Build Coastguard Worker     m_minimumMeasurementCount = cmdLineIterCount > 0 ? cmdLineIterCount : DEFAULT_MINIMUM_MEASUREMENT_COUNT;
1717*35238bceSAndroid Build Coastguard Worker     m_maximumMeasurementCount = m_minimumMeasurementCount * 3;
1718*35238bceSAndroid Build Coastguard Worker }
1719*35238bceSAndroid Build Coastguard Worker 
~ShaderCompilerCase(void)1720*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::~ShaderCompilerCase(void)
1721*35238bceSAndroid Build Coastguard Worker {
1722*35238bceSAndroid Build Coastguard Worker }
1723*35238bceSAndroid Build Coastguard Worker 
getSpecializationID(int measurementNdx) const1724*35238bceSAndroid Build Coastguard Worker uint32_t ShaderCompilerCase::getSpecializationID(int measurementNdx) const
1725*35238bceSAndroid Build Coastguard Worker {
1726*35238bceSAndroid Build Coastguard Worker     if (m_avoidCache)
1727*35238bceSAndroid Build Coastguard Worker         return m_startHash ^ (uint32_t)deInt32Hash((int32_t)measurementNdx);
1728*35238bceSAndroid Build Coastguard Worker     else
1729*35238bceSAndroid Build Coastguard Worker         return m_startHash;
1730*35238bceSAndroid Build Coastguard Worker }
1731*35238bceSAndroid Build Coastguard Worker 
init(void)1732*35238bceSAndroid Build Coastguard Worker void ShaderCompilerCase::init(void)
1733*35238bceSAndroid Build Coastguard Worker {
1734*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl              = m_context.getRenderContext().getFunctions();
1735*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
1736*35238bceSAndroid Build Coastguard Worker 
1737*35238bceSAndroid Build Coastguard Worker     m_viewportWidth  = deMin32(MAX_VIEWPORT_WIDTH, renderTarget.getWidth());
1738*35238bceSAndroid Build Coastguard Worker     m_viewportHeight = deMin32(MAX_VIEWPORT_HEIGHT, renderTarget.getHeight());
1739*35238bceSAndroid Build Coastguard Worker 
1740*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, m_viewportWidth, m_viewportHeight);
1741*35238bceSAndroid Build Coastguard Worker }
1742*35238bceSAndroid Build Coastguard Worker 
createShadersAndProgram(void) const1743*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::ShadersAndProgram ShaderCompilerCase::createShadersAndProgram(void) const
1744*35238bceSAndroid Build Coastguard Worker {
1745*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1746*35238bceSAndroid Build Coastguard Worker     ShadersAndProgram result;
1747*35238bceSAndroid Build Coastguard Worker 
1748*35238bceSAndroid Build Coastguard Worker     result.vertShader = gl.createShader(GL_VERTEX_SHADER);
1749*35238bceSAndroid Build Coastguard Worker     result.fragShader = gl.createShader(GL_FRAGMENT_SHADER);
1750*35238bceSAndroid Build Coastguard Worker     result.program    = gl.createProgram();
1751*35238bceSAndroid Build Coastguard Worker 
1752*35238bceSAndroid Build Coastguard Worker     gl.attachShader(result.program, result.vertShader);
1753*35238bceSAndroid Build Coastguard Worker     gl.attachShader(result.program, result.fragShader);
1754*35238bceSAndroid Build Coastguard Worker 
1755*35238bceSAndroid Build Coastguard Worker     return result;
1756*35238bceSAndroid Build Coastguard Worker }
1757*35238bceSAndroid Build Coastguard Worker 
setShaderSources(uint32_t vertShader,uint32_t fragShader,const ProgramContext & progCtx) const1758*35238bceSAndroid Build Coastguard Worker void ShaderCompilerCase::setShaderSources(uint32_t vertShader, uint32_t fragShader, const ProgramContext &progCtx) const
1759*35238bceSAndroid Build Coastguard Worker {
1760*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl         = m_context.getRenderContext().getFunctions();
1761*35238bceSAndroid Build Coastguard Worker     const char *vertShaderSourceCStr = progCtx.vertShaderSource.c_str();
1762*35238bceSAndroid Build Coastguard Worker     const char *fragShaderSourceCStr = progCtx.fragShaderSource.c_str();
1763*35238bceSAndroid Build Coastguard Worker     gl.shaderSource(vertShader, 1, &vertShaderSourceCStr, DE_NULL);
1764*35238bceSAndroid Build Coastguard Worker     gl.shaderSource(fragShader, 1, &fragShaderSourceCStr, DE_NULL);
1765*35238bceSAndroid Build Coastguard Worker }
1766*35238bceSAndroid Build Coastguard Worker 
compileShader(uint32_t shader) const1767*35238bceSAndroid Build Coastguard Worker bool ShaderCompilerCase::compileShader(uint32_t shader) const
1768*35238bceSAndroid Build Coastguard Worker {
1769*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1770*35238bceSAndroid Build Coastguard Worker     GLint status             = 0;
1771*35238bceSAndroid Build Coastguard Worker     gl.compileShader(shader);
1772*35238bceSAndroid Build Coastguard Worker     gl.getShaderiv(shader, GL_COMPILE_STATUS, &status);
1773*35238bceSAndroid Build Coastguard Worker     return status != 0;
1774*35238bceSAndroid Build Coastguard Worker }
1775*35238bceSAndroid Build Coastguard Worker 
linkAndUseProgram(uint32_t program) const1776*35238bceSAndroid Build Coastguard Worker bool ShaderCompilerCase::linkAndUseProgram(uint32_t program) const
1777*35238bceSAndroid Build Coastguard Worker {
1778*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1779*35238bceSAndroid Build Coastguard Worker     GLint linkStatus         = 0;
1780*35238bceSAndroid Build Coastguard Worker 
1781*35238bceSAndroid Build Coastguard Worker     gl.linkProgram(program);
1782*35238bceSAndroid Build Coastguard Worker     gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus);
1783*35238bceSAndroid Build Coastguard Worker 
1784*35238bceSAndroid Build Coastguard Worker     if (linkStatus != 0)
1785*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program);
1786*35238bceSAndroid Build Coastguard Worker 
1787*35238bceSAndroid Build Coastguard Worker     return linkStatus != 0;
1788*35238bceSAndroid Build Coastguard Worker }
1789*35238bceSAndroid Build Coastguard Worker 
setShaderInputs(uint32_t program,const ProgramContext & progCtx) const1790*35238bceSAndroid Build Coastguard Worker void ShaderCompilerCase::setShaderInputs(uint32_t program, const ProgramContext &progCtx) const
1791*35238bceSAndroid Build Coastguard Worker {
1792*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1793*35238bceSAndroid Build Coastguard Worker 
1794*35238bceSAndroid Build Coastguard Worker     // Setup attributes.
1795*35238bceSAndroid Build Coastguard Worker 
1796*35238bceSAndroid Build Coastguard Worker     for (int attribNdx = 0; attribNdx < (int)progCtx.vertexAttributes.size(); attribNdx++)
1797*35238bceSAndroid Build Coastguard Worker     {
1798*35238bceSAndroid Build Coastguard Worker         int location = gl.getAttribLocation(program, progCtx.vertexAttributes[attribNdx].name.c_str());
1799*35238bceSAndroid Build Coastguard Worker         if (location >= 0)
1800*35238bceSAndroid Build Coastguard Worker         {
1801*35238bceSAndroid Build Coastguard Worker             gl.enableVertexAttribArray(location);
1802*35238bceSAndroid Build Coastguard Worker             gl.vertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, 0,
1803*35238bceSAndroid Build Coastguard Worker                                    progCtx.vertexAttributes[attribNdx].value.getPtr());
1804*35238bceSAndroid Build Coastguard Worker         }
1805*35238bceSAndroid Build Coastguard Worker     }
1806*35238bceSAndroid Build Coastguard Worker 
1807*35238bceSAndroid Build Coastguard Worker     // Setup uniforms.
1808*35238bceSAndroid Build Coastguard Worker 
1809*35238bceSAndroid Build Coastguard Worker     for (int uniformNdx = 0; uniformNdx < (int)progCtx.uniforms.size(); uniformNdx++)
1810*35238bceSAndroid Build Coastguard Worker     {
1811*35238bceSAndroid Build Coastguard Worker         int location = gl.getUniformLocation(program, progCtx.uniforms[uniformNdx].name.c_str());
1812*35238bceSAndroid Build Coastguard Worker         if (location >= 0)
1813*35238bceSAndroid Build Coastguard Worker         {
1814*35238bceSAndroid Build Coastguard Worker             const float *floatPtr = progCtx.uniforms[uniformNdx].value.getPtr();
1815*35238bceSAndroid Build Coastguard Worker 
1816*35238bceSAndroid Build Coastguard Worker             switch (progCtx.uniforms[uniformNdx].type)
1817*35238bceSAndroid Build Coastguard Worker             {
1818*35238bceSAndroid Build Coastguard Worker             case UniformSpec::TYPE_FLOAT:
1819*35238bceSAndroid Build Coastguard Worker                 gl.uniform1fv(location, 1, floatPtr);
1820*35238bceSAndroid Build Coastguard Worker                 break;
1821*35238bceSAndroid Build Coastguard Worker             case UniformSpec::TYPE_VEC2:
1822*35238bceSAndroid Build Coastguard Worker                 gl.uniform2fv(location, 1, floatPtr);
1823*35238bceSAndroid Build Coastguard Worker                 break;
1824*35238bceSAndroid Build Coastguard Worker             case UniformSpec::TYPE_VEC3:
1825*35238bceSAndroid Build Coastguard Worker                 gl.uniform3fv(location, 1, floatPtr);
1826*35238bceSAndroid Build Coastguard Worker                 break;
1827*35238bceSAndroid Build Coastguard Worker             case UniformSpec::TYPE_VEC4:
1828*35238bceSAndroid Build Coastguard Worker                 gl.uniform4fv(location, 1, floatPtr);
1829*35238bceSAndroid Build Coastguard Worker                 break;
1830*35238bceSAndroid Build Coastguard Worker             case UniformSpec::TYPE_MAT3:
1831*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix3fv(location, 1, GL_FALSE, floatPtr);
1832*35238bceSAndroid Build Coastguard Worker                 break;
1833*35238bceSAndroid Build Coastguard Worker             case UniformSpec::TYPE_MAT4:
1834*35238bceSAndroid Build Coastguard Worker                 gl.uniformMatrix4fv(location, 1, GL_FALSE, floatPtr);
1835*35238bceSAndroid Build Coastguard Worker                 break;
1836*35238bceSAndroid Build Coastguard Worker             case UniformSpec::TYPE_TEXTURE_UNIT:
1837*35238bceSAndroid Build Coastguard Worker                 gl.uniform1i(location, (GLint)deRoundFloatToInt32(*floatPtr));
1838*35238bceSAndroid Build Coastguard Worker                 break;
1839*35238bceSAndroid Build Coastguard Worker             default:
1840*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1841*35238bceSAndroid Build Coastguard Worker             }
1842*35238bceSAndroid Build Coastguard Worker         }
1843*35238bceSAndroid Build Coastguard Worker     }
1844*35238bceSAndroid Build Coastguard Worker }
1845*35238bceSAndroid Build Coastguard Worker 
draw(void) const1846*35238bceSAndroid Build Coastguard Worker void ShaderCompilerCase::draw(void) const
1847*35238bceSAndroid Build Coastguard Worker {
1848*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1849*35238bceSAndroid Build Coastguard Worker 
1850*35238bceSAndroid Build Coastguard Worker     static const uint8_t indices[] = {0, 1, 2, 2, 1, 3};
1851*35238bceSAndroid Build Coastguard Worker 
1852*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1853*35238bceSAndroid Build Coastguard Worker     gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_BYTE, indices);
1854*35238bceSAndroid Build Coastguard Worker 
1855*35238bceSAndroid Build Coastguard Worker     // \note Read one pixel to force compilation.
1856*35238bceSAndroid Build Coastguard Worker     uint32_t pixel;
1857*35238bceSAndroid Build Coastguard Worker     gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
1858*35238bceSAndroid Build Coastguard Worker }
1859*35238bceSAndroid Build Coastguard Worker 
cleanup(const ShadersAndProgram & shadersAndProgram,const ProgramContext & progCtx,bool linkSuccess) const1860*35238bceSAndroid Build Coastguard Worker void ShaderCompilerCase::cleanup(const ShadersAndProgram &shadersAndProgram, const ProgramContext &progCtx,
1861*35238bceSAndroid Build Coastguard Worker                                  bool linkSuccess) const
1862*35238bceSAndroid Build Coastguard Worker {
1863*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1864*35238bceSAndroid Build Coastguard Worker 
1865*35238bceSAndroid Build Coastguard Worker     if (linkSuccess)
1866*35238bceSAndroid Build Coastguard Worker     {
1867*35238bceSAndroid Build Coastguard Worker         for (int attribNdx = 0; attribNdx < (int)progCtx.vertexAttributes.size(); attribNdx++)
1868*35238bceSAndroid Build Coastguard Worker         {
1869*35238bceSAndroid Build Coastguard Worker             int location =
1870*35238bceSAndroid Build Coastguard Worker                 gl.getAttribLocation(shadersAndProgram.program, progCtx.vertexAttributes[attribNdx].name.c_str());
1871*35238bceSAndroid Build Coastguard Worker             if (location >= 0)
1872*35238bceSAndroid Build Coastguard Worker                 gl.disableVertexAttribArray(location);
1873*35238bceSAndroid Build Coastguard Worker         }
1874*35238bceSAndroid Build Coastguard Worker     }
1875*35238bceSAndroid Build Coastguard Worker 
1876*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
1877*35238bceSAndroid Build Coastguard Worker     gl.detachShader(shadersAndProgram.program, shadersAndProgram.vertShader);
1878*35238bceSAndroid Build Coastguard Worker     gl.detachShader(shadersAndProgram.program, shadersAndProgram.fragShader);
1879*35238bceSAndroid Build Coastguard Worker     gl.deleteShader(shadersAndProgram.vertShader);
1880*35238bceSAndroid Build Coastguard Worker     gl.deleteShader(shadersAndProgram.fragShader);
1881*35238bceSAndroid Build Coastguard Worker     gl.deleteProgram(shadersAndProgram.program);
1882*35238bceSAndroid Build Coastguard Worker }
1883*35238bceSAndroid Build Coastguard Worker 
logProgramData(const BuildInfo & buildInfo,const ProgramContext & progCtx) const1884*35238bceSAndroid Build Coastguard Worker void ShaderCompilerCase::logProgramData(const BuildInfo &buildInfo, const ProgramContext &progCtx) const
1885*35238bceSAndroid Build Coastguard Worker {
1886*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << TestLog::ShaderProgram(buildInfo.linkSuccess, buildInfo.logs.link)
1887*35238bceSAndroid Build Coastguard Worker                        << TestLog::Shader(QP_SHADER_TYPE_VERTEX, progCtx.vertShaderSource, buildInfo.vertCompileSuccess,
1888*35238bceSAndroid Build Coastguard Worker                                           buildInfo.logs.vert)
1889*35238bceSAndroid Build Coastguard Worker                        << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT, progCtx.fragShaderSource,
1890*35238bceSAndroid Build Coastguard Worker                                           buildInfo.fragCompileSuccess, buildInfo.logs.frag)
1891*35238bceSAndroid Build Coastguard Worker                        << TestLog::EndShaderProgram;
1892*35238bceSAndroid Build Coastguard Worker }
1893*35238bceSAndroid Build Coastguard Worker 
getLogs(const ShadersAndProgram & shadersAndProgram) const1894*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::Logs ShaderCompilerCase::getLogs(const ShadersAndProgram &shadersAndProgram) const
1895*35238bceSAndroid Build Coastguard Worker {
1896*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1897*35238bceSAndroid Build Coastguard Worker     Logs result;
1898*35238bceSAndroid Build Coastguard Worker 
1899*35238bceSAndroid Build Coastguard Worker     result.vert = getShaderInfoLog(gl, shadersAndProgram.vertShader);
1900*35238bceSAndroid Build Coastguard Worker     result.frag = getShaderInfoLog(gl, shadersAndProgram.fragShader);
1901*35238bceSAndroid Build Coastguard Worker     result.link = getProgramInfoLog(gl, shadersAndProgram.program);
1902*35238bceSAndroid Build Coastguard Worker 
1903*35238bceSAndroid Build Coastguard Worker     return result;
1904*35238bceSAndroid Build Coastguard Worker }
1905*35238bceSAndroid Build Coastguard Worker 
goodEnoughMeasurements(const vector<Measurement> & measurements) const1906*35238bceSAndroid Build Coastguard Worker bool ShaderCompilerCase::goodEnoughMeasurements(const vector<Measurement> &measurements) const
1907*35238bceSAndroid Build Coastguard Worker {
1908*35238bceSAndroid Build Coastguard Worker     if ((int)measurements.size() < m_minimumMeasurementCount)
1909*35238bceSAndroid Build Coastguard Worker         return false;
1910*35238bceSAndroid Build Coastguard Worker     else
1911*35238bceSAndroid Build Coastguard Worker     {
1912*35238bceSAndroid Build Coastguard Worker         if ((int)measurements.size() >= m_maximumMeasurementCount)
1913*35238bceSAndroid Build Coastguard Worker             return true;
1914*35238bceSAndroid Build Coastguard Worker         else
1915*35238bceSAndroid Build Coastguard Worker         {
1916*35238bceSAndroid Build Coastguard Worker             vector<int64_t> totalTimesWithoutDraw;
1917*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < (int)measurements.size(); i++)
1918*35238bceSAndroid Build Coastguard Worker                 totalTimesWithoutDraw.push_back(measurements[i].totalTimeWithoutDraw());
1919*35238bceSAndroid Build Coastguard Worker             return vectorFloatRelativeMedianAbsoluteDeviation(vectorLowestPercentage(totalTimesWithoutDraw, 0.5f)) <
1920*35238bceSAndroid Build Coastguard Worker                    RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD;
1921*35238bceSAndroid Build Coastguard Worker         }
1922*35238bceSAndroid Build Coastguard Worker     }
1923*35238bceSAndroid Build Coastguard Worker }
1924*35238bceSAndroid Build Coastguard Worker 
iterate(void)1925*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::IterateResult ShaderCompilerCase::iterate(void)
1926*35238bceSAndroid Build Coastguard Worker {
1927*35238bceSAndroid Build Coastguard Worker     // Before actual measurements, compile and draw with a minimal shader to avoid possible initial slowdowns in the actual test.
1928*35238bceSAndroid Build Coastguard Worker     {
1929*35238bceSAndroid Build Coastguard Worker         uint32_t specID = getSpecializationID(0);
1930*35238bceSAndroid Build Coastguard Worker         ProgramContext progCtx;
1931*35238bceSAndroid Build Coastguard Worker         progCtx.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, SHADER_VALIDITY_VALID);
1932*35238bceSAndroid Build Coastguard Worker         progCtx.fragShaderSource =
1933*35238bceSAndroid Build Coastguard Worker             specializeShaderSource(singleVaryingFragmentTemplate(), specID, SHADER_VALIDITY_VALID);
1934*35238bceSAndroid Build Coastguard Worker         progCtx.vertexAttributes = singleValueShaderAttributes(getNameSpecialization(specID));
1935*35238bceSAndroid Build Coastguard Worker 
1936*35238bceSAndroid Build Coastguard Worker         ShadersAndProgram shadersAndProgram = createShadersAndProgram();
1937*35238bceSAndroid Build Coastguard Worker         setShaderSources(shadersAndProgram.vertShader, shadersAndProgram.fragShader, progCtx);
1938*35238bceSAndroid Build Coastguard Worker 
1939*35238bceSAndroid Build Coastguard Worker         BuildInfo buildInfo;
1940*35238bceSAndroid Build Coastguard Worker         buildInfo.vertCompileSuccess = compileShader(shadersAndProgram.vertShader);
1941*35238bceSAndroid Build Coastguard Worker         buildInfo.fragCompileSuccess = compileShader(shadersAndProgram.fragShader);
1942*35238bceSAndroid Build Coastguard Worker         buildInfo.linkSuccess        = linkAndUseProgram(shadersAndProgram.program);
1943*35238bceSAndroid Build Coastguard Worker         if (!(buildInfo.vertCompileSuccess && buildInfo.fragCompileSuccess && buildInfo.linkSuccess))
1944*35238bceSAndroid Build Coastguard Worker         {
1945*35238bceSAndroid Build Coastguard Worker             buildInfo.logs = getLogs(shadersAndProgram);
1946*35238bceSAndroid Build Coastguard Worker             logProgramData(buildInfo, progCtx);
1947*35238bceSAndroid Build Coastguard Worker             cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
1948*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation failed");
1949*35238bceSAndroid Build Coastguard Worker             return STOP;
1950*35238bceSAndroid Build Coastguard Worker         }
1951*35238bceSAndroid Build Coastguard Worker         setShaderInputs(shadersAndProgram.program, progCtx);
1952*35238bceSAndroid Build Coastguard Worker         draw();
1953*35238bceSAndroid Build Coastguard Worker         cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
1954*35238bceSAndroid Build Coastguard Worker     }
1955*35238bceSAndroid Build Coastguard Worker 
1956*35238bceSAndroid Build Coastguard Worker     vector<Measurement> measurements;
1957*35238bceSAndroid Build Coastguard Worker     // \note These are logged after measurements are done.
1958*35238bceSAndroid Build Coastguard Worker     ProgramContext latestProgramContext;
1959*35238bceSAndroid Build Coastguard Worker     BuildInfo latestBuildInfo;
1960*35238bceSAndroid Build Coastguard Worker 
1961*35238bceSAndroid Build Coastguard Worker     if (WARMUP_CPU_AT_BEGINNING_OF_CASE)
1962*35238bceSAndroid Build Coastguard Worker         tcu::warmupCPU();
1963*35238bceSAndroid Build Coastguard Worker 
1964*35238bceSAndroid Build Coastguard Worker     // Actual test measurements.
1965*35238bceSAndroid Build Coastguard Worker     while (!goodEnoughMeasurements(measurements))
1966*35238bceSAndroid Build Coastguard Worker     {
1967*35238bceSAndroid Build Coastguard Worker         // Create shaders, compile & link, set shader inputs and draw. Time measurement is done at relevant points.
1968*35238bceSAndroid Build Coastguard Worker         // \note Setting inputs and drawing are done twice in order to find out the time for actual compiling.
1969*35238bceSAndroid Build Coastguard Worker 
1970*35238bceSAndroid Build Coastguard Worker         // \note Shader data (sources and inputs) are generated and GL shader and program objects are created before any time measurements.
1971*35238bceSAndroid Build Coastguard Worker         ProgramContext progCtx              = generateShaderData((int)measurements.size());
1972*35238bceSAndroid Build Coastguard Worker         ShadersAndProgram shadersAndProgram = createShadersAndProgram();
1973*35238bceSAndroid Build Coastguard Worker         BuildInfo buildInfo;
1974*35238bceSAndroid Build Coastguard Worker 
1975*35238bceSAndroid Build Coastguard Worker         if (m_addWhitespaceAndComments)
1976*35238bceSAndroid Build Coastguard Worker         {
1977*35238bceSAndroid Build Coastguard Worker             const uint32_t hash      = m_startHash ^ (uint32_t)deInt32Hash((int32_t)measurements.size());
1978*35238bceSAndroid Build Coastguard Worker             progCtx.vertShaderSource = strWithWhiteSpaceAndComments(progCtx.vertShaderSource, hash);
1979*35238bceSAndroid Build Coastguard Worker             progCtx.fragShaderSource = strWithWhiteSpaceAndComments(progCtx.fragShaderSource, hash);
1980*35238bceSAndroid Build Coastguard Worker         }
1981*35238bceSAndroid Build Coastguard Worker 
1982*35238bceSAndroid Build Coastguard Worker         if (WARMUP_CPU_BEFORE_EACH_MEASUREMENT)
1983*35238bceSAndroid Build Coastguard Worker             tcu::warmupCPU();
1984*35238bceSAndroid Build Coastguard Worker 
1985*35238bceSAndroid Build Coastguard Worker         // \note Do NOT do anything too hefty between the first and last deGetMicroseconds() here (other than the gl calls); it would disturb the measurement.
1986*35238bceSAndroid Build Coastguard Worker 
1987*35238bceSAndroid Build Coastguard Worker         uint64_t startTime = deGetMicroseconds();
1988*35238bceSAndroid Build Coastguard Worker 
1989*35238bceSAndroid Build Coastguard Worker         setShaderSources(shadersAndProgram.vertShader, shadersAndProgram.fragShader, progCtx);
1990*35238bceSAndroid Build Coastguard Worker         uint64_t shaderSourceSetEndTime = deGetMicroseconds();
1991*35238bceSAndroid Build Coastguard Worker 
1992*35238bceSAndroid Build Coastguard Worker         buildInfo.vertCompileSuccess        = compileShader(shadersAndProgram.vertShader);
1993*35238bceSAndroid Build Coastguard Worker         uint64_t vertexShaderCompileEndTime = deGetMicroseconds();
1994*35238bceSAndroid Build Coastguard Worker 
1995*35238bceSAndroid Build Coastguard Worker         buildInfo.fragCompileSuccess          = compileShader(shadersAndProgram.fragShader);
1996*35238bceSAndroid Build Coastguard Worker         uint64_t fragmentShaderCompileEndTime = deGetMicroseconds();
1997*35238bceSAndroid Build Coastguard Worker 
1998*35238bceSAndroid Build Coastguard Worker         buildInfo.linkSuccess       = linkAndUseProgram(shadersAndProgram.program);
1999*35238bceSAndroid Build Coastguard Worker         uint64_t programLinkEndTime = deGetMicroseconds();
2000*35238bceSAndroid Build Coastguard Worker 
2001*35238bceSAndroid Build Coastguard Worker         // Check compilation and linking status here, after all compilation and linking gl calls are made.
2002*35238bceSAndroid Build Coastguard Worker         if (!(buildInfo.vertCompileSuccess && buildInfo.fragCompileSuccess && buildInfo.linkSuccess))
2003*35238bceSAndroid Build Coastguard Worker         {
2004*35238bceSAndroid Build Coastguard Worker             buildInfo.logs = getLogs(shadersAndProgram);
2005*35238bceSAndroid Build Coastguard Worker             logProgramData(buildInfo, progCtx);
2006*35238bceSAndroid Build Coastguard Worker             cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
2007*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation failed");
2008*35238bceSAndroid Build Coastguard Worker             return STOP;
2009*35238bceSAndroid Build Coastguard Worker         }
2010*35238bceSAndroid Build Coastguard Worker 
2011*35238bceSAndroid Build Coastguard Worker         setShaderInputs(shadersAndProgram.program, progCtx);
2012*35238bceSAndroid Build Coastguard Worker         uint64_t firstShaderInputSetEndTime = deGetMicroseconds();
2013*35238bceSAndroid Build Coastguard Worker 
2014*35238bceSAndroid Build Coastguard Worker         // Draw for the first time.
2015*35238bceSAndroid Build Coastguard Worker         draw();
2016*35238bceSAndroid Build Coastguard Worker         uint64_t firstDrawEndTime = deGetMicroseconds();
2017*35238bceSAndroid Build Coastguard Worker 
2018*35238bceSAndroid Build Coastguard Worker         // Set inputs and draw again.
2019*35238bceSAndroid Build Coastguard Worker 
2020*35238bceSAndroid Build Coastguard Worker         setShaderInputs(shadersAndProgram.program, progCtx);
2021*35238bceSAndroid Build Coastguard Worker         uint64_t secondShaderInputSetEndTime = deGetMicroseconds();
2022*35238bceSAndroid Build Coastguard Worker 
2023*35238bceSAndroid Build Coastguard Worker         draw();
2024*35238bceSAndroid Build Coastguard Worker         uint64_t secondDrawEndTime = deGetMicroseconds();
2025*35238bceSAndroid Build Coastguard Worker 
2026*35238bceSAndroid Build Coastguard Worker         // De-initializations (detach shaders etc.).
2027*35238bceSAndroid Build Coastguard Worker 
2028*35238bceSAndroid Build Coastguard Worker         buildInfo.logs = getLogs(shadersAndProgram);
2029*35238bceSAndroid Build Coastguard Worker         cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
2030*35238bceSAndroid Build Coastguard Worker 
2031*35238bceSAndroid Build Coastguard Worker         // Output measurement log later (after last measurement).
2032*35238bceSAndroid Build Coastguard Worker 
2033*35238bceSAndroid Build Coastguard Worker         measurements.push_back(Measurement((int64_t)(shaderSourceSetEndTime - startTime),
2034*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(vertexShaderCompileEndTime - shaderSourceSetEndTime),
2035*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(fragmentShaderCompileEndTime - vertexShaderCompileEndTime),
2036*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(programLinkEndTime - fragmentShaderCompileEndTime),
2037*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(firstShaderInputSetEndTime - programLinkEndTime),
2038*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(firstDrawEndTime - firstShaderInputSetEndTime),
2039*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(secondShaderInputSetEndTime - firstDrawEndTime),
2040*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(secondDrawEndTime - secondShaderInputSetEndTime)));
2041*35238bceSAndroid Build Coastguard Worker 
2042*35238bceSAndroid Build Coastguard Worker         latestBuildInfo      = buildInfo;
2043*35238bceSAndroid Build Coastguard Worker         latestProgramContext = progCtx;
2044*35238bceSAndroid Build Coastguard Worker 
2045*35238bceSAndroid Build Coastguard Worker         m_testCtx.touchWatchdog(); // \note Measurements may take a while in a bad case.
2046*35238bceSAndroid Build Coastguard Worker     }
2047*35238bceSAndroid Build Coastguard Worker 
2048*35238bceSAndroid Build Coastguard Worker     // End of test case, log information about measurements.
2049*35238bceSAndroid Build Coastguard Worker     {
2050*35238bceSAndroid Build Coastguard Worker         TestLog &log = m_testCtx.getLog();
2051*35238bceSAndroid Build Coastguard Worker 
2052*35238bceSAndroid Build Coastguard Worker         vector<int64_t> sourceSetTimes;
2053*35238bceSAndroid Build Coastguard Worker         vector<int64_t> vertexCompileTimes;
2054*35238bceSAndroid Build Coastguard Worker         vector<int64_t> fragmentCompileTimes;
2055*35238bceSAndroid Build Coastguard Worker         vector<int64_t> programLinkTimes;
2056*35238bceSAndroid Build Coastguard Worker         vector<int64_t> firstInputSetTimes;
2057*35238bceSAndroid Build Coastguard Worker         vector<int64_t> firstDrawTimes;
2058*35238bceSAndroid Build Coastguard Worker         vector<int64_t> secondInputTimes;
2059*35238bceSAndroid Build Coastguard Worker         vector<int64_t> secondDrawTimes;
2060*35238bceSAndroid Build Coastguard Worker         vector<int64_t> firstPhaseTimes;
2061*35238bceSAndroid Build Coastguard Worker         vector<int64_t> secondPhaseTimes;
2062*35238bceSAndroid Build Coastguard Worker         vector<int64_t> totalTimesWithoutDraw;
2063*35238bceSAndroid Build Coastguard Worker         vector<int64_t> specializationTimes;
2064*35238bceSAndroid Build Coastguard Worker 
2065*35238bceSAndroid Build Coastguard Worker         if (!m_avoidCache)
2066*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message
2067*35238bceSAndroid Build Coastguard Worker                 << "Note: Testing cache hits, so the medians and averages exclude the first iteration."
2068*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
2069*35238bceSAndroid Build Coastguard Worker 
2070*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Note: \"Specialization time\" means first draw time minus second draw time."
2071*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage << TestLog::Message
2072*35238bceSAndroid Build Coastguard Worker             << "Note: \"Compilation time\" means the time up to (and including) linking, plus specialization time."
2073*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
2074*35238bceSAndroid Build Coastguard Worker 
2075*35238bceSAndroid Build Coastguard Worker         log << TestLog::Section("IterationMeasurements", "Iteration measurements of compilation and linking times");
2076*35238bceSAndroid Build Coastguard Worker 
2077*35238bceSAndroid Build Coastguard Worker         DE_ASSERT((int)measurements.size() > (m_avoidCache ? 0 : 1));
2078*35238bceSAndroid Build Coastguard Worker 
2079*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)measurements.size(); ndx++)
2080*35238bceSAndroid Build Coastguard Worker         {
2081*35238bceSAndroid Build Coastguard Worker             const Measurement &curMeas = measurements[ndx];
2082*35238bceSAndroid Build Coastguard Worker 
2083*35238bceSAndroid Build Coastguard Worker             // Subtract time of second phase (second input setup and draw) from first (from start to end of first draw).
2084*35238bceSAndroid Build Coastguard Worker             // \note Cap if second phase seems unreasonably high (higher than first input set and draw).
2085*35238bceSAndroid Build Coastguard Worker             int64_t timeWithoutDraw = curMeas.totalTimeWithoutDraw();
2086*35238bceSAndroid Build Coastguard Worker 
2087*35238bceSAndroid Build Coastguard Worker             // Specialization time = first draw - second draw time. Again, cap at 0 if second draw was longer than first draw.
2088*35238bceSAndroid Build Coastguard Worker             int64_t specializationTime = de::max<int64_t>(0, curMeas.firstDrawTime - curMeas.secondDrawTime);
2089*35238bceSAndroid Build Coastguard Worker 
2090*35238bceSAndroid Build Coastguard Worker             if (ndx > 0 ||
2091*35238bceSAndroid Build Coastguard Worker                 m_avoidCache) // \note When allowing cache hits, don't account for the first measurement when calculating median or average.
2092*35238bceSAndroid Build Coastguard Worker             {
2093*35238bceSAndroid Build Coastguard Worker                 sourceSetTimes.push_back(curMeas.sourceSetTime);
2094*35238bceSAndroid Build Coastguard Worker                 vertexCompileTimes.push_back(curMeas.vertexCompileTime);
2095*35238bceSAndroid Build Coastguard Worker                 fragmentCompileTimes.push_back(curMeas.fragmentCompileTime);
2096*35238bceSAndroid Build Coastguard Worker                 programLinkTimes.push_back(curMeas.programLinkTime);
2097*35238bceSAndroid Build Coastguard Worker                 firstInputSetTimes.push_back(curMeas.firstInputSetTime);
2098*35238bceSAndroid Build Coastguard Worker                 firstDrawTimes.push_back(curMeas.firstDrawTime);
2099*35238bceSAndroid Build Coastguard Worker                 firstPhaseTimes.push_back(curMeas.firstPhase());
2100*35238bceSAndroid Build Coastguard Worker                 secondDrawTimes.push_back(curMeas.secondDrawTime);
2101*35238bceSAndroid Build Coastguard Worker                 secondInputTimes.push_back(curMeas.secondInputSetTime);
2102*35238bceSAndroid Build Coastguard Worker                 secondPhaseTimes.push_back(curMeas.secondPhase());
2103*35238bceSAndroid Build Coastguard Worker                 totalTimesWithoutDraw.push_back(timeWithoutDraw);
2104*35238bceSAndroid Build Coastguard Worker                 specializationTimes.push_back(specializationTime);
2105*35238bceSAndroid Build Coastguard Worker             }
2106*35238bceSAndroid Build Coastguard Worker 
2107*35238bceSAndroid Build Coastguard Worker             // Log this measurement.
2108*35238bceSAndroid Build Coastguard Worker             log << TestLog::Float("Measurement" + de::toString(ndx) + "CompilationTime",
2109*35238bceSAndroid Build Coastguard Worker                                   "Measurement " + de::toString(ndx) + " compilation time", "ms", QP_KEY_TAG_TIME,
2110*35238bceSAndroid Build Coastguard Worker                                   (float)timeWithoutDraw / 1000.0f)
2111*35238bceSAndroid Build Coastguard Worker                 << TestLog::Float("Measurement" + de::toString(ndx) + "SpecializationTime",
2112*35238bceSAndroid Build Coastguard Worker                                   "Measurement " + de::toString(ndx) + " specialization time", "ms", QP_KEY_TAG_TIME,
2113*35238bceSAndroid Build Coastguard Worker                                   (float)specializationTime / 1000.0f);
2114*35238bceSAndroid Build Coastguard Worker         }
2115*35238bceSAndroid Build Coastguard Worker 
2116*35238bceSAndroid Build Coastguard Worker         // Log some statistics.
2117*35238bceSAndroid Build Coastguard Worker 
2118*35238bceSAndroid Build Coastguard Worker         for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
2119*35238bceSAndroid Build Coastguard Worker         {
2120*35238bceSAndroid Build Coastguard Worker             bool isEntireRange    = entireRangeOrLowestHalf == 0;
2121*35238bceSAndroid Build Coastguard Worker             string statNamePrefix = isEntireRange ? "" : "LowestHalf";
2122*35238bceSAndroid Build Coastguard Worker             vector<int64_t> rangeTotalTimes =
2123*35238bceSAndroid Build Coastguard Worker                 isEntireRange ? totalTimesWithoutDraw : vectorLowestPercentage(totalTimesWithoutDraw, 0.5f);
2124*35238bceSAndroid Build Coastguard Worker             vector<int64_t> rangeSpecializationTimes =
2125*35238bceSAndroid Build Coastguard Worker                 isEntireRange ? specializationTimes : vectorLowestPercentage(specializationTimes, 0.5f);
2126*35238bceSAndroid Build Coastguard Worker 
2127*35238bceSAndroid Build Coastguard Worker #define LOG_COMPILE_SPECIALIZE_TIME_STAT(NAME, DESC, FUNC)                                                            \
2128*35238bceSAndroid Build Coastguard Worker     log << TestLog::Float(statNamePrefix + "CompilationTime" + (NAME), (DESC) + string(" of compilation time"), "ms", \
2129*35238bceSAndroid Build Coastguard Worker                           QP_KEY_TAG_TIME, (FUNC)(rangeTotalTimes) / 1000.0f)                                         \
2130*35238bceSAndroid Build Coastguard Worker         << TestLog::Float(statNamePrefix + "SpecializationTime" + (NAME), (DESC) + string(" of specialization time"), \
2131*35238bceSAndroid Build Coastguard Worker                           "ms", QP_KEY_TAG_TIME, (FUNC)(rangeSpecializationTimes) / 1000.0f)
2132*35238bceSAndroid Build Coastguard Worker 
2133*35238bceSAndroid Build Coastguard Worker #define LOG_COMPILE_SPECIALIZE_RELATIVE_STAT(NAME, DESC, FUNC)                                                        \
2134*35238bceSAndroid Build Coastguard Worker     log << TestLog::Float(statNamePrefix + "CompilationTime" + (NAME), (DESC) + string(" of compilation time"), "",   \
2135*35238bceSAndroid Build Coastguard Worker                           QP_KEY_TAG_NONE, (FUNC)(rangeTotalTimes))                                                   \
2136*35238bceSAndroid Build Coastguard Worker         << TestLog::Float(statNamePrefix + "SpecializationTime" + (NAME), (DESC) + string(" of specialization time"), \
2137*35238bceSAndroid Build Coastguard Worker                           "", QP_KEY_TAG_NONE, (FUNC)(rangeSpecializationTimes))
2138*35238bceSAndroid Build Coastguard Worker 
2139*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "\nStatistics computed from " << (isEntireRange ? "all" : "only the lowest 50%")
2140*35238bceSAndroid Build Coastguard Worker                 << " of the above measurements:" << TestLog::EndMessage;
2141*35238bceSAndroid Build Coastguard Worker 
2142*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_TIME_STAT("Median", "Median", vectorFloatMedian);
2143*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_TIME_STAT("Average", "Average", vectorFloatAverage);
2144*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_TIME_STAT("Minimum", "Minimum", vectorFloatMinimum);
2145*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_TIME_STAT("Maximum", "Maximum", vectorFloatMaximum);
2146*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_TIME_STAT("MedianAbsoluteDeviation", "Median absolute deviation",
2147*35238bceSAndroid Build Coastguard Worker                                              vectorFloatMedianAbsoluteDeviation);
2148*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_RELATIVE_STAT("RelativeMedianAbsoluteDeviation",
2149*35238bceSAndroid Build Coastguard Worker                                                  "Relative median absolute deviation",
2150*35238bceSAndroid Build Coastguard Worker                                                  vectorFloatRelativeMedianAbsoluteDeviation);
2151*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_TIME_STAT("StandardDeviation", "Standard deviation", vectorFloatStandardDeviation);
2152*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_RELATIVE_STAT("RelativeStandardDeviation", "Relative standard deviation",
2153*35238bceSAndroid Build Coastguard Worker                                                  vectorFloatRelativeStandardDeviation);
2154*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_TIME_STAT("MaxMinusMin", "Max-min", vectorFloatMaximumMinusMinimum);
2155*35238bceSAndroid Build Coastguard Worker             LOG_COMPILE_SPECIALIZE_RELATIVE_STAT("RelativeMaxMinusMin", "Relative max-min",
2156*35238bceSAndroid Build Coastguard Worker                                                  vectorFloatRelativeMaximumMinusMinimum);
2157*35238bceSAndroid Build Coastguard Worker 
2158*35238bceSAndroid Build Coastguard Worker #undef LOG_COMPILE_SPECIALIZE_RELATIVE_STAT
2159*35238bceSAndroid Build Coastguard Worker #undef LOG_COMPILE_SPECIALIZE_TIME_STAT
2160*35238bceSAndroid Build Coastguard Worker 
2161*35238bceSAndroid Build Coastguard Worker             if (!isEntireRange && vectorFloatRelativeMedianAbsoluteDeviation(rangeTotalTimes) >
2162*35238bceSAndroid Build Coastguard Worker                                       RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD)
2163*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
2164*35238bceSAndroid Build Coastguard Worker                     << "\nWARNING: couldn't achieve relative median absolute deviation under threshold value "
2165*35238bceSAndroid Build Coastguard Worker                     << RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD
2166*35238bceSAndroid Build Coastguard Worker                     << " for compilation time of the lowest 50% of measurements" << TestLog::EndMessage;
2167*35238bceSAndroid Build Coastguard Worker         }
2168*35238bceSAndroid Build Coastguard Worker 
2169*35238bceSAndroid Build Coastguard Worker         log << TestLog::EndSection; // End section IterationMeasurements
2170*35238bceSAndroid Build Coastguard Worker 
2171*35238bceSAndroid Build Coastguard Worker         for (int medianOrAverage = 0; medianOrAverage < 2; medianOrAverage++)
2172*35238bceSAndroid Build Coastguard Worker         {
2173*35238bceSAndroid Build Coastguard Worker             typedef float (*VecFunc)(const vector<int64_t> &);
2174*35238bceSAndroid Build Coastguard Worker 
2175*35238bceSAndroid Build Coastguard Worker             bool isMedian   = medianOrAverage == 0;
2176*35238bceSAndroid Build Coastguard Worker             string singular = isMedian ? "Median" : "Average";
2177*35238bceSAndroid Build Coastguard Worker             string plural   = singular + "s";
2178*35238bceSAndroid Build Coastguard Worker             VecFunc func    = isMedian ? (VecFunc)vectorFloatMedian<int64_t> : (VecFunc)vectorFloatAverage<int64_t>;
2179*35238bceSAndroid Build Coastguard Worker 
2180*35238bceSAndroid Build Coastguard Worker             log << TestLog::Section(plural + "PerPhase", plural + " per phase");
2181*35238bceSAndroid Build Coastguard Worker 
2182*35238bceSAndroid Build Coastguard Worker             for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
2183*35238bceSAndroid Build Coastguard Worker             {
2184*35238bceSAndroid Build Coastguard Worker                 bool isEntireRange    = entireRangeOrLowestHalf == 0;
2185*35238bceSAndroid Build Coastguard Worker                 string statNamePrefix = isEntireRange ? "" : "LowestHalf";
2186*35238bceSAndroid Build Coastguard Worker                 float rangeSizeRatio  = isEntireRange ? 1.0f : 0.5f;
2187*35238bceSAndroid Build Coastguard Worker 
2188*35238bceSAndroid Build Coastguard Worker #define LOG_TIME(NAME, DESC, DATA)                                                                               \
2189*35238bceSAndroid Build Coastguard Worker     log << TestLog::Float(statNamePrefix + (NAME) + singular, singular + " of " + (DESC), "ms", QP_KEY_TAG_TIME, \
2190*35238bceSAndroid Build Coastguard Worker                           func(vectorLowestPercentage((DATA), rangeSizeRatio)) / 1000.0f)
2191*35238bceSAndroid Build Coastguard Worker 
2192*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
2193*35238bceSAndroid Build Coastguard Worker                     << (isEntireRange ? "For all measurements:" : "\nFor only the lowest 50% of the measurements:")
2194*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
2195*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("ShaderSourceSetTime", "shader source set time", sourceSetTimes);
2196*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("VertexShaderCompileTime", "vertex shader compile time", vertexCompileTimes);
2197*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("FragmentShaderCompileTime", "fragment shader compile time", fragmentCompileTimes);
2198*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("ProgramLinkTime", "program link time", programLinkTimes);
2199*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("FirstShaderInputSetTime", "first shader input set time", firstInputSetTimes);
2200*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("FirstDrawTime", "first draw time", firstDrawTimes);
2201*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("SecondShaderInputSetTime", "second shader input set time", secondInputTimes);
2202*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("SecondDrawTime", "second draw time", secondDrawTimes);
2203*35238bceSAndroid Build Coastguard Worker 
2204*35238bceSAndroid Build Coastguard Worker #undef LOG_TIME
2205*35238bceSAndroid Build Coastguard Worker             }
2206*35238bceSAndroid Build Coastguard Worker 
2207*35238bceSAndroid Build Coastguard Worker             log << TestLog::EndSection;
2208*35238bceSAndroid Build Coastguard Worker         }
2209*35238bceSAndroid Build Coastguard Worker 
2210*35238bceSAndroid Build Coastguard Worker         // Set result.
2211*35238bceSAndroid Build Coastguard Worker 
2212*35238bceSAndroid Build Coastguard Worker         {
2213*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message
2214*35238bceSAndroid Build Coastguard Worker                 << "Note: test result is the first quartile (i.e. median of the lowest half of measurements) of "
2215*35238bceSAndroid Build Coastguard Worker                    "compilation times"
2216*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
2217*35238bceSAndroid Build Coastguard Worker             float result = vectorFloatFirstQuartile(totalTimesWithoutDraw) / 1000.0f;
2218*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
2219*35238bceSAndroid Build Coastguard Worker         }
2220*35238bceSAndroid Build Coastguard Worker 
2221*35238bceSAndroid Build Coastguard Worker         // Log shaders.
2222*35238bceSAndroid Build Coastguard Worker 
2223*35238bceSAndroid Build Coastguard Worker         if (m_avoidCache || m_addWhitespaceAndComments)
2224*35238bceSAndroid Build Coastguard Worker         {
2225*35238bceSAndroid Build Coastguard Worker             string msg = "Note: the following shaders are the ones from the last iteration; ";
2226*35238bceSAndroid Build Coastguard Worker 
2227*35238bceSAndroid Build Coastguard Worker             if (m_avoidCache)
2228*35238bceSAndroid Build Coastguard Worker                 msg += "variables' names and some constant expressions";
2229*35238bceSAndroid Build Coastguard Worker             if (m_addWhitespaceAndComments)
2230*35238bceSAndroid Build Coastguard Worker                 msg += string(m_avoidCache ? " as well as " : "") + "whitespace and comments";
2231*35238bceSAndroid Build Coastguard Worker 
2232*35238bceSAndroid Build Coastguard Worker             msg += " differ between iterations.";
2233*35238bceSAndroid Build Coastguard Worker 
2234*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << msg.c_str() << TestLog::EndMessage;
2235*35238bceSAndroid Build Coastguard Worker         }
2236*35238bceSAndroid Build Coastguard Worker 
2237*35238bceSAndroid Build Coastguard Worker         logProgramData(latestBuildInfo, latestProgramContext);
2238*35238bceSAndroid Build Coastguard Worker 
2239*35238bceSAndroid Build Coastguard Worker         return STOP;
2240*35238bceSAndroid Build Coastguard Worker     }
2241*35238bceSAndroid Build Coastguard Worker }
2242*35238bceSAndroid Build Coastguard Worker 
ShaderCompilerLightCase(Context & context,const char * name,const char * description,int caseID,bool avoidCache,bool addWhitespaceAndComments,bool isVertexCase,int numLights,LightType lightType)2243*35238bceSAndroid Build Coastguard Worker ShaderCompilerLightCase::ShaderCompilerLightCase(Context &context, const char *name, const char *description,
2244*35238bceSAndroid Build Coastguard Worker                                                  int caseID, bool avoidCache, bool addWhitespaceAndComments,
2245*35238bceSAndroid Build Coastguard Worker                                                  bool isVertexCase, int numLights, LightType lightType)
2246*35238bceSAndroid Build Coastguard Worker     : ShaderCompilerCase(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
2247*35238bceSAndroid Build Coastguard Worker     , m_numLights(numLights)
2248*35238bceSAndroid Build Coastguard Worker     , m_isVertexCase(isVertexCase)
2249*35238bceSAndroid Build Coastguard Worker     , m_lightType(lightType)
2250*35238bceSAndroid Build Coastguard Worker     , m_texture(DE_NULL)
2251*35238bceSAndroid Build Coastguard Worker {
2252*35238bceSAndroid Build Coastguard Worker }
2253*35238bceSAndroid Build Coastguard Worker 
~ShaderCompilerLightCase(void)2254*35238bceSAndroid Build Coastguard Worker ShaderCompilerLightCase::~ShaderCompilerLightCase(void)
2255*35238bceSAndroid Build Coastguard Worker {
2256*35238bceSAndroid Build Coastguard Worker     ShaderCompilerLightCase::deinit();
2257*35238bceSAndroid Build Coastguard Worker }
2258*35238bceSAndroid Build Coastguard Worker 
deinit(void)2259*35238bceSAndroid Build Coastguard Worker void ShaderCompilerLightCase::deinit(void)
2260*35238bceSAndroid Build Coastguard Worker {
2261*35238bceSAndroid Build Coastguard Worker     delete m_texture;
2262*35238bceSAndroid Build Coastguard Worker     m_texture = DE_NULL;
2263*35238bceSAndroid Build Coastguard Worker }
2264*35238bceSAndroid Build Coastguard Worker 
init(void)2265*35238bceSAndroid Build Coastguard Worker void ShaderCompilerLightCase::init(void)
2266*35238bceSAndroid Build Coastguard Worker {
2267*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2268*35238bceSAndroid Build Coastguard Worker 
2269*35238bceSAndroid Build Coastguard Worker     // Setup texture.
2270*35238bceSAndroid Build Coastguard Worker 
2271*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_texture == DE_NULL);
2272*35238bceSAndroid Build Coastguard Worker 
2273*35238bceSAndroid Build Coastguard Worker     m_texture =
2274*35238bceSAndroid Build Coastguard Worker         new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, TEXTURE_WIDTH, TEXTURE_HEIGHT);
2275*35238bceSAndroid Build Coastguard Worker 
2276*35238bceSAndroid Build Coastguard Worker     tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
2277*35238bceSAndroid Build Coastguard Worker 
2278*35238bceSAndroid Build Coastguard Worker     m_texture->getRefTexture().allocLevel(0);
2279*35238bceSAndroid Build Coastguard Worker     tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), fmtInfo.valueMin, fmtInfo.valueMax);
2280*35238bceSAndroid Build Coastguard Worker 
2281*35238bceSAndroid Build Coastguard Worker     gl.activeTexture(GL_TEXTURE0);
2282*35238bceSAndroid Build Coastguard Worker     gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
2283*35238bceSAndroid Build Coastguard Worker     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2284*35238bceSAndroid Build Coastguard Worker     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2285*35238bceSAndroid Build Coastguard Worker     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2286*35238bceSAndroid Build Coastguard Worker     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2287*35238bceSAndroid Build Coastguard Worker     m_texture->upload();
2288*35238bceSAndroid Build Coastguard Worker 
2289*35238bceSAndroid Build Coastguard Worker     ShaderCompilerCase::init();
2290*35238bceSAndroid Build Coastguard Worker }
2291*35238bceSAndroid Build Coastguard Worker 
generateShaderData(int measurementNdx) const2292*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::ProgramContext ShaderCompilerLightCase::generateShaderData(int measurementNdx) const
2293*35238bceSAndroid Build Coastguard Worker {
2294*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2295*35238bceSAndroid Build Coastguard Worker     string nameSpec = getNameSpecialization(specID);
2296*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2297*35238bceSAndroid Build Coastguard Worker 
2298*35238bceSAndroid Build Coastguard Worker     result.vertShaderSource = specializeShaderSource(lightVertexTemplate(m_numLights, m_isVertexCase, m_lightType),
2299*35238bceSAndroid Build Coastguard Worker                                                      specID, SHADER_VALIDITY_VALID);
2300*35238bceSAndroid Build Coastguard Worker     result.fragShaderSource = specializeShaderSource(lightFragmentTemplate(m_numLights, m_isVertexCase, m_lightType),
2301*35238bceSAndroid Build Coastguard Worker                                                      specID, SHADER_VALIDITY_VALID);
2302*35238bceSAndroid Build Coastguard Worker     result.vertexAttributes = lightShaderAttributes(nameSpec);
2303*35238bceSAndroid Build Coastguard Worker     result.uniforms         = lightShaderUniforms(nameSpec, m_numLights, m_lightType);
2304*35238bceSAndroid Build Coastguard Worker 
2305*35238bceSAndroid Build Coastguard Worker     return result;
2306*35238bceSAndroid Build Coastguard Worker }
2307*35238bceSAndroid Build Coastguard Worker 
ShaderCompilerTextureCase(Context & context,const char * name,const char * description,int caseID,bool avoidCache,bool addWhitespaceAndComments,int numLookups,ConditionalUsage conditionalUsage,ConditionalType conditionalType)2308*35238bceSAndroid Build Coastguard Worker ShaderCompilerTextureCase::ShaderCompilerTextureCase(Context &context, const char *name, const char *description,
2309*35238bceSAndroid Build Coastguard Worker                                                      int caseID, bool avoidCache, bool addWhitespaceAndComments,
2310*35238bceSAndroid Build Coastguard Worker                                                      int numLookups, ConditionalUsage conditionalUsage,
2311*35238bceSAndroid Build Coastguard Worker                                                      ConditionalType conditionalType)
2312*35238bceSAndroid Build Coastguard Worker     : ShaderCompilerCase(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
2313*35238bceSAndroid Build Coastguard Worker     , m_numLookups(numLookups)
2314*35238bceSAndroid Build Coastguard Worker     , m_conditionalUsage(conditionalUsage)
2315*35238bceSAndroid Build Coastguard Worker     , m_conditionalType(conditionalType)
2316*35238bceSAndroid Build Coastguard Worker {
2317*35238bceSAndroid Build Coastguard Worker }
2318*35238bceSAndroid Build Coastguard Worker 
~ShaderCompilerTextureCase(void)2319*35238bceSAndroid Build Coastguard Worker ShaderCompilerTextureCase::~ShaderCompilerTextureCase(void)
2320*35238bceSAndroid Build Coastguard Worker {
2321*35238bceSAndroid Build Coastguard Worker     ShaderCompilerTextureCase::deinit();
2322*35238bceSAndroid Build Coastguard Worker }
2323*35238bceSAndroid Build Coastguard Worker 
deinit(void)2324*35238bceSAndroid Build Coastguard Worker void ShaderCompilerTextureCase::deinit(void)
2325*35238bceSAndroid Build Coastguard Worker {
2326*35238bceSAndroid Build Coastguard Worker     for (vector<glu::Texture2D *>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
2327*35238bceSAndroid Build Coastguard Worker         delete *i;
2328*35238bceSAndroid Build Coastguard Worker     m_textures.clear();
2329*35238bceSAndroid Build Coastguard Worker }
2330*35238bceSAndroid Build Coastguard Worker 
init(void)2331*35238bceSAndroid Build Coastguard Worker void ShaderCompilerTextureCase::init(void)
2332*35238bceSAndroid Build Coastguard Worker {
2333*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2334*35238bceSAndroid Build Coastguard Worker 
2335*35238bceSAndroid Build Coastguard Worker     // Setup texture.
2336*35238bceSAndroid Build Coastguard Worker 
2337*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_textures.empty());
2338*35238bceSAndroid Build Coastguard Worker 
2339*35238bceSAndroid Build Coastguard Worker     m_textures.reserve(m_numLookups);
2340*35238bceSAndroid Build Coastguard Worker 
2341*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < m_numLookups; i++)
2342*35238bceSAndroid Build Coastguard Worker     {
2343*35238bceSAndroid Build Coastguard Worker         glu::Texture2D *tex =
2344*35238bceSAndroid Build Coastguard Worker             new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, TEXTURE_WIDTH, TEXTURE_HEIGHT);
2345*35238bceSAndroid Build Coastguard Worker         tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(tex->getRefTexture().getFormat());
2346*35238bceSAndroid Build Coastguard Worker 
2347*35238bceSAndroid Build Coastguard Worker         tex->getRefTexture().allocLevel(0);
2348*35238bceSAndroid Build Coastguard Worker         tcu::fillWithComponentGradients(tex->getRefTexture().getLevel(0), fmtInfo.valueMin, fmtInfo.valueMax);
2349*35238bceSAndroid Build Coastguard Worker 
2350*35238bceSAndroid Build Coastguard Worker         gl.activeTexture(GL_TEXTURE0 + i);
2351*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D, tex->getGLTexture());
2352*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2353*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2354*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2355*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2356*35238bceSAndroid Build Coastguard Worker         tex->upload();
2357*35238bceSAndroid Build Coastguard Worker 
2358*35238bceSAndroid Build Coastguard Worker         m_textures.push_back(tex);
2359*35238bceSAndroid Build Coastguard Worker     }
2360*35238bceSAndroid Build Coastguard Worker 
2361*35238bceSAndroid Build Coastguard Worker     ShaderCompilerCase::init();
2362*35238bceSAndroid Build Coastguard Worker }
2363*35238bceSAndroid Build Coastguard Worker 
generateShaderData(int measurementNdx) const2364*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::ProgramContext ShaderCompilerTextureCase::generateShaderData(int measurementNdx) const
2365*35238bceSAndroid Build Coastguard Worker {
2366*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2367*35238bceSAndroid Build Coastguard Worker     string nameSpec = getNameSpecialization(specID);
2368*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2369*35238bceSAndroid Build Coastguard Worker 
2370*35238bceSAndroid Build Coastguard Worker     result.vertShaderSource = specializeShaderSource(textureLookupVertexTemplate(m_conditionalUsage, m_conditionalType),
2371*35238bceSAndroid Build Coastguard Worker                                                      specID, SHADER_VALIDITY_VALID);
2372*35238bceSAndroid Build Coastguard Worker     result.fragShaderSource =
2373*35238bceSAndroid Build Coastguard Worker         specializeShaderSource(textureLookupFragmentTemplate(m_numLookups, m_conditionalUsage, m_conditionalType),
2374*35238bceSAndroid Build Coastguard Worker                                specID, SHADER_VALIDITY_VALID);
2375*35238bceSAndroid Build Coastguard Worker     result.vertexAttributes = textureLookupShaderAttributes(nameSpec, m_conditionalUsage, m_conditionalType);
2376*35238bceSAndroid Build Coastguard Worker     result.uniforms = textureLookupShaderUniforms(nameSpec, m_numLookups, m_conditionalUsage, m_conditionalType);
2377*35238bceSAndroid Build Coastguard Worker 
2378*35238bceSAndroid Build Coastguard Worker     return result;
2379*35238bceSAndroid Build Coastguard Worker }
2380*35238bceSAndroid Build Coastguard Worker 
ShaderCompilerLoopCase(Context & context,const char * name,const char * description,int caseID,bool avoidCache,bool addWhitespaceAndComments,bool isVertexCase,LoopType type,int numLoopIterations,int nestingDepth)2381*35238bceSAndroid Build Coastguard Worker ShaderCompilerLoopCase::ShaderCompilerLoopCase(Context &context, const char *name, const char *description, int caseID,
2382*35238bceSAndroid Build Coastguard Worker                                                bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase,
2383*35238bceSAndroid Build Coastguard Worker                                                LoopType type, int numLoopIterations, int nestingDepth)
2384*35238bceSAndroid Build Coastguard Worker     : ShaderCompilerCase(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
2385*35238bceSAndroid Build Coastguard Worker     , m_numLoopIterations(numLoopIterations)
2386*35238bceSAndroid Build Coastguard Worker     , m_nestingDepth(nestingDepth)
2387*35238bceSAndroid Build Coastguard Worker     , m_isVertexCase(isVertexCase)
2388*35238bceSAndroid Build Coastguard Worker     , m_type(type)
2389*35238bceSAndroid Build Coastguard Worker {
2390*35238bceSAndroid Build Coastguard Worker }
2391*35238bceSAndroid Build Coastguard Worker 
~ShaderCompilerLoopCase(void)2392*35238bceSAndroid Build Coastguard Worker ShaderCompilerLoopCase::~ShaderCompilerLoopCase(void)
2393*35238bceSAndroid Build Coastguard Worker {
2394*35238bceSAndroid Build Coastguard Worker }
2395*35238bceSAndroid Build Coastguard Worker 
generateShaderData(int measurementNdx) const2396*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::ProgramContext ShaderCompilerLoopCase::generateShaderData(int measurementNdx) const
2397*35238bceSAndroid Build Coastguard Worker {
2398*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2399*35238bceSAndroid Build Coastguard Worker     string nameSpec = getNameSpecialization(specID);
2400*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2401*35238bceSAndroid Build Coastguard Worker 
2402*35238bceSAndroid Build Coastguard Worker     result.vertShaderSource = specializeShaderSource(
2403*35238bceSAndroid Build Coastguard Worker         loopVertexTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, SHADER_VALIDITY_VALID);
2404*35238bceSAndroid Build Coastguard Worker     result.fragShaderSource =
2405*35238bceSAndroid Build Coastguard Worker         specializeShaderSource(loopFragmentTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth),
2406*35238bceSAndroid Build Coastguard Worker                                specID, SHADER_VALIDITY_VALID);
2407*35238bceSAndroid Build Coastguard Worker 
2408*35238bceSAndroid Build Coastguard Worker     result.vertexAttributes = loopShaderAttributes(nameSpec, m_type, m_numLoopIterations);
2409*35238bceSAndroid Build Coastguard Worker     result.uniforms         = loopShaderUniforms(nameSpec, m_type, m_numLoopIterations);
2410*35238bceSAndroid Build Coastguard Worker 
2411*35238bceSAndroid Build Coastguard Worker     return result;
2412*35238bceSAndroid Build Coastguard Worker }
2413*35238bceSAndroid Build Coastguard Worker 
ShaderCompilerOperCase(Context & context,const char * name,const char * description,int caseID,bool avoidCache,bool addWhitespaceAndComments,bool isVertexCase,const char * oper,int numOperations)2414*35238bceSAndroid Build Coastguard Worker ShaderCompilerOperCase::ShaderCompilerOperCase(Context &context, const char *name, const char *description, int caseID,
2415*35238bceSAndroid Build Coastguard Worker                                                bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase,
2416*35238bceSAndroid Build Coastguard Worker                                                const char *oper, int numOperations)
2417*35238bceSAndroid Build Coastguard Worker     : ShaderCompilerCase(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
2418*35238bceSAndroid Build Coastguard Worker     , m_oper(oper)
2419*35238bceSAndroid Build Coastguard Worker     , m_numOperations(numOperations)
2420*35238bceSAndroid Build Coastguard Worker     , m_isVertexCase(isVertexCase)
2421*35238bceSAndroid Build Coastguard Worker {
2422*35238bceSAndroid Build Coastguard Worker }
2423*35238bceSAndroid Build Coastguard Worker 
~ShaderCompilerOperCase(void)2424*35238bceSAndroid Build Coastguard Worker ShaderCompilerOperCase::~ShaderCompilerOperCase(void)
2425*35238bceSAndroid Build Coastguard Worker {
2426*35238bceSAndroid Build Coastguard Worker }
2427*35238bceSAndroid Build Coastguard Worker 
generateShaderData(int measurementNdx) const2428*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::ProgramContext ShaderCompilerOperCase::generateShaderData(int measurementNdx) const
2429*35238bceSAndroid Build Coastguard Worker {
2430*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2431*35238bceSAndroid Build Coastguard Worker     string nameSpec = getNameSpecialization(specID);
2432*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2433*35238bceSAndroid Build Coastguard Worker 
2434*35238bceSAndroid Build Coastguard Worker     if (m_isVertexCase)
2435*35238bceSAndroid Build Coastguard Worker     {
2436*35238bceSAndroid Build Coastguard Worker         result.vertShaderSource = specializeShaderSource(binaryOpVertexTemplate(m_numOperations, m_oper.c_str()),
2437*35238bceSAndroid Build Coastguard Worker                                                          specID, SHADER_VALIDITY_VALID);
2438*35238bceSAndroid Build Coastguard Worker         result.fragShaderSource =
2439*35238bceSAndroid Build Coastguard Worker             specializeShaderSource(singleVaryingFragmentTemplate(), specID, SHADER_VALIDITY_VALID);
2440*35238bceSAndroid Build Coastguard Worker     }
2441*35238bceSAndroid Build Coastguard Worker     else
2442*35238bceSAndroid Build Coastguard Worker     {
2443*35238bceSAndroid Build Coastguard Worker         result.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, SHADER_VALIDITY_VALID);
2444*35238bceSAndroid Build Coastguard Worker         result.fragShaderSource = specializeShaderSource(binaryOpFragmentTemplate(m_numOperations, m_oper.c_str()),
2445*35238bceSAndroid Build Coastguard Worker                                                          specID, SHADER_VALIDITY_VALID);
2446*35238bceSAndroid Build Coastguard Worker     }
2447*35238bceSAndroid Build Coastguard Worker 
2448*35238bceSAndroid Build Coastguard Worker     result.vertexAttributes = singleValueShaderAttributes(nameSpec);
2449*35238bceSAndroid Build Coastguard Worker 
2450*35238bceSAndroid Build Coastguard Worker     result.uniforms.clear(); // No uniforms used.
2451*35238bceSAndroid Build Coastguard Worker 
2452*35238bceSAndroid Build Coastguard Worker     return result;
2453*35238bceSAndroid Build Coastguard Worker }
2454*35238bceSAndroid Build Coastguard Worker 
ShaderCompilerMandelbrotCase(Context & context,const char * name,const char * description,int caseID,bool avoidCache,bool addWhitespaceAndComments,int numFractalIterations)2455*35238bceSAndroid Build Coastguard Worker ShaderCompilerMandelbrotCase::ShaderCompilerMandelbrotCase(Context &context, const char *name, const char *description,
2456*35238bceSAndroid Build Coastguard Worker                                                            int caseID, bool avoidCache, bool addWhitespaceAndComments,
2457*35238bceSAndroid Build Coastguard Worker                                                            int numFractalIterations)
2458*35238bceSAndroid Build Coastguard Worker     : ShaderCompilerCase(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
2459*35238bceSAndroid Build Coastguard Worker     , m_numFractalIterations(numFractalIterations)
2460*35238bceSAndroid Build Coastguard Worker {
2461*35238bceSAndroid Build Coastguard Worker }
2462*35238bceSAndroid Build Coastguard Worker 
~ShaderCompilerMandelbrotCase(void)2463*35238bceSAndroid Build Coastguard Worker ShaderCompilerMandelbrotCase::~ShaderCompilerMandelbrotCase(void)
2464*35238bceSAndroid Build Coastguard Worker {
2465*35238bceSAndroid Build Coastguard Worker }
2466*35238bceSAndroid Build Coastguard Worker 
generateShaderData(int measurementNdx) const2467*35238bceSAndroid Build Coastguard Worker ShaderCompilerCase::ProgramContext ShaderCompilerMandelbrotCase::generateShaderData(int measurementNdx) const
2468*35238bceSAndroid Build Coastguard Worker {
2469*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2470*35238bceSAndroid Build Coastguard Worker     string nameSpec = getNameSpecialization(specID);
2471*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2472*35238bceSAndroid Build Coastguard Worker 
2473*35238bceSAndroid Build Coastguard Worker     result.vertShaderSource = specializeShaderSource(mandelbrotVertexTemplate(), specID, SHADER_VALIDITY_VALID);
2474*35238bceSAndroid Build Coastguard Worker     result.fragShaderSource =
2475*35238bceSAndroid Build Coastguard Worker         specializeShaderSource(mandelbrotFragmentTemplate(m_numFractalIterations), specID, SHADER_VALIDITY_VALID);
2476*35238bceSAndroid Build Coastguard Worker 
2477*35238bceSAndroid Build Coastguard Worker     result.vertexAttributes = mandelbrotShaderAttributes(nameSpec);
2478*35238bceSAndroid Build Coastguard Worker     result.uniforms         = mandelbrotShaderUniforms(nameSpec);
2479*35238bceSAndroid Build Coastguard Worker 
2480*35238bceSAndroid Build Coastguard Worker     return result;
2481*35238bceSAndroid Build Coastguard Worker }
2482*35238bceSAndroid Build Coastguard Worker 
InvalidShaderCompilerCase(Context & context,const char * name,const char * description,int caseID,InvalidityType invalidityType)2483*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::InvalidShaderCompilerCase(Context &context, const char *name, const char *description,
2484*35238bceSAndroid Build Coastguard Worker                                                      int caseID, InvalidityType invalidityType)
2485*35238bceSAndroid Build Coastguard Worker     : TestCase(context, tcu::NODETYPE_PERFORMANCE, name, description)
2486*35238bceSAndroid Build Coastguard Worker     , m_invalidityType(invalidityType)
2487*35238bceSAndroid Build Coastguard Worker     , m_startHash((uint32_t)(deUint64Hash(deGetTime()) ^ deUint64Hash(deGetMicroseconds()) ^ deInt32Hash(caseID)))
2488*35238bceSAndroid Build Coastguard Worker {
2489*35238bceSAndroid Build Coastguard Worker     int cmdLineIterCount      = context.getTestContext().getCommandLine().getTestIterationCount();
2490*35238bceSAndroid Build Coastguard Worker     m_minimumMeasurementCount = cmdLineIterCount > 0 ? cmdLineIterCount : DEFAULT_MINIMUM_MEASUREMENT_COUNT;
2491*35238bceSAndroid Build Coastguard Worker     m_maximumMeasurementCount = 3 * m_minimumMeasurementCount;
2492*35238bceSAndroid Build Coastguard Worker }
2493*35238bceSAndroid Build Coastguard Worker 
~InvalidShaderCompilerCase(void)2494*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::~InvalidShaderCompilerCase(void)
2495*35238bceSAndroid Build Coastguard Worker {
2496*35238bceSAndroid Build Coastguard Worker }
2497*35238bceSAndroid Build Coastguard Worker 
getSpecializationID(int measurementNdx) const2498*35238bceSAndroid Build Coastguard Worker uint32_t InvalidShaderCompilerCase::getSpecializationID(int measurementNdx) const
2499*35238bceSAndroid Build Coastguard Worker {
2500*35238bceSAndroid Build Coastguard Worker     return m_startHash ^ (uint32_t)deInt32Hash((int32_t)measurementNdx);
2501*35238bceSAndroid Build Coastguard Worker }
2502*35238bceSAndroid Build Coastguard Worker 
createShaders(void) const2503*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::Shaders InvalidShaderCompilerCase::createShaders(void) const
2504*35238bceSAndroid Build Coastguard Worker {
2505*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2506*35238bceSAndroid Build Coastguard Worker     Shaders result;
2507*35238bceSAndroid Build Coastguard Worker 
2508*35238bceSAndroid Build Coastguard Worker     result.vertShader = gl.createShader(GL_VERTEX_SHADER);
2509*35238bceSAndroid Build Coastguard Worker     result.fragShader = gl.createShader(GL_FRAGMENT_SHADER);
2510*35238bceSAndroid Build Coastguard Worker 
2511*35238bceSAndroid Build Coastguard Worker     return result;
2512*35238bceSAndroid Build Coastguard Worker }
2513*35238bceSAndroid Build Coastguard Worker 
setShaderSources(const Shaders & shaders,const ProgramContext & progCtx) const2514*35238bceSAndroid Build Coastguard Worker void InvalidShaderCompilerCase::setShaderSources(const Shaders &shaders, const ProgramContext &progCtx) const
2515*35238bceSAndroid Build Coastguard Worker {
2516*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl         = m_context.getRenderContext().getFunctions();
2517*35238bceSAndroid Build Coastguard Worker     const char *vertShaderSourceCStr = progCtx.vertShaderSource.c_str();
2518*35238bceSAndroid Build Coastguard Worker     const char *fragShaderSourceCStr = progCtx.fragShaderSource.c_str();
2519*35238bceSAndroid Build Coastguard Worker     gl.shaderSource(shaders.vertShader, 1, &vertShaderSourceCStr, DE_NULL);
2520*35238bceSAndroid Build Coastguard Worker     gl.shaderSource(shaders.fragShader, 1, &fragShaderSourceCStr, DE_NULL);
2521*35238bceSAndroid Build Coastguard Worker }
2522*35238bceSAndroid Build Coastguard Worker 
compileShader(uint32_t shader) const2523*35238bceSAndroid Build Coastguard Worker bool InvalidShaderCompilerCase::compileShader(uint32_t shader) const
2524*35238bceSAndroid Build Coastguard Worker {
2525*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2526*35238bceSAndroid Build Coastguard Worker     GLint status;
2527*35238bceSAndroid Build Coastguard Worker     gl.compileShader(shader);
2528*35238bceSAndroid Build Coastguard Worker     gl.getShaderiv(shader, GL_COMPILE_STATUS, &status);
2529*35238bceSAndroid Build Coastguard Worker     return status != 0;
2530*35238bceSAndroid Build Coastguard Worker }
2531*35238bceSAndroid Build Coastguard Worker 
logProgramData(const BuildInfo & buildInfo,const ProgramContext & progCtx) const2532*35238bceSAndroid Build Coastguard Worker void InvalidShaderCompilerCase::logProgramData(const BuildInfo &buildInfo, const ProgramContext &progCtx) const
2533*35238bceSAndroid Build Coastguard Worker {
2534*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << TestLog::ShaderProgram(false, "(No linking done)")
2535*35238bceSAndroid Build Coastguard Worker                        << TestLog::Shader(QP_SHADER_TYPE_VERTEX, progCtx.vertShaderSource, buildInfo.vertCompileSuccess,
2536*35238bceSAndroid Build Coastguard Worker                                           buildInfo.logs.vert)
2537*35238bceSAndroid Build Coastguard Worker                        << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT, progCtx.fragShaderSource,
2538*35238bceSAndroid Build Coastguard Worker                                           buildInfo.fragCompileSuccess, buildInfo.logs.frag)
2539*35238bceSAndroid Build Coastguard Worker                        << TestLog::EndShaderProgram;
2540*35238bceSAndroid Build Coastguard Worker }
2541*35238bceSAndroid Build Coastguard Worker 
getLogs(const Shaders & shaders) const2542*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::Logs InvalidShaderCompilerCase::getLogs(const Shaders &shaders) const
2543*35238bceSAndroid Build Coastguard Worker {
2544*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2545*35238bceSAndroid Build Coastguard Worker     Logs result;
2546*35238bceSAndroid Build Coastguard Worker 
2547*35238bceSAndroid Build Coastguard Worker     result.vert = getShaderInfoLog(gl, shaders.vertShader);
2548*35238bceSAndroid Build Coastguard Worker     result.frag = getShaderInfoLog(gl, shaders.fragShader);
2549*35238bceSAndroid Build Coastguard Worker 
2550*35238bceSAndroid Build Coastguard Worker     return result;
2551*35238bceSAndroid Build Coastguard Worker }
2552*35238bceSAndroid Build Coastguard Worker 
cleanup(const Shaders & shaders) const2553*35238bceSAndroid Build Coastguard Worker void InvalidShaderCompilerCase::cleanup(const Shaders &shaders) const
2554*35238bceSAndroid Build Coastguard Worker {
2555*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2556*35238bceSAndroid Build Coastguard Worker 
2557*35238bceSAndroid Build Coastguard Worker     gl.deleteShader(shaders.vertShader);
2558*35238bceSAndroid Build Coastguard Worker     gl.deleteShader(shaders.fragShader);
2559*35238bceSAndroid Build Coastguard Worker }
2560*35238bceSAndroid Build Coastguard Worker 
goodEnoughMeasurements(const vector<Measurement> & measurements) const2561*35238bceSAndroid Build Coastguard Worker bool InvalidShaderCompilerCase::goodEnoughMeasurements(const vector<Measurement> &measurements) const
2562*35238bceSAndroid Build Coastguard Worker {
2563*35238bceSAndroid Build Coastguard Worker     if ((int)measurements.size() < m_minimumMeasurementCount)
2564*35238bceSAndroid Build Coastguard Worker         return false;
2565*35238bceSAndroid Build Coastguard Worker     else
2566*35238bceSAndroid Build Coastguard Worker     {
2567*35238bceSAndroid Build Coastguard Worker         if ((int)measurements.size() >= m_maximumMeasurementCount)
2568*35238bceSAndroid Build Coastguard Worker             return true;
2569*35238bceSAndroid Build Coastguard Worker         else
2570*35238bceSAndroid Build Coastguard Worker         {
2571*35238bceSAndroid Build Coastguard Worker             vector<int64_t> totalTimes;
2572*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < (int)measurements.size(); i++)
2573*35238bceSAndroid Build Coastguard Worker                 totalTimes.push_back(measurements[i].totalTime());
2574*35238bceSAndroid Build Coastguard Worker             return vectorFloatRelativeMedianAbsoluteDeviation(vectorLowestPercentage(totalTimes, 0.5f)) <
2575*35238bceSAndroid Build Coastguard Worker                    RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD;
2576*35238bceSAndroid Build Coastguard Worker         }
2577*35238bceSAndroid Build Coastguard Worker     }
2578*35238bceSAndroid Build Coastguard Worker }
2579*35238bceSAndroid Build Coastguard Worker 
iterate(void)2580*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::IterateResult InvalidShaderCompilerCase::iterate(void)
2581*35238bceSAndroid Build Coastguard Worker {
2582*35238bceSAndroid Build Coastguard Worker     ShaderValidity shaderValidity = m_invalidityType == INVALIDITY_INVALID_CHAR   ? SHADER_VALIDITY_INVALID_CHAR :
2583*35238bceSAndroid Build Coastguard Worker                                     m_invalidityType == INVALIDITY_SEMANTIC_ERROR ? SHADER_VALIDITY_SEMANTIC_ERROR :
2584*35238bceSAndroid Build Coastguard Worker                                                                                     SHADER_VALIDITY_LAST;
2585*35238bceSAndroid Build Coastguard Worker 
2586*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
2587*35238bceSAndroid Build Coastguard Worker 
2588*35238bceSAndroid Build Coastguard Worker     // Before actual measurements, compile a minimal shader to avoid possible initial slowdowns in the actual test.
2589*35238bceSAndroid Build Coastguard Worker     {
2590*35238bceSAndroid Build Coastguard Worker         uint32_t specID = getSpecializationID(0);
2591*35238bceSAndroid Build Coastguard Worker         ProgramContext progCtx;
2592*35238bceSAndroid Build Coastguard Worker         progCtx.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, shaderValidity);
2593*35238bceSAndroid Build Coastguard Worker         progCtx.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, shaderValidity);
2594*35238bceSAndroid Build Coastguard Worker 
2595*35238bceSAndroid Build Coastguard Worker         Shaders shaders = createShaders();
2596*35238bceSAndroid Build Coastguard Worker         setShaderSources(shaders, progCtx);
2597*35238bceSAndroid Build Coastguard Worker 
2598*35238bceSAndroid Build Coastguard Worker         BuildInfo buildInfo;
2599*35238bceSAndroid Build Coastguard Worker         buildInfo.vertCompileSuccess = compileShader(shaders.vertShader);
2600*35238bceSAndroid Build Coastguard Worker         buildInfo.fragCompileSuccess = compileShader(shaders.fragShader);
2601*35238bceSAndroid Build Coastguard Worker         if (buildInfo.vertCompileSuccess || buildInfo.fragCompileSuccess)
2602*35238bceSAndroid Build Coastguard Worker         {
2603*35238bceSAndroid Build Coastguard Worker             buildInfo.logs = getLogs(shaders);
2604*35238bceSAndroid Build Coastguard Worker             logProgramData(buildInfo, progCtx);
2605*35238bceSAndroid Build Coastguard Worker             cleanup(shaders);
2606*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of a shader erroneously succeeded");
2607*35238bceSAndroid Build Coastguard Worker             return STOP;
2608*35238bceSAndroid Build Coastguard Worker         }
2609*35238bceSAndroid Build Coastguard Worker         cleanup(shaders);
2610*35238bceSAndroid Build Coastguard Worker     }
2611*35238bceSAndroid Build Coastguard Worker 
2612*35238bceSAndroid Build Coastguard Worker     vector<Measurement> measurements;
2613*35238bceSAndroid Build Coastguard Worker     // \note These are logged after measurements are done.
2614*35238bceSAndroid Build Coastguard Worker     ProgramContext latestProgramContext;
2615*35238bceSAndroid Build Coastguard Worker     BuildInfo latestBuildInfo;
2616*35238bceSAndroid Build Coastguard Worker 
2617*35238bceSAndroid Build Coastguard Worker     if (WARMUP_CPU_AT_BEGINNING_OF_CASE)
2618*35238bceSAndroid Build Coastguard Worker         tcu::warmupCPU();
2619*35238bceSAndroid Build Coastguard Worker 
2620*35238bceSAndroid Build Coastguard Worker     // Actual test measurements.
2621*35238bceSAndroid Build Coastguard Worker     while (!goodEnoughMeasurements(measurements))
2622*35238bceSAndroid Build Coastguard Worker     {
2623*35238bceSAndroid Build Coastguard Worker         // Create shader and compile. Measure time.
2624*35238bceSAndroid Build Coastguard Worker 
2625*35238bceSAndroid Build Coastguard Worker         // \note Shader sources are generated and GL shader objects are created before any time measurements.
2626*35238bceSAndroid Build Coastguard Worker         ProgramContext progCtx = generateShaderSources((int)measurements.size());
2627*35238bceSAndroid Build Coastguard Worker         Shaders shaders        = createShaders();
2628*35238bceSAndroid Build Coastguard Worker         BuildInfo buildInfo;
2629*35238bceSAndroid Build Coastguard Worker 
2630*35238bceSAndroid Build Coastguard Worker         if (WARMUP_CPU_BEFORE_EACH_MEASUREMENT)
2631*35238bceSAndroid Build Coastguard Worker             tcu::warmupCPU();
2632*35238bceSAndroid Build Coastguard Worker 
2633*35238bceSAndroid Build Coastguard Worker         // \note Do NOT do anything too hefty between the first and last deGetMicroseconds() here (other than the gl calls); it would disturb the measurement.
2634*35238bceSAndroid Build Coastguard Worker 
2635*35238bceSAndroid Build Coastguard Worker         uint64_t startTime = deGetMicroseconds();
2636*35238bceSAndroid Build Coastguard Worker 
2637*35238bceSAndroid Build Coastguard Worker         setShaderSources(shaders, progCtx);
2638*35238bceSAndroid Build Coastguard Worker         uint64_t shaderSourceSetEndTime = deGetMicroseconds();
2639*35238bceSAndroid Build Coastguard Worker 
2640*35238bceSAndroid Build Coastguard Worker         buildInfo.vertCompileSuccess        = compileShader(shaders.vertShader);
2641*35238bceSAndroid Build Coastguard Worker         uint64_t vertexShaderCompileEndTime = deGetMicroseconds();
2642*35238bceSAndroid Build Coastguard Worker 
2643*35238bceSAndroid Build Coastguard Worker         buildInfo.fragCompileSuccess          = compileShader(shaders.fragShader);
2644*35238bceSAndroid Build Coastguard Worker         uint64_t fragmentShaderCompileEndTime = deGetMicroseconds();
2645*35238bceSAndroid Build Coastguard Worker 
2646*35238bceSAndroid Build Coastguard Worker         buildInfo.logs = getLogs(shaders);
2647*35238bceSAndroid Build Coastguard Worker 
2648*35238bceSAndroid Build Coastguard Worker         // Both shader compilations should have failed.
2649*35238bceSAndroid Build Coastguard Worker         if (buildInfo.vertCompileSuccess || buildInfo.fragCompileSuccess)
2650*35238bceSAndroid Build Coastguard Worker         {
2651*35238bceSAndroid Build Coastguard Worker             logProgramData(buildInfo, progCtx);
2652*35238bceSAndroid Build Coastguard Worker             cleanup(shaders);
2653*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of a shader erroneously succeeded");
2654*35238bceSAndroid Build Coastguard Worker             return STOP;
2655*35238bceSAndroid Build Coastguard Worker         }
2656*35238bceSAndroid Build Coastguard Worker 
2657*35238bceSAndroid Build Coastguard Worker         // De-initializations (delete shaders).
2658*35238bceSAndroid Build Coastguard Worker 
2659*35238bceSAndroid Build Coastguard Worker         cleanup(shaders);
2660*35238bceSAndroid Build Coastguard Worker 
2661*35238bceSAndroid Build Coastguard Worker         // Output measurement log later (after last measurement).
2662*35238bceSAndroid Build Coastguard Worker 
2663*35238bceSAndroid Build Coastguard Worker         measurements.push_back(Measurement((int64_t)(shaderSourceSetEndTime - startTime),
2664*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(vertexShaderCompileEndTime - shaderSourceSetEndTime),
2665*35238bceSAndroid Build Coastguard Worker                                            (int64_t)(fragmentShaderCompileEndTime - vertexShaderCompileEndTime)));
2666*35238bceSAndroid Build Coastguard Worker 
2667*35238bceSAndroid Build Coastguard Worker         latestBuildInfo      = buildInfo;
2668*35238bceSAndroid Build Coastguard Worker         latestProgramContext = progCtx;
2669*35238bceSAndroid Build Coastguard Worker 
2670*35238bceSAndroid Build Coastguard Worker         m_testCtx.touchWatchdog(); // \note Measurements may take a while in a bad case.
2671*35238bceSAndroid Build Coastguard Worker     }
2672*35238bceSAndroid Build Coastguard Worker 
2673*35238bceSAndroid Build Coastguard Worker     // End of test case, log information about measurements.
2674*35238bceSAndroid Build Coastguard Worker     {
2675*35238bceSAndroid Build Coastguard Worker         TestLog &log = m_testCtx.getLog();
2676*35238bceSAndroid Build Coastguard Worker 
2677*35238bceSAndroid Build Coastguard Worker         vector<int64_t> sourceSetTimes;
2678*35238bceSAndroid Build Coastguard Worker         vector<int64_t> vertexCompileTimes;
2679*35238bceSAndroid Build Coastguard Worker         vector<int64_t> fragmentCompileTimes;
2680*35238bceSAndroid Build Coastguard Worker         vector<int64_t> totalTimes;
2681*35238bceSAndroid Build Coastguard Worker 
2682*35238bceSAndroid Build Coastguard Worker         log << TestLog::Section("IterationMeasurements", "Iteration measurements of compilation times");
2683*35238bceSAndroid Build Coastguard Worker 
2684*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)measurements.size(); ndx++)
2685*35238bceSAndroid Build Coastguard Worker         {
2686*35238bceSAndroid Build Coastguard Worker             sourceSetTimes.push_back(measurements[ndx].sourceSetTime);
2687*35238bceSAndroid Build Coastguard Worker             vertexCompileTimes.push_back(measurements[ndx].vertexCompileTime);
2688*35238bceSAndroid Build Coastguard Worker             fragmentCompileTimes.push_back(measurements[ndx].fragmentCompileTime);
2689*35238bceSAndroid Build Coastguard Worker             totalTimes.push_back(measurements[ndx].totalTime());
2690*35238bceSAndroid Build Coastguard Worker 
2691*35238bceSAndroid Build Coastguard Worker             // Log this measurement.
2692*35238bceSAndroid Build Coastguard Worker             log << TestLog::Float("Measurement" + de::toString(ndx) + "Time",
2693*35238bceSAndroid Build Coastguard Worker                                   "Measurement " + de::toString(ndx) + " time", "ms", QP_KEY_TAG_TIME,
2694*35238bceSAndroid Build Coastguard Worker                                   (float)measurements[ndx].totalTime() / 1000.0f);
2695*35238bceSAndroid Build Coastguard Worker         }
2696*35238bceSAndroid Build Coastguard Worker 
2697*35238bceSAndroid Build Coastguard Worker         // Log some statistics.
2698*35238bceSAndroid Build Coastguard Worker 
2699*35238bceSAndroid Build Coastguard Worker         for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
2700*35238bceSAndroid Build Coastguard Worker         {
2701*35238bceSAndroid Build Coastguard Worker             bool isEntireRange         = entireRangeOrLowestHalf == 0;
2702*35238bceSAndroid Build Coastguard Worker             string statNamePrefix      = isEntireRange ? "" : "LowestHalf";
2703*35238bceSAndroid Build Coastguard Worker             vector<int64_t> rangeTimes = isEntireRange ? totalTimes : vectorLowestPercentage(totalTimes, 0.5f);
2704*35238bceSAndroid Build Coastguard Worker 
2705*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "\nStatistics computed from " << (isEntireRange ? "all" : "only the lowest 50%")
2706*35238bceSAndroid Build Coastguard Worker                 << " of the above measurements:" << TestLog::EndMessage;
2707*35238bceSAndroid Build Coastguard Worker 
2708*35238bceSAndroid Build Coastguard Worker #define LOG_TIME_STAT(NAME, DESC, FUNC)                                                                   \
2709*35238bceSAndroid Build Coastguard Worker     log << TestLog::Float(statNamePrefix + "TotalTime" + (NAME), (DESC) + string(" of total time"), "ms", \
2710*35238bceSAndroid Build Coastguard Worker                           QP_KEY_TAG_TIME, (FUNC)(rangeTimes) / 1000.0f)
2711*35238bceSAndroid Build Coastguard Worker #define LOG_RELATIVE_STAT(NAME, DESC, FUNC)                                                             \
2712*35238bceSAndroid Build Coastguard Worker     log << TestLog::Float(statNamePrefix + "TotalTime" + (NAME), (DESC) + string(" of total time"), "", \
2713*35238bceSAndroid Build Coastguard Worker                           QP_KEY_TAG_NONE, (FUNC)(rangeTimes))
2714*35238bceSAndroid Build Coastguard Worker 
2715*35238bceSAndroid Build Coastguard Worker             LOG_TIME_STAT("Median", "Median", vectorFloatMedian);
2716*35238bceSAndroid Build Coastguard Worker             LOG_TIME_STAT("Average", "Average", vectorFloatAverage);
2717*35238bceSAndroid Build Coastguard Worker             LOG_TIME_STAT("Minimum", "Minimum", vectorFloatMinimum);
2718*35238bceSAndroid Build Coastguard Worker             LOG_TIME_STAT("Maximum", "Maximum", vectorFloatMaximum);
2719*35238bceSAndroid Build Coastguard Worker             LOG_TIME_STAT("MedianAbsoluteDeviation", "Median absolute deviation", vectorFloatMedianAbsoluteDeviation);
2720*35238bceSAndroid Build Coastguard Worker             LOG_RELATIVE_STAT("RelativeMedianAbsoluteDeviation", "Relative median absolute deviation",
2721*35238bceSAndroid Build Coastguard Worker                               vectorFloatRelativeMedianAbsoluteDeviation);
2722*35238bceSAndroid Build Coastguard Worker             LOG_TIME_STAT("StandardDeviation", "Standard deviation", vectorFloatStandardDeviation);
2723*35238bceSAndroid Build Coastguard Worker             LOG_RELATIVE_STAT("RelativeStandardDeviation", "Relative standard deviation",
2724*35238bceSAndroid Build Coastguard Worker                               vectorFloatRelativeStandardDeviation);
2725*35238bceSAndroid Build Coastguard Worker             LOG_TIME_STAT("MaxMinusMin", "Max-min", vectorFloatMaximumMinusMinimum);
2726*35238bceSAndroid Build Coastguard Worker             LOG_RELATIVE_STAT("RelativeMaxMinusMin", "Relative max-min", vectorFloatRelativeMaximumMinusMinimum);
2727*35238bceSAndroid Build Coastguard Worker 
2728*35238bceSAndroid Build Coastguard Worker #undef LOG_TIME_STAT
2729*35238bceSAndroid Build Coastguard Worker #undef LOG_RELATIVE_STAT
2730*35238bceSAndroid Build Coastguard Worker 
2731*35238bceSAndroid Build Coastguard Worker             if (!isEntireRange &&
2732*35238bceSAndroid Build Coastguard Worker                 vectorFloatRelativeMedianAbsoluteDeviation(rangeTimes) > RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD)
2733*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
2734*35238bceSAndroid Build Coastguard Worker                     << "\nWARNING: couldn't achieve relative median absolute deviation under threshold value "
2735*35238bceSAndroid Build Coastguard Worker                     << RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD << TestLog::EndMessage;
2736*35238bceSAndroid Build Coastguard Worker         }
2737*35238bceSAndroid Build Coastguard Worker 
2738*35238bceSAndroid Build Coastguard Worker         log << TestLog::EndSection; // End section IterationMeasurements
2739*35238bceSAndroid Build Coastguard Worker 
2740*35238bceSAndroid Build Coastguard Worker         for (int medianOrAverage = 0; medianOrAverage < 2; medianOrAverage++)
2741*35238bceSAndroid Build Coastguard Worker         {
2742*35238bceSAndroid Build Coastguard Worker             typedef float (*VecFunc)(const vector<int64_t> &);
2743*35238bceSAndroid Build Coastguard Worker 
2744*35238bceSAndroid Build Coastguard Worker             bool isMedian   = medianOrAverage == 0;
2745*35238bceSAndroid Build Coastguard Worker             string singular = isMedian ? "Median" : "Average";
2746*35238bceSAndroid Build Coastguard Worker             string plural   = singular + "s";
2747*35238bceSAndroid Build Coastguard Worker             VecFunc func    = isMedian ? (VecFunc)vectorFloatMedian<int64_t> : (VecFunc)vectorFloatAverage<int64_t>;
2748*35238bceSAndroid Build Coastguard Worker 
2749*35238bceSAndroid Build Coastguard Worker             log << TestLog::Section(plural + "PerPhase", plural + " per phase");
2750*35238bceSAndroid Build Coastguard Worker 
2751*35238bceSAndroid Build Coastguard Worker             for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
2752*35238bceSAndroid Build Coastguard Worker             {
2753*35238bceSAndroid Build Coastguard Worker                 bool isEntireRange    = entireRangeOrLowestHalf == 0;
2754*35238bceSAndroid Build Coastguard Worker                 string statNamePrefix = isEntireRange ? "" : "LowestHalf";
2755*35238bceSAndroid Build Coastguard Worker                 float rangeSizeRatio  = isEntireRange ? 1.0f : 0.5f;
2756*35238bceSAndroid Build Coastguard Worker 
2757*35238bceSAndroid Build Coastguard Worker #define LOG_TIME(NAME, DESC, DATA)                                                                               \
2758*35238bceSAndroid Build Coastguard Worker     log << TestLog::Float(statNamePrefix + (NAME) + singular, singular + " of " + (DESC), "ms", QP_KEY_TAG_TIME, \
2759*35238bceSAndroid Build Coastguard Worker                           func(vectorLowestPercentage((DATA), rangeSizeRatio)) / 1000.0f)
2760*35238bceSAndroid Build Coastguard Worker 
2761*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
2762*35238bceSAndroid Build Coastguard Worker                     << (isEntireRange ? "For all measurements:" : "\nFor only the lowest 50% of the measurements:")
2763*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
2764*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("ShaderSourceSetTime", "shader source set time", sourceSetTimes);
2765*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("VertexShaderCompileTime", "vertex shader compile time", vertexCompileTimes);
2766*35238bceSAndroid Build Coastguard Worker                 LOG_TIME("FragmentShaderCompileTime", "fragment shader compile time", fragmentCompileTimes);
2767*35238bceSAndroid Build Coastguard Worker 
2768*35238bceSAndroid Build Coastguard Worker #undef LOG_TIME
2769*35238bceSAndroid Build Coastguard Worker             }
2770*35238bceSAndroid Build Coastguard Worker 
2771*35238bceSAndroid Build Coastguard Worker             log << TestLog::EndSection;
2772*35238bceSAndroid Build Coastguard Worker         }
2773*35238bceSAndroid Build Coastguard Worker 
2774*35238bceSAndroid Build Coastguard Worker         // Set result.
2775*35238bceSAndroid Build Coastguard Worker 
2776*35238bceSAndroid Build Coastguard Worker         {
2777*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message
2778*35238bceSAndroid Build Coastguard Worker                 << "Note: test result is the first quartile (i.e. median of the lowest half of measurements) of total "
2779*35238bceSAndroid Build Coastguard Worker                    "times"
2780*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
2781*35238bceSAndroid Build Coastguard Worker             float result = vectorFloatFirstQuartile(totalTimes) / 1000.0f;
2782*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
2783*35238bceSAndroid Build Coastguard Worker         }
2784*35238bceSAndroid Build Coastguard Worker 
2785*35238bceSAndroid Build Coastguard Worker         // Log shaders.
2786*35238bceSAndroid Build Coastguard Worker 
2787*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message
2788*35238bceSAndroid Build Coastguard Worker             << "Note: the following shaders are the ones from the last iteration; variables' names and some constant "
2789*35238bceSAndroid Build Coastguard Worker                "expressions differ between iterations."
2790*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
2791*35238bceSAndroid Build Coastguard Worker 
2792*35238bceSAndroid Build Coastguard Worker         logProgramData(latestBuildInfo, latestProgramContext);
2793*35238bceSAndroid Build Coastguard Worker 
2794*35238bceSAndroid Build Coastguard Worker         return STOP;
2795*35238bceSAndroid Build Coastguard Worker     }
2796*35238bceSAndroid Build Coastguard Worker }
2797*35238bceSAndroid Build Coastguard Worker 
InvalidShaderCompilerLightCase(Context & context,const char * name,const char * description,int caseID,InvalidityType invalidityType,bool isVertexCase,int numLights,LightType lightType)2798*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerLightCase::InvalidShaderCompilerLightCase(Context &context, const char *name,
2799*35238bceSAndroid Build Coastguard Worker                                                                const char *description, int caseID,
2800*35238bceSAndroid Build Coastguard Worker                                                                InvalidityType invalidityType, bool isVertexCase,
2801*35238bceSAndroid Build Coastguard Worker                                                                int numLights, LightType lightType)
2802*35238bceSAndroid Build Coastguard Worker     : InvalidShaderCompilerCase(context, name, description, caseID, invalidityType)
2803*35238bceSAndroid Build Coastguard Worker     , m_isVertexCase(isVertexCase)
2804*35238bceSAndroid Build Coastguard Worker     , m_numLights(numLights)
2805*35238bceSAndroid Build Coastguard Worker     , m_lightType(lightType)
2806*35238bceSAndroid Build Coastguard Worker {
2807*35238bceSAndroid Build Coastguard Worker }
2808*35238bceSAndroid Build Coastguard Worker 
~InvalidShaderCompilerLightCase(void)2809*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerLightCase::~InvalidShaderCompilerLightCase(void)
2810*35238bceSAndroid Build Coastguard Worker {
2811*35238bceSAndroid Build Coastguard Worker }
2812*35238bceSAndroid Build Coastguard Worker 
generateShaderSources(int measurementNdx) const2813*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerLightCase::generateShaderSources(
2814*35238bceSAndroid Build Coastguard Worker     int measurementNdx) const
2815*35238bceSAndroid Build Coastguard Worker {
2816*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2817*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2818*35238bceSAndroid Build Coastguard Worker     ShaderValidity shaderValidity = m_invalidityType == INVALIDITY_INVALID_CHAR   ? SHADER_VALIDITY_INVALID_CHAR :
2819*35238bceSAndroid Build Coastguard Worker                                     m_invalidityType == INVALIDITY_SEMANTIC_ERROR ? SHADER_VALIDITY_SEMANTIC_ERROR :
2820*35238bceSAndroid Build Coastguard Worker                                                                                     SHADER_VALIDITY_LAST;
2821*35238bceSAndroid Build Coastguard Worker 
2822*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
2823*35238bceSAndroid Build Coastguard Worker 
2824*35238bceSAndroid Build Coastguard Worker     result.vertShaderSource =
2825*35238bceSAndroid Build Coastguard Worker         specializeShaderSource(lightVertexTemplate(m_numLights, m_isVertexCase, m_lightType), specID, shaderValidity);
2826*35238bceSAndroid Build Coastguard Worker     result.fragShaderSource =
2827*35238bceSAndroid Build Coastguard Worker         specializeShaderSource(lightFragmentTemplate(m_numLights, m_isVertexCase, m_lightType), specID, shaderValidity);
2828*35238bceSAndroid Build Coastguard Worker 
2829*35238bceSAndroid Build Coastguard Worker     return result;
2830*35238bceSAndroid Build Coastguard Worker }
2831*35238bceSAndroid Build Coastguard Worker 
InvalidShaderCompilerTextureCase(Context & context,const char * name,const char * description,int caseID,InvalidityType invalidityType,int numLookups,ConditionalUsage conditionalUsage,ConditionalType conditionalType)2832*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerTextureCase::InvalidShaderCompilerTextureCase(Context &context, const char *name,
2833*35238bceSAndroid Build Coastguard Worker                                                                    const char *description, int caseID,
2834*35238bceSAndroid Build Coastguard Worker                                                                    InvalidityType invalidityType, int numLookups,
2835*35238bceSAndroid Build Coastguard Worker                                                                    ConditionalUsage conditionalUsage,
2836*35238bceSAndroid Build Coastguard Worker                                                                    ConditionalType conditionalType)
2837*35238bceSAndroid Build Coastguard Worker     : InvalidShaderCompilerCase(context, name, description, caseID, invalidityType)
2838*35238bceSAndroid Build Coastguard Worker     , m_numLookups(numLookups)
2839*35238bceSAndroid Build Coastguard Worker     , m_conditionalUsage(conditionalUsage)
2840*35238bceSAndroid Build Coastguard Worker     , m_conditionalType(conditionalType)
2841*35238bceSAndroid Build Coastguard Worker {
2842*35238bceSAndroid Build Coastguard Worker }
2843*35238bceSAndroid Build Coastguard Worker 
~InvalidShaderCompilerTextureCase(void)2844*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerTextureCase::~InvalidShaderCompilerTextureCase(void)
2845*35238bceSAndroid Build Coastguard Worker {
2846*35238bceSAndroid Build Coastguard Worker }
2847*35238bceSAndroid Build Coastguard Worker 
generateShaderSources(int measurementNdx) const2848*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerTextureCase::generateShaderSources(
2849*35238bceSAndroid Build Coastguard Worker     int measurementNdx) const
2850*35238bceSAndroid Build Coastguard Worker {
2851*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2852*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2853*35238bceSAndroid Build Coastguard Worker     ShaderValidity shaderValidity = m_invalidityType == INVALIDITY_INVALID_CHAR   ? SHADER_VALIDITY_INVALID_CHAR :
2854*35238bceSAndroid Build Coastguard Worker                                     m_invalidityType == INVALIDITY_SEMANTIC_ERROR ? SHADER_VALIDITY_SEMANTIC_ERROR :
2855*35238bceSAndroid Build Coastguard Worker                                                                                     SHADER_VALIDITY_LAST;
2856*35238bceSAndroid Build Coastguard Worker 
2857*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
2858*35238bceSAndroid Build Coastguard Worker 
2859*35238bceSAndroid Build Coastguard Worker     result.vertShaderSource = specializeShaderSource(textureLookupVertexTemplate(m_conditionalUsage, m_conditionalType),
2860*35238bceSAndroid Build Coastguard Worker                                                      specID, shaderValidity);
2861*35238bceSAndroid Build Coastguard Worker     result.fragShaderSource = specializeShaderSource(
2862*35238bceSAndroid Build Coastguard Worker         textureLookupFragmentTemplate(m_numLookups, m_conditionalUsage, m_conditionalType), specID, shaderValidity);
2863*35238bceSAndroid Build Coastguard Worker 
2864*35238bceSAndroid Build Coastguard Worker     return result;
2865*35238bceSAndroid Build Coastguard Worker }
2866*35238bceSAndroid Build Coastguard Worker 
InvalidShaderCompilerLoopCase(Context & context,const char * name,const char * description,int caseID,InvalidityType invalidityType,bool isVertexCase,LoopType type,int numLoopIterations,int nestingDepth)2867*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerLoopCase::InvalidShaderCompilerLoopCase(Context &context, const char *name,
2868*35238bceSAndroid Build Coastguard Worker                                                              const char *description, int caseID,
2869*35238bceSAndroid Build Coastguard Worker                                                              InvalidityType invalidityType, bool isVertexCase,
2870*35238bceSAndroid Build Coastguard Worker                                                              LoopType type, int numLoopIterations, int nestingDepth)
2871*35238bceSAndroid Build Coastguard Worker     : InvalidShaderCompilerCase(context, name, description, caseID, invalidityType)
2872*35238bceSAndroid Build Coastguard Worker     , m_isVertexCase(isVertexCase)
2873*35238bceSAndroid Build Coastguard Worker     , m_numLoopIterations(numLoopIterations)
2874*35238bceSAndroid Build Coastguard Worker     , m_nestingDepth(nestingDepth)
2875*35238bceSAndroid Build Coastguard Worker     , m_type(type)
2876*35238bceSAndroid Build Coastguard Worker {
2877*35238bceSAndroid Build Coastguard Worker }
2878*35238bceSAndroid Build Coastguard Worker 
~InvalidShaderCompilerLoopCase(void)2879*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerLoopCase::~InvalidShaderCompilerLoopCase(void)
2880*35238bceSAndroid Build Coastguard Worker {
2881*35238bceSAndroid Build Coastguard Worker }
2882*35238bceSAndroid Build Coastguard Worker 
generateShaderSources(int measurementNdx) const2883*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerLoopCase::generateShaderSources(int measurementNdx) const
2884*35238bceSAndroid Build Coastguard Worker {
2885*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2886*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2887*35238bceSAndroid Build Coastguard Worker     ShaderValidity shaderValidity = m_invalidityType == INVALIDITY_INVALID_CHAR   ? SHADER_VALIDITY_INVALID_CHAR :
2888*35238bceSAndroid Build Coastguard Worker                                     m_invalidityType == INVALIDITY_SEMANTIC_ERROR ? SHADER_VALIDITY_SEMANTIC_ERROR :
2889*35238bceSAndroid Build Coastguard Worker                                                                                     SHADER_VALIDITY_LAST;
2890*35238bceSAndroid Build Coastguard Worker 
2891*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
2892*35238bceSAndroid Build Coastguard Worker 
2893*35238bceSAndroid Build Coastguard Worker     result.vertShaderSource = specializeShaderSource(
2894*35238bceSAndroid Build Coastguard Worker         loopVertexTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, shaderValidity);
2895*35238bceSAndroid Build Coastguard Worker     result.fragShaderSource = specializeShaderSource(
2896*35238bceSAndroid Build Coastguard Worker         loopFragmentTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, shaderValidity);
2897*35238bceSAndroid Build Coastguard Worker 
2898*35238bceSAndroid Build Coastguard Worker     return result;
2899*35238bceSAndroid Build Coastguard Worker }
2900*35238bceSAndroid Build Coastguard Worker 
InvalidShaderCompilerOperCase(Context & context,const char * name,const char * description,int caseID,InvalidityType invalidityType,bool isVertexCase,const char * oper,int numOperations)2901*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerOperCase::InvalidShaderCompilerOperCase(Context &context, const char *name,
2902*35238bceSAndroid Build Coastguard Worker                                                              const char *description, int caseID,
2903*35238bceSAndroid Build Coastguard Worker                                                              InvalidityType invalidityType, bool isVertexCase,
2904*35238bceSAndroid Build Coastguard Worker                                                              const char *oper, int numOperations)
2905*35238bceSAndroid Build Coastguard Worker     : InvalidShaderCompilerCase(context, name, description, caseID, invalidityType)
2906*35238bceSAndroid Build Coastguard Worker     , m_isVertexCase(isVertexCase)
2907*35238bceSAndroid Build Coastguard Worker     , m_oper(oper)
2908*35238bceSAndroid Build Coastguard Worker     , m_numOperations(numOperations)
2909*35238bceSAndroid Build Coastguard Worker {
2910*35238bceSAndroid Build Coastguard Worker }
2911*35238bceSAndroid Build Coastguard Worker 
~InvalidShaderCompilerOperCase(void)2912*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerOperCase::~InvalidShaderCompilerOperCase(void)
2913*35238bceSAndroid Build Coastguard Worker {
2914*35238bceSAndroid Build Coastguard Worker }
2915*35238bceSAndroid Build Coastguard Worker 
generateShaderSources(int measurementNdx) const2916*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerOperCase::generateShaderSources(int measurementNdx) const
2917*35238bceSAndroid Build Coastguard Worker {
2918*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2919*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2920*35238bceSAndroid Build Coastguard Worker     ShaderValidity shaderValidity = m_invalidityType == INVALIDITY_INVALID_CHAR   ? SHADER_VALIDITY_INVALID_CHAR :
2921*35238bceSAndroid Build Coastguard Worker                                     m_invalidityType == INVALIDITY_SEMANTIC_ERROR ? SHADER_VALIDITY_SEMANTIC_ERROR :
2922*35238bceSAndroid Build Coastguard Worker                                                                                     SHADER_VALIDITY_LAST;
2923*35238bceSAndroid Build Coastguard Worker 
2924*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
2925*35238bceSAndroid Build Coastguard Worker 
2926*35238bceSAndroid Build Coastguard Worker     if (m_isVertexCase)
2927*35238bceSAndroid Build Coastguard Worker     {
2928*35238bceSAndroid Build Coastguard Worker         result.vertShaderSource =
2929*35238bceSAndroid Build Coastguard Worker             specializeShaderSource(binaryOpVertexTemplate(m_numOperations, m_oper.c_str()), specID, shaderValidity);
2930*35238bceSAndroid Build Coastguard Worker         result.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, shaderValidity);
2931*35238bceSAndroid Build Coastguard Worker     }
2932*35238bceSAndroid Build Coastguard Worker     else
2933*35238bceSAndroid Build Coastguard Worker     {
2934*35238bceSAndroid Build Coastguard Worker         result.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, shaderValidity);
2935*35238bceSAndroid Build Coastguard Worker         result.fragShaderSource =
2936*35238bceSAndroid Build Coastguard Worker             specializeShaderSource(binaryOpFragmentTemplate(m_numOperations, m_oper.c_str()), specID, shaderValidity);
2937*35238bceSAndroid Build Coastguard Worker     }
2938*35238bceSAndroid Build Coastguard Worker 
2939*35238bceSAndroid Build Coastguard Worker     return result;
2940*35238bceSAndroid Build Coastguard Worker }
2941*35238bceSAndroid Build Coastguard Worker 
InvalidShaderCompilerMandelbrotCase(Context & context,const char * name,const char * description,int caseID,InvalidityType invalidityType,int numFractalIterations)2942*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerMandelbrotCase::InvalidShaderCompilerMandelbrotCase(Context &context, const char *name,
2943*35238bceSAndroid Build Coastguard Worker                                                                          const char *description, int caseID,
2944*35238bceSAndroid Build Coastguard Worker                                                                          InvalidityType invalidityType,
2945*35238bceSAndroid Build Coastguard Worker                                                                          int numFractalIterations)
2946*35238bceSAndroid Build Coastguard Worker     : InvalidShaderCompilerCase(context, name, description, caseID, invalidityType)
2947*35238bceSAndroid Build Coastguard Worker     , m_numFractalIterations(numFractalIterations)
2948*35238bceSAndroid Build Coastguard Worker {
2949*35238bceSAndroid Build Coastguard Worker }
2950*35238bceSAndroid Build Coastguard Worker 
~InvalidShaderCompilerMandelbrotCase(void)2951*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerMandelbrotCase::~InvalidShaderCompilerMandelbrotCase(void)
2952*35238bceSAndroid Build Coastguard Worker {
2953*35238bceSAndroid Build Coastguard Worker }
2954*35238bceSAndroid Build Coastguard Worker 
generateShaderSources(int measurementNdx) const2955*35238bceSAndroid Build Coastguard Worker InvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerMandelbrotCase::generateShaderSources(
2956*35238bceSAndroid Build Coastguard Worker     int measurementNdx) const
2957*35238bceSAndroid Build Coastguard Worker {
2958*35238bceSAndroid Build Coastguard Worker     uint32_t specID = getSpecializationID(measurementNdx);
2959*35238bceSAndroid Build Coastguard Worker     ProgramContext result;
2960*35238bceSAndroid Build Coastguard Worker     ShaderValidity shaderValidity = m_invalidityType == INVALIDITY_INVALID_CHAR   ? SHADER_VALIDITY_INVALID_CHAR :
2961*35238bceSAndroid Build Coastguard Worker                                     m_invalidityType == INVALIDITY_SEMANTIC_ERROR ? SHADER_VALIDITY_SEMANTIC_ERROR :
2962*35238bceSAndroid Build Coastguard Worker                                                                                     SHADER_VALIDITY_LAST;
2963*35238bceSAndroid Build Coastguard Worker 
2964*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
2965*35238bceSAndroid Build Coastguard Worker 
2966*35238bceSAndroid Build Coastguard Worker     result.vertShaderSource = specializeShaderSource(mandelbrotVertexTemplate(), specID, shaderValidity);
2967*35238bceSAndroid Build Coastguard Worker     result.fragShaderSource =
2968*35238bceSAndroid Build Coastguard Worker         specializeShaderSource(mandelbrotFragmentTemplate(m_numFractalIterations), specID, shaderValidity);
2969*35238bceSAndroid Build Coastguard Worker 
2970*35238bceSAndroid Build Coastguard Worker     return result;
2971*35238bceSAndroid Build Coastguard Worker }
2972*35238bceSAndroid Build Coastguard Worker 
addShaderCompilationPerformanceCases(TestCaseGroup & parentGroup)2973*35238bceSAndroid Build Coastguard Worker void addShaderCompilationPerformanceCases(TestCaseGroup &parentGroup)
2974*35238bceSAndroid Build Coastguard Worker {
2975*35238bceSAndroid Build Coastguard Worker     Context &context = parentGroup.getContext();
2976*35238bceSAndroid Build Coastguard Worker     int caseID       = 0; // Increment this after adding each case. Used for avoiding cache hits between cases.
2977*35238bceSAndroid Build Coastguard Worker 
2978*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *validGroup   = new TestCaseGroup(context, "valid_shader", "Valid Shader Compiler Cases");
2979*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *invalidGroup = new TestCaseGroup(context, "invalid_shader", "Invalid Shader Compiler Cases");
2980*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *cacheGroup   = new TestCaseGroup(context, "cache", "Allow shader caching");
2981*35238bceSAndroid Build Coastguard Worker     parentGroup.addChild(validGroup);
2982*35238bceSAndroid Build Coastguard Worker     parentGroup.addChild(invalidGroup);
2983*35238bceSAndroid Build Coastguard Worker     parentGroup.addChild(cacheGroup);
2984*35238bceSAndroid Build Coastguard Worker 
2985*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *invalidCharGroup =
2986*35238bceSAndroid Build Coastguard Worker         new TestCaseGroup(context, "invalid_char", "Invalid Character Shader Compiler Cases");
2987*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *semanticErrorGroup =
2988*35238bceSAndroid Build Coastguard Worker         new TestCaseGroup(context, "semantic_error", "Semantic Error Shader Compiler Cases");
2989*35238bceSAndroid Build Coastguard Worker     invalidGroup->addChild(invalidCharGroup);
2990*35238bceSAndroid Build Coastguard Worker     invalidGroup->addChild(semanticErrorGroup);
2991*35238bceSAndroid Build Coastguard Worker 
2992*35238bceSAndroid Build Coastguard Worker     // Lighting shader compilation cases.
2993*35238bceSAndroid Build Coastguard Worker 
2994*35238bceSAndroid Build Coastguard Worker     {
2995*35238bceSAndroid Build Coastguard Worker         static const int lightCounts[] = {1, 2, 4, 8};
2996*35238bceSAndroid Build Coastguard Worker 
2997*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *validLightingGroup = new TestCaseGroup(context, "lighting", "Shader Compiler Lighting Cases");
2998*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *invalidCharLightingGroup =
2999*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "lighting", "Invalid Character Shader Compiler Lighting Cases");
3000*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *semanticErrorLightingGroup =
3001*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "lighting", "Semantic Error Shader Compiler Lighting Cases");
3002*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *cacheLightingGroup =
3003*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "lighting", "Shader Compiler Lighting Cache Cases");
3004*35238bceSAndroid Build Coastguard Worker         validGroup->addChild(validLightingGroup);
3005*35238bceSAndroid Build Coastguard Worker         invalidCharGroup->addChild(invalidCharLightingGroup);
3006*35238bceSAndroid Build Coastguard Worker         semanticErrorGroup->addChild(semanticErrorLightingGroup);
3007*35238bceSAndroid Build Coastguard Worker         cacheGroup->addChild(cacheLightingGroup);
3008*35238bceSAndroid Build Coastguard Worker 
3009*35238bceSAndroid Build Coastguard Worker         for (int lightType = 0; lightType < (int)LIGHT_LAST; lightType++)
3010*35238bceSAndroid Build Coastguard Worker         {
3011*35238bceSAndroid Build Coastguard Worker             const char *lightTypeName = lightType == (int)LIGHT_DIRECTIONAL ? "directional" :
3012*35238bceSAndroid Build Coastguard Worker                                         lightType == (int)LIGHT_POINT       ? "point" :
3013*35238bceSAndroid Build Coastguard Worker                                                                               DE_NULL;
3014*35238bceSAndroid Build Coastguard Worker 
3015*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(lightTypeName != DE_NULL);
3016*35238bceSAndroid Build Coastguard Worker 
3017*35238bceSAndroid Build Coastguard Worker             for (int isFrag = 0; isFrag <= 1; isFrag++)
3018*35238bceSAndroid Build Coastguard Worker             {
3019*35238bceSAndroid Build Coastguard Worker                 bool isVertex           = isFrag == 0;
3020*35238bceSAndroid Build Coastguard Worker                 const char *vertFragStr = isVertex ? "vertex" : "fragment";
3021*35238bceSAndroid Build Coastguard Worker 
3022*35238bceSAndroid Build Coastguard Worker                 for (int lightCountNdx = 0; lightCountNdx < DE_LENGTH_OF_ARRAY(lightCounts); lightCountNdx++)
3023*35238bceSAndroid Build Coastguard Worker                 {
3024*35238bceSAndroid Build Coastguard Worker                     int numLights = lightCounts[lightCountNdx];
3025*35238bceSAndroid Build Coastguard Worker 
3026*35238bceSAndroid Build Coastguard Worker                     string caseName =
3027*35238bceSAndroid Build Coastguard Worker                         string("") + lightTypeName + "_" + de::toString(numLights) + "_lights_" + vertFragStr;
3028*35238bceSAndroid Build Coastguard Worker 
3029*35238bceSAndroid Build Coastguard Worker                     // Valid shader case, no-cache and cache versions.
3030*35238bceSAndroid Build Coastguard Worker 
3031*35238bceSAndroid Build Coastguard Worker                     validLightingGroup->addChild(new ShaderCompilerLightCase(context, caseName.c_str(), "", caseID++,
3032*35238bceSAndroid Build Coastguard Worker                                                                              true /* avoid cache */, false, isVertex,
3033*35238bceSAndroid Build Coastguard Worker                                                                              numLights, (LightType)lightType));
3034*35238bceSAndroid Build Coastguard Worker                     cacheLightingGroup->addChild(new ShaderCompilerLightCase(context, caseName.c_str(), "", caseID++,
3035*35238bceSAndroid Build Coastguard Worker                                                                              false /* allow cache */, false, isVertex,
3036*35238bceSAndroid Build Coastguard Worker                                                                              numLights, (LightType)lightType));
3037*35238bceSAndroid Build Coastguard Worker 
3038*35238bceSAndroid Build Coastguard Worker                     // Invalid shader cases.
3039*35238bceSAndroid Build Coastguard Worker 
3040*35238bceSAndroid Build Coastguard Worker                     for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST;
3041*35238bceSAndroid Build Coastguard Worker                          invalidityType++)
3042*35238bceSAndroid Build Coastguard Worker                     {
3043*35238bceSAndroid Build Coastguard Worker                         TestCaseGroup *curInvalidGroup =
3044*35238bceSAndroid Build Coastguard Worker                             invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR ?
3045*35238bceSAndroid Build Coastguard Worker                                 invalidCharLightingGroup :
3046*35238bceSAndroid Build Coastguard Worker                             invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR ?
3047*35238bceSAndroid Build Coastguard Worker                                 semanticErrorLightingGroup :
3048*35238bceSAndroid Build Coastguard Worker                                 DE_NULL;
3049*35238bceSAndroid Build Coastguard Worker 
3050*35238bceSAndroid Build Coastguard Worker                         DE_ASSERT(curInvalidGroup != DE_NULL);
3051*35238bceSAndroid Build Coastguard Worker 
3052*35238bceSAndroid Build Coastguard Worker                         curInvalidGroup->addChild(new InvalidShaderCompilerLightCase(
3053*35238bceSAndroid Build Coastguard Worker                             context, caseName.c_str(), "", caseID++,
3054*35238bceSAndroid Build Coastguard Worker                             (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, numLights,
3055*35238bceSAndroid Build Coastguard Worker                             (LightType)lightType));
3056*35238bceSAndroid Build Coastguard Worker                     }
3057*35238bceSAndroid Build Coastguard Worker                 }
3058*35238bceSAndroid Build Coastguard Worker             }
3059*35238bceSAndroid Build Coastguard Worker         }
3060*35238bceSAndroid Build Coastguard Worker     }
3061*35238bceSAndroid Build Coastguard Worker 
3062*35238bceSAndroid Build Coastguard Worker     // Texture lookup shader compilation cases.
3063*35238bceSAndroid Build Coastguard Worker 
3064*35238bceSAndroid Build Coastguard Worker     {
3065*35238bceSAndroid Build Coastguard Worker         static const int texLookupCounts[] = {1, 2, 4, 8};
3066*35238bceSAndroid Build Coastguard Worker 
3067*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *validTexGroup = new TestCaseGroup(context, "texture", "Shader Compiler Texture Lookup Cases");
3068*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *invalidCharTexGroup =
3069*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "texture", "Invalid Character Shader Compiler Texture Lookup Cases");
3070*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *semanticErrorTexGroup =
3071*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "texture", "Semantic Error Shader Compiler Texture Lookup Cases");
3072*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *cacheTexGroup =
3073*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "texture", "Shader Compiler Texture Lookup Cache Cases");
3074*35238bceSAndroid Build Coastguard Worker         validGroup->addChild(validTexGroup);
3075*35238bceSAndroid Build Coastguard Worker         invalidCharGroup->addChild(invalidCharTexGroup);
3076*35238bceSAndroid Build Coastguard Worker         semanticErrorGroup->addChild(semanticErrorTexGroup);
3077*35238bceSAndroid Build Coastguard Worker         cacheGroup->addChild(cacheTexGroup);
3078*35238bceSAndroid Build Coastguard Worker 
3079*35238bceSAndroid Build Coastguard Worker         for (int conditionalUsage = 0; conditionalUsage < (int)CONDITIONAL_USAGE_LAST; conditionalUsage++)
3080*35238bceSAndroid Build Coastguard Worker         {
3081*35238bceSAndroid Build Coastguard Worker             const char *conditionalUsageName = conditionalUsage == (int)CONDITIONAL_USAGE_NONE ? "no_conditionals" :
3082*35238bceSAndroid Build Coastguard Worker                                                conditionalUsage == (int)CONDITIONAL_USAGE_FIRST_HALF  ? "first_half" :
3083*35238bceSAndroid Build Coastguard Worker                                                conditionalUsage == (int)CONDITIONAL_USAGE_EVERY_OTHER ? "every_other" :
3084*35238bceSAndroid Build Coastguard Worker                                                                                                         DE_NULL;
3085*35238bceSAndroid Build Coastguard Worker 
3086*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(conditionalUsageName != DE_NULL);
3087*35238bceSAndroid Build Coastguard Worker 
3088*35238bceSAndroid Build Coastguard Worker             int lastConditionalType = conditionalUsage == (int)CONDITIONAL_USAGE_NONE ? 1 : (int)CONDITIONAL_TYPE_LAST;
3089*35238bceSAndroid Build Coastguard Worker 
3090*35238bceSAndroid Build Coastguard Worker             for (int conditionalType = 0; conditionalType < lastConditionalType; conditionalType++)
3091*35238bceSAndroid Build Coastguard Worker             {
3092*35238bceSAndroid Build Coastguard Worker                 const char *conditionalTypeName =
3093*35238bceSAndroid Build Coastguard Worker                     conditionalType == (int)CONDITIONAL_TYPE_STATIC  ? "static_conditionals" :
3094*35238bceSAndroid Build Coastguard Worker                     conditionalType == (int)CONDITIONAL_TYPE_UNIFORM ? "uniform_conditionals" :
3095*35238bceSAndroid Build Coastguard Worker                     conditionalType == (int)CONDITIONAL_TYPE_DYNAMIC ? "dynamic_conditionals" :
3096*35238bceSAndroid Build Coastguard Worker                                                                        DE_NULL;
3097*35238bceSAndroid Build Coastguard Worker 
3098*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(conditionalTypeName != DE_NULL);
3099*35238bceSAndroid Build Coastguard Worker 
3100*35238bceSAndroid Build Coastguard Worker                 for (int lookupCountNdx = 0; lookupCountNdx < DE_LENGTH_OF_ARRAY(texLookupCounts); lookupCountNdx++)
3101*35238bceSAndroid Build Coastguard Worker                 {
3102*35238bceSAndroid Build Coastguard Worker                     int numLookups = texLookupCounts[lookupCountNdx];
3103*35238bceSAndroid Build Coastguard Worker 
3104*35238bceSAndroid Build Coastguard Worker                     string caseName =
3105*35238bceSAndroid Build Coastguard Worker                         de::toString(numLookups) + "_lookups_" + conditionalUsageName +
3106*35238bceSAndroid Build Coastguard Worker                         (conditionalUsage == (int)CONDITIONAL_USAGE_NONE ? "" : string("_") + conditionalTypeName);
3107*35238bceSAndroid Build Coastguard Worker 
3108*35238bceSAndroid Build Coastguard Worker                     // Valid shader case, no-cache and cache versions.
3109*35238bceSAndroid Build Coastguard Worker 
3110*35238bceSAndroid Build Coastguard Worker                     validTexGroup->addChild(new ShaderCompilerTextureCase(
3111*35238bceSAndroid Build Coastguard Worker                         context, caseName.c_str(), "", caseID++, true /* avoid cache */, false, numLookups,
3112*35238bceSAndroid Build Coastguard Worker                         (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));
3113*35238bceSAndroid Build Coastguard Worker                     cacheTexGroup->addChild(new ShaderCompilerTextureCase(
3114*35238bceSAndroid Build Coastguard Worker                         context, caseName.c_str(), "", caseID++, false /* allow cache */, false, numLookups,
3115*35238bceSAndroid Build Coastguard Worker                         (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));
3116*35238bceSAndroid Build Coastguard Worker 
3117*35238bceSAndroid Build Coastguard Worker                     // Invalid shader cases.
3118*35238bceSAndroid Build Coastguard Worker 
3119*35238bceSAndroid Build Coastguard Worker                     for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST;
3120*35238bceSAndroid Build Coastguard Worker                          invalidityType++)
3121*35238bceSAndroid Build Coastguard Worker                     {
3122*35238bceSAndroid Build Coastguard Worker                         TestCaseGroup *curInvalidGroup =
3123*35238bceSAndroid Build Coastguard Worker                             invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR ?
3124*35238bceSAndroid Build Coastguard Worker                                 invalidCharTexGroup :
3125*35238bceSAndroid Build Coastguard Worker                             invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR ?
3126*35238bceSAndroid Build Coastguard Worker                                 semanticErrorTexGroup :
3127*35238bceSAndroid Build Coastguard Worker                                 DE_NULL;
3128*35238bceSAndroid Build Coastguard Worker 
3129*35238bceSAndroid Build Coastguard Worker                         DE_ASSERT(curInvalidGroup != DE_NULL);
3130*35238bceSAndroid Build Coastguard Worker 
3131*35238bceSAndroid Build Coastguard Worker                         curInvalidGroup->addChild(new InvalidShaderCompilerTextureCase(
3132*35238bceSAndroid Build Coastguard Worker                             context, caseName.c_str(), "", caseID++,
3133*35238bceSAndroid Build Coastguard Worker                             (InvalidShaderCompilerCase::InvalidityType)invalidityType, numLookups,
3134*35238bceSAndroid Build Coastguard Worker                             (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));
3135*35238bceSAndroid Build Coastguard Worker                     }
3136*35238bceSAndroid Build Coastguard Worker                 }
3137*35238bceSAndroid Build Coastguard Worker             }
3138*35238bceSAndroid Build Coastguard Worker         }
3139*35238bceSAndroid Build Coastguard Worker     }
3140*35238bceSAndroid Build Coastguard Worker 
3141*35238bceSAndroid Build Coastguard Worker     // Loop shader compilation cases.
3142*35238bceSAndroid Build Coastguard Worker 
3143*35238bceSAndroid Build Coastguard Worker     {
3144*35238bceSAndroid Build Coastguard Worker         static const int loopIterCounts[]    = {10, 100, 1000};
3145*35238bceSAndroid Build Coastguard Worker         static const int maxLoopNestingDepth = 3;
3146*35238bceSAndroid Build Coastguard Worker         static const int maxTotalLoopIterations =
3147*35238bceSAndroid Build Coastguard Worker             2000; // If <loop iteration count> ** <loop nesting depth> (where ** is exponentiation) exceeds this, don't generate the case.
3148*35238bceSAndroid Build Coastguard Worker 
3149*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *validLoopGroup = new TestCaseGroup(context, "loop", "Shader Compiler Loop Cases");
3150*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *invalidCharLoopGroup =
3151*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "loop", "Invalid Character Shader Compiler Loop Cases");
3152*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *semanticErrorLoopGroup =
3153*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "loop", "Semantic Error Shader Compiler Loop Cases");
3154*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *cacheLoopGroup = new TestCaseGroup(context, "loop", "Shader Compiler Loop Cache Cases");
3155*35238bceSAndroid Build Coastguard Worker         validGroup->addChild(validLoopGroup);
3156*35238bceSAndroid Build Coastguard Worker         invalidCharGroup->addChild(invalidCharLoopGroup);
3157*35238bceSAndroid Build Coastguard Worker         semanticErrorGroup->addChild(semanticErrorLoopGroup);
3158*35238bceSAndroid Build Coastguard Worker         cacheGroup->addChild(cacheLoopGroup);
3159*35238bceSAndroid Build Coastguard Worker 
3160*35238bceSAndroid Build Coastguard Worker         for (int loopType = 0; loopType < (int)LOOP_LAST; loopType++)
3161*35238bceSAndroid Build Coastguard Worker         {
3162*35238bceSAndroid Build Coastguard Worker             const char *loopTypeName = loopType == (int)LOOP_TYPE_STATIC  ? "static" :
3163*35238bceSAndroid Build Coastguard Worker                                        loopType == (int)LOOP_TYPE_UNIFORM ? "uniform" :
3164*35238bceSAndroid Build Coastguard Worker                                        loopType == (int)LOOP_TYPE_DYNAMIC ? "dynamic" :
3165*35238bceSAndroid Build Coastguard Worker                                                                             DE_NULL;
3166*35238bceSAndroid Build Coastguard Worker 
3167*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(loopTypeName != DE_NULL);
3168*35238bceSAndroid Build Coastguard Worker 
3169*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *validLoopTypeGroup         = new TestCaseGroup(context, loopTypeName, "");
3170*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *invalidCharLoopTypeGroup   = new TestCaseGroup(context, loopTypeName, "");
3171*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *semanticErrorLoopTypeGroup = new TestCaseGroup(context, loopTypeName, "");
3172*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *cacheLoopTypeGroup         = new TestCaseGroup(context, loopTypeName, "");
3173*35238bceSAndroid Build Coastguard Worker             validLoopGroup->addChild(validLoopTypeGroup);
3174*35238bceSAndroid Build Coastguard Worker             invalidCharLoopGroup->addChild(invalidCharLoopTypeGroup);
3175*35238bceSAndroid Build Coastguard Worker             semanticErrorLoopGroup->addChild(semanticErrorLoopTypeGroup);
3176*35238bceSAndroid Build Coastguard Worker             cacheLoopGroup->addChild(cacheLoopTypeGroup);
3177*35238bceSAndroid Build Coastguard Worker 
3178*35238bceSAndroid Build Coastguard Worker             for (int isFrag = 0; isFrag <= 1; isFrag++)
3179*35238bceSAndroid Build Coastguard Worker             {
3180*35238bceSAndroid Build Coastguard Worker                 bool isVertex           = isFrag == 0;
3181*35238bceSAndroid Build Coastguard Worker                 const char *vertFragStr = isVertex ? "vertex" : "fragment";
3182*35238bceSAndroid Build Coastguard Worker 
3183*35238bceSAndroid Build Coastguard Worker                 // \note Non-static loop cases with different iteration counts have identical shaders, so only make one of each.
3184*35238bceSAndroid Build Coastguard Worker                 int loopIterCountMaxNdx = loopType != (int)LOOP_TYPE_STATIC ? 1 : DE_LENGTH_OF_ARRAY(loopIterCounts);
3185*35238bceSAndroid Build Coastguard Worker 
3186*35238bceSAndroid Build Coastguard Worker                 for (int nestingDepth = 1; nestingDepth <= maxLoopNestingDepth; nestingDepth++)
3187*35238bceSAndroid Build Coastguard Worker                 {
3188*35238bceSAndroid Build Coastguard Worker                     for (int loopIterCountNdx = 0; loopIterCountNdx < loopIterCountMaxNdx; loopIterCountNdx++)
3189*35238bceSAndroid Build Coastguard Worker                     {
3190*35238bceSAndroid Build Coastguard Worker                         int numIterations = loopIterCounts[loopIterCountNdx];
3191*35238bceSAndroid Build Coastguard Worker 
3192*35238bceSAndroid Build Coastguard Worker                         if (deFloatPow((float)numIterations, (float)nestingDepth) > (float)maxTotalLoopIterations)
3193*35238bceSAndroid Build Coastguard Worker                             continue; // Don't generate too heavy tasks.
3194*35238bceSAndroid Build Coastguard Worker 
3195*35238bceSAndroid Build Coastguard Worker                         string validCaseName = de::toString(numIterations) + "_iterations_" +
3196*35238bceSAndroid Build Coastguard Worker                                                de::toString(nestingDepth) + "_levels_" + vertFragStr;
3197*35238bceSAndroid Build Coastguard Worker 
3198*35238bceSAndroid Build Coastguard Worker                         // Valid shader case, no-cache and cache versions.
3199*35238bceSAndroid Build Coastguard Worker 
3200*35238bceSAndroid Build Coastguard Worker                         validLoopTypeGroup->addChild(new ShaderCompilerLoopCase(
3201*35238bceSAndroid Build Coastguard Worker                             context, validCaseName.c_str(), "", caseID++, true /* avoid cache */, false, isVertex,
3202*35238bceSAndroid Build Coastguard Worker                             (LoopType)loopType, numIterations, nestingDepth));
3203*35238bceSAndroid Build Coastguard Worker                         cacheLoopTypeGroup->addChild(new ShaderCompilerLoopCase(
3204*35238bceSAndroid Build Coastguard Worker                             context, validCaseName.c_str(), "", caseID++, false /* allow cache */, false, isVertex,
3205*35238bceSAndroid Build Coastguard Worker                             (LoopType)loopType, numIterations, nestingDepth));
3206*35238bceSAndroid Build Coastguard Worker 
3207*35238bceSAndroid Build Coastguard Worker                         // Invalid shader cases.
3208*35238bceSAndroid Build Coastguard Worker 
3209*35238bceSAndroid Build Coastguard Worker                         for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST;
3210*35238bceSAndroid Build Coastguard Worker                              invalidityType++)
3211*35238bceSAndroid Build Coastguard Worker                         {
3212*35238bceSAndroid Build Coastguard Worker                             TestCaseGroup *curInvalidGroup =
3213*35238bceSAndroid Build Coastguard Worker                                 invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR ?
3214*35238bceSAndroid Build Coastguard Worker                                     invalidCharLoopTypeGroup :
3215*35238bceSAndroid Build Coastguard Worker                                 invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR ?
3216*35238bceSAndroid Build Coastguard Worker                                     semanticErrorLoopTypeGroup :
3217*35238bceSAndroid Build Coastguard Worker                                     DE_NULL;
3218*35238bceSAndroid Build Coastguard Worker 
3219*35238bceSAndroid Build Coastguard Worker                             DE_ASSERT(curInvalidGroup != DE_NULL);
3220*35238bceSAndroid Build Coastguard Worker 
3221*35238bceSAndroid Build Coastguard Worker                             string invalidCaseName = de::toString(nestingDepth) + "_levels_" + vertFragStr;
3222*35238bceSAndroid Build Coastguard Worker 
3223*35238bceSAndroid Build Coastguard Worker                             if (loopType == (int)LOOP_TYPE_STATIC)
3224*35238bceSAndroid Build Coastguard Worker                                 invalidCaseName =
3225*35238bceSAndroid Build Coastguard Worker                                     de::toString(numIterations) + "_iterations_" +
3226*35238bceSAndroid Build Coastguard Worker                                     invalidCaseName; // \note For invalid, non-static loop cases the iteration count means nothing (since no uniforms or attributes are set).
3227*35238bceSAndroid Build Coastguard Worker 
3228*35238bceSAndroid Build Coastguard Worker                             curInvalidGroup->addChild(new InvalidShaderCompilerLoopCase(
3229*35238bceSAndroid Build Coastguard Worker                                 context, invalidCaseName.c_str(), "", caseID++,
3230*35238bceSAndroid Build Coastguard Worker                                 (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, (LoopType)loopType,
3231*35238bceSAndroid Build Coastguard Worker                                 numIterations, nestingDepth));
3232*35238bceSAndroid Build Coastguard Worker                         }
3233*35238bceSAndroid Build Coastguard Worker                     }
3234*35238bceSAndroid Build Coastguard Worker                 }
3235*35238bceSAndroid Build Coastguard Worker             }
3236*35238bceSAndroid Build Coastguard Worker         }
3237*35238bceSAndroid Build Coastguard Worker     }
3238*35238bceSAndroid Build Coastguard Worker 
3239*35238bceSAndroid Build Coastguard Worker     // Multiplication shader compilation cases.
3240*35238bceSAndroid Build Coastguard Worker 
3241*35238bceSAndroid Build Coastguard Worker     {
3242*35238bceSAndroid Build Coastguard Worker         static const int multiplicationCounts[] = {10, 100, 1000};
3243*35238bceSAndroid Build Coastguard Worker 
3244*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *validMulGroup =
3245*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "multiplication", "Shader Compiler Multiplication Cases");
3246*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *invalidCharMulGroup =
3247*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "multiplication", "Invalid Character Shader Compiler Multiplication Cases");
3248*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *semanticErrorMulGroup =
3249*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "multiplication", "Semantic Error Shader Compiler Multiplication Cases");
3250*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *cacheMulGroup =
3251*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "multiplication", "Shader Compiler Multiplication Cache Cases");
3252*35238bceSAndroid Build Coastguard Worker         validGroup->addChild(validMulGroup);
3253*35238bceSAndroid Build Coastguard Worker         invalidCharGroup->addChild(invalidCharMulGroup);
3254*35238bceSAndroid Build Coastguard Worker         semanticErrorGroup->addChild(semanticErrorMulGroup);
3255*35238bceSAndroid Build Coastguard Worker         cacheGroup->addChild(cacheMulGroup);
3256*35238bceSAndroid Build Coastguard Worker 
3257*35238bceSAndroid Build Coastguard Worker         for (int isFrag = 0; isFrag <= 1; isFrag++)
3258*35238bceSAndroid Build Coastguard Worker         {
3259*35238bceSAndroid Build Coastguard Worker             bool isVertex           = isFrag == 0;
3260*35238bceSAndroid Build Coastguard Worker             const char *vertFragStr = isVertex ? "vertex" : "fragment";
3261*35238bceSAndroid Build Coastguard Worker 
3262*35238bceSAndroid Build Coastguard Worker             for (int operCountNdx = 0; operCountNdx < DE_LENGTH_OF_ARRAY(multiplicationCounts); operCountNdx++)
3263*35238bceSAndroid Build Coastguard Worker             {
3264*35238bceSAndroid Build Coastguard Worker                 int numOpers = multiplicationCounts[operCountNdx];
3265*35238bceSAndroid Build Coastguard Worker 
3266*35238bceSAndroid Build Coastguard Worker                 string caseName = de::toString(numOpers) + "_operations_" + vertFragStr;
3267*35238bceSAndroid Build Coastguard Worker 
3268*35238bceSAndroid Build Coastguard Worker                 // Valid shader case, no-cache and cache versions.
3269*35238bceSAndroid Build Coastguard Worker 
3270*35238bceSAndroid Build Coastguard Worker                 validMulGroup->addChild(new ShaderCompilerOperCase(
3271*35238bceSAndroid Build Coastguard Worker                     context, caseName.c_str(), "", caseID++, true /* avoid cache */, false, isVertex, "*", numOpers));
3272*35238bceSAndroid Build Coastguard Worker                 cacheMulGroup->addChild(new ShaderCompilerOperCase(
3273*35238bceSAndroid Build Coastguard Worker                     context, caseName.c_str(), "", caseID++, false /* allow cache */, false, isVertex, "*", numOpers));
3274*35238bceSAndroid Build Coastguard Worker 
3275*35238bceSAndroid Build Coastguard Worker                 // Invalid shader cases.
3276*35238bceSAndroid Build Coastguard Worker 
3277*35238bceSAndroid Build Coastguard Worker                 for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST;
3278*35238bceSAndroid Build Coastguard Worker                      invalidityType++)
3279*35238bceSAndroid Build Coastguard Worker                 {
3280*35238bceSAndroid Build Coastguard Worker                     TestCaseGroup *curInvalidGroup =
3281*35238bceSAndroid Build Coastguard Worker                         invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR ?
3282*35238bceSAndroid Build Coastguard Worker                             invalidCharMulGroup :
3283*35238bceSAndroid Build Coastguard Worker                         invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR ?
3284*35238bceSAndroid Build Coastguard Worker                             semanticErrorMulGroup :
3285*35238bceSAndroid Build Coastguard Worker                             DE_NULL;
3286*35238bceSAndroid Build Coastguard Worker 
3287*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(curInvalidGroup != DE_NULL);
3288*35238bceSAndroid Build Coastguard Worker 
3289*35238bceSAndroid Build Coastguard Worker                     curInvalidGroup->addChild(new InvalidShaderCompilerOperCase(
3290*35238bceSAndroid Build Coastguard Worker                         context, caseName.c_str(), "", caseID++,
3291*35238bceSAndroid Build Coastguard Worker                         (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, "*", numOpers));
3292*35238bceSAndroid Build Coastguard Worker                 }
3293*35238bceSAndroid Build Coastguard Worker             }
3294*35238bceSAndroid Build Coastguard Worker         }
3295*35238bceSAndroid Build Coastguard Worker     }
3296*35238bceSAndroid Build Coastguard Worker 
3297*35238bceSAndroid Build Coastguard Worker     // Mandelbrot shader compilation cases.
3298*35238bceSAndroid Build Coastguard Worker 
3299*35238bceSAndroid Build Coastguard Worker     {
3300*35238bceSAndroid Build Coastguard Worker         static const int mandelbrotIterationCounts[] = {32, 64, 128};
3301*35238bceSAndroid Build Coastguard Worker 
3302*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *validMandelbrotGroup =
3303*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "mandelbrot", "Shader Compiler Mandelbrot Fractal Cases");
3304*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *invalidCharMandelbrotGroup =
3305*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "mandelbrot", "Invalid Character Shader Compiler Mandelbrot Fractal Cases");
3306*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *semanticErrorMandelbrotGroup =
3307*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "mandelbrot", "Semantic Error Shader Compiler Mandelbrot Fractal Cases");
3308*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *cacheMandelbrotGroup =
3309*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, "mandelbrot", "Shader Compiler Mandelbrot Fractal Cache Cases");
3310*35238bceSAndroid Build Coastguard Worker         validGroup->addChild(validMandelbrotGroup);
3311*35238bceSAndroid Build Coastguard Worker         invalidCharGroup->addChild(invalidCharMandelbrotGroup);
3312*35238bceSAndroid Build Coastguard Worker         semanticErrorGroup->addChild(semanticErrorMandelbrotGroup);
3313*35238bceSAndroid Build Coastguard Worker         cacheGroup->addChild(cacheMandelbrotGroup);
3314*35238bceSAndroid Build Coastguard Worker 
3315*35238bceSAndroid Build Coastguard Worker         for (int iterCountNdx = 0; iterCountNdx < DE_LENGTH_OF_ARRAY(mandelbrotIterationCounts); iterCountNdx++)
3316*35238bceSAndroid Build Coastguard Worker         {
3317*35238bceSAndroid Build Coastguard Worker             int numFractalIterations = mandelbrotIterationCounts[iterCountNdx];
3318*35238bceSAndroid Build Coastguard Worker             string caseName          = de::toString(numFractalIterations) + "_iterations";
3319*35238bceSAndroid Build Coastguard Worker 
3320*35238bceSAndroid Build Coastguard Worker             // Valid shader case, no-cache and cache versions.
3321*35238bceSAndroid Build Coastguard Worker 
3322*35238bceSAndroid Build Coastguard Worker             validMandelbrotGroup->addChild(new ShaderCompilerMandelbrotCase(
3323*35238bceSAndroid Build Coastguard Worker                 context, caseName.c_str(), "", caseID++, true /* avoid cache */, false, numFractalIterations));
3324*35238bceSAndroid Build Coastguard Worker             cacheMandelbrotGroup->addChild(new ShaderCompilerMandelbrotCase(
3325*35238bceSAndroid Build Coastguard Worker                 context, caseName.c_str(), "", caseID++, false /* allow cache */, false, numFractalIterations));
3326*35238bceSAndroid Build Coastguard Worker 
3327*35238bceSAndroid Build Coastguard Worker             // Invalid shader cases.
3328*35238bceSAndroid Build Coastguard Worker 
3329*35238bceSAndroid Build Coastguard Worker             for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST;
3330*35238bceSAndroid Build Coastguard Worker                  invalidityType++)
3331*35238bceSAndroid Build Coastguard Worker             {
3332*35238bceSAndroid Build Coastguard Worker                 TestCaseGroup *curInvalidGroup =
3333*35238bceSAndroid Build Coastguard Worker                     invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR ?
3334*35238bceSAndroid Build Coastguard Worker                         invalidCharMandelbrotGroup :
3335*35238bceSAndroid Build Coastguard Worker                     invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR ?
3336*35238bceSAndroid Build Coastguard Worker                         semanticErrorMandelbrotGroup :
3337*35238bceSAndroid Build Coastguard Worker                         DE_NULL;
3338*35238bceSAndroid Build Coastguard Worker 
3339*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(curInvalidGroup != DE_NULL);
3340*35238bceSAndroid Build Coastguard Worker 
3341*35238bceSAndroid Build Coastguard Worker                 curInvalidGroup->addChild(new InvalidShaderCompilerMandelbrotCase(
3342*35238bceSAndroid Build Coastguard Worker                     context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType,
3343*35238bceSAndroid Build Coastguard Worker                     numFractalIterations));
3344*35238bceSAndroid Build Coastguard Worker             }
3345*35238bceSAndroid Build Coastguard Worker         }
3346*35238bceSAndroid Build Coastguard Worker     }
3347*35238bceSAndroid Build Coastguard Worker 
3348*35238bceSAndroid Build Coastguard Worker     // Cases testing cache behaviour when whitespace and comments are added.
3349*35238bceSAndroid Build Coastguard Worker 
3350*35238bceSAndroid Build Coastguard Worker     {
3351*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *whitespaceCommentCacheGroup = new TestCaseGroup(
3352*35238bceSAndroid Build Coastguard Worker             context, "cache_whitespace_comment", "Cases testing the effect of whitespace and comments on caching");
3353*35238bceSAndroid Build Coastguard Worker         parentGroup.addChild(whitespaceCommentCacheGroup);
3354*35238bceSAndroid Build Coastguard Worker 
3355*35238bceSAndroid Build Coastguard Worker         // \note Add just a small subset of the cases that were added above for the main performance tests.
3356*35238bceSAndroid Build Coastguard Worker 
3357*35238bceSAndroid Build Coastguard Worker         // Cases with both vertex and fragment variants.
3358*35238bceSAndroid Build Coastguard Worker         for (int isFrag = 0; isFrag <= 1; isFrag++)
3359*35238bceSAndroid Build Coastguard Worker         {
3360*35238bceSAndroid Build Coastguard Worker             bool isVertex        = isFrag == 0;
3361*35238bceSAndroid Build Coastguard Worker             string vtxFragSuffix = isVertex ? "_vertex" : "_fragment";
3362*35238bceSAndroid Build Coastguard Worker             string dirLightName  = "directional_2_lights" + vtxFragSuffix;
3363*35238bceSAndroid Build Coastguard Worker             string loopName      = "static_loop_100_iterations" + vtxFragSuffix;
3364*35238bceSAndroid Build Coastguard Worker             string multCase      = "multiplication_100_operations" + vtxFragSuffix;
3365*35238bceSAndroid Build Coastguard Worker 
3366*35238bceSAndroid Build Coastguard Worker             whitespaceCommentCacheGroup->addChild(new ShaderCompilerLightCase(
3367*35238bceSAndroid Build Coastguard Worker                 context, dirLightName.c_str(), "", caseID++, false, true, isVertex, 2, LIGHT_DIRECTIONAL));
3368*35238bceSAndroid Build Coastguard Worker             whitespaceCommentCacheGroup->addChild(new ShaderCompilerLoopCase(
3369*35238bceSAndroid Build Coastguard Worker                 context, loopName.c_str(), "", caseID++, false, true, isVertex, LOOP_TYPE_STATIC, 100, 1));
3370*35238bceSAndroid Build Coastguard Worker             whitespaceCommentCacheGroup->addChild(
3371*35238bceSAndroid Build Coastguard Worker                 new ShaderCompilerOperCase(context, multCase.c_str(), "", caseID++, false, true, isVertex, "*", 100));
3372*35238bceSAndroid Build Coastguard Worker         }
3373*35238bceSAndroid Build Coastguard Worker 
3374*35238bceSAndroid Build Coastguard Worker         // Cases that don't have vertex and fragment variants.
3375*35238bceSAndroid Build Coastguard Worker         whitespaceCommentCacheGroup->addChild(new ShaderCompilerTextureCase(context, "texture_4_lookups", "", caseID++,
3376*35238bceSAndroid Build Coastguard Worker                                                                             false, true, 4, CONDITIONAL_USAGE_NONE,
3377*35238bceSAndroid Build Coastguard Worker                                                                             CONDITIONAL_TYPE_STATIC));
3378*35238bceSAndroid Build Coastguard Worker         whitespaceCommentCacheGroup->addChild(
3379*35238bceSAndroid Build Coastguard Worker             new ShaderCompilerMandelbrotCase(context, "mandelbrot_32_operations", "", caseID++, false, true, 32));
3380*35238bceSAndroid Build Coastguard Worker     }
3381*35238bceSAndroid Build Coastguard Worker }
3382*35238bceSAndroid Build Coastguard Worker 
3383*35238bceSAndroid Build Coastguard Worker } // namespace Performance
3384*35238bceSAndroid Build Coastguard Worker } // namespace gles3
3385*35238bceSAndroid Build Coastguard Worker } // namespace deqp
3386