1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES 3.1 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 Tests for separate shader objects
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31fSeparateShaderTests.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
27*35238bceSAndroid Build Coastguard Worker #include "deString.h"
28*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "deSTLUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuResultCollector.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuRGBA.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "gluCallLogWrapper.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "gluVarType.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "glsShaderLibrary.hpp"
45*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
46*35238bceSAndroid Build Coastguard Worker #include "glwDefs.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
48*35238bceSAndroid Build Coastguard Worker
49*35238bceSAndroid Build Coastguard Worker #include <cstdarg>
50*35238bceSAndroid Build Coastguard Worker #include <algorithm>
51*35238bceSAndroid Build Coastguard Worker #include <map>
52*35238bceSAndroid Build Coastguard Worker #include <sstream>
53*35238bceSAndroid Build Coastguard Worker #include <string>
54*35238bceSAndroid Build Coastguard Worker #include <set>
55*35238bceSAndroid Build Coastguard Worker #include <vector>
56*35238bceSAndroid Build Coastguard Worker
57*35238bceSAndroid Build Coastguard Worker namespace deqp
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker namespace gles31
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker namespace Functional
62*35238bceSAndroid Build Coastguard Worker {
63*35238bceSAndroid Build Coastguard Worker namespace
64*35238bceSAndroid Build Coastguard Worker {
65*35238bceSAndroid Build Coastguard Worker
66*35238bceSAndroid Build Coastguard Worker using de::MovePtr;
67*35238bceSAndroid Build Coastguard Worker using de::Random;
68*35238bceSAndroid Build Coastguard Worker using de::UniquePtr;
69*35238bceSAndroid Build Coastguard Worker using glu::CallLogWrapper;
70*35238bceSAndroid Build Coastguard Worker using glu::DataType;
71*35238bceSAndroid Build Coastguard Worker using glu::FragmentSource;
72*35238bceSAndroid Build Coastguard Worker using glu::Precision;
73*35238bceSAndroid Build Coastguard Worker using glu::Program;
74*35238bceSAndroid Build Coastguard Worker using glu::ProgramPipeline;
75*35238bceSAndroid Build Coastguard Worker using glu::ProgramSeparable;
76*35238bceSAndroid Build Coastguard Worker using glu::ProgramSources;
77*35238bceSAndroid Build Coastguard Worker using glu::RenderContext;
78*35238bceSAndroid Build Coastguard Worker using glu::ShaderProgram;
79*35238bceSAndroid Build Coastguard Worker using glu::ShaderType;
80*35238bceSAndroid Build Coastguard Worker using glu::Storage;
81*35238bceSAndroid Build Coastguard Worker using glu::VariableDeclaration;
82*35238bceSAndroid Build Coastguard Worker using glu::VarType;
83*35238bceSAndroid Build Coastguard Worker using glu::VertexSource;
84*35238bceSAndroid Build Coastguard Worker using std::map;
85*35238bceSAndroid Build Coastguard Worker using std::ostringstream;
86*35238bceSAndroid Build Coastguard Worker using std::set;
87*35238bceSAndroid Build Coastguard Worker using std::string;
88*35238bceSAndroid Build Coastguard Worker using std::vector;
89*35238bceSAndroid Build Coastguard Worker using tcu::MessageBuilder;
90*35238bceSAndroid Build Coastguard Worker using tcu::RenderTarget;
91*35238bceSAndroid Build Coastguard Worker using tcu::ResultCollector;
92*35238bceSAndroid Build Coastguard Worker using tcu::StringTemplate;
93*35238bceSAndroid Build Coastguard Worker using tcu::Surface;
94*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
95*35238bceSAndroid Build Coastguard Worker
96*35238bceSAndroid Build Coastguard Worker using namespace glw;
97*35238bceSAndroid Build Coastguard Worker
98*35238bceSAndroid Build Coastguard Worker #define LOG_CALL(CALL) \
99*35238bceSAndroid Build Coastguard Worker do \
100*35238bceSAndroid Build Coastguard Worker { \
101*35238bceSAndroid Build Coastguard Worker enableLogging(true); \
102*35238bceSAndroid Build Coastguard Worker CALL; \
103*35238bceSAndroid Build Coastguard Worker enableLogging(false); \
104*35238bceSAndroid Build Coastguard Worker } while (false)
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker enum
107*35238bceSAndroid Build Coastguard Worker {
108*35238bceSAndroid Build Coastguard Worker VIEWPORT_SIZE = 128
109*35238bceSAndroid Build Coastguard Worker };
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker enum VaryingInterpolation
112*35238bceSAndroid Build Coastguard Worker {
113*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_SMOOTH = 0,
114*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_FLAT,
115*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_CENTROID,
116*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_DEFAULT,
117*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_RANDOM,
118*35238bceSAndroid Build Coastguard Worker
119*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_LAST
120*35238bceSAndroid Build Coastguard Worker };
121*35238bceSAndroid Build Coastguard Worker
randomType(Random & rnd)122*35238bceSAndroid Build Coastguard Worker DataType randomType(Random &rnd)
123*35238bceSAndroid Build Coastguard Worker {
124*35238bceSAndroid Build Coastguard Worker using namespace glu;
125*35238bceSAndroid Build Coastguard Worker
126*35238bceSAndroid Build Coastguard Worker if (rnd.getInt(0, 7) == 0)
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker const int numCols = rnd.getInt(2, 4), numRows = rnd.getInt(2, 4);
129*35238bceSAndroid Build Coastguard Worker
130*35238bceSAndroid Build Coastguard Worker return getDataTypeMatrix(numCols, numRows);
131*35238bceSAndroid Build Coastguard Worker }
132*35238bceSAndroid Build Coastguard Worker else
133*35238bceSAndroid Build Coastguard Worker {
134*35238bceSAndroid Build Coastguard Worker static const DataType s_types[] = {TYPE_FLOAT, TYPE_INT, TYPE_UINT};
135*35238bceSAndroid Build Coastguard Worker static const float s_weights[] = {3.0, 1.0, 1.0};
136*35238bceSAndroid Build Coastguard Worker const int size = rnd.getInt(1, 4);
137*35238bceSAndroid Build Coastguard Worker const DataType scalarType =
138*35238bceSAndroid Build Coastguard Worker rnd.chooseWeighted<DataType>(DE_ARRAY_BEGIN(s_types), DE_ARRAY_END(s_types), DE_ARRAY_BEGIN(s_weights));
139*35238bceSAndroid Build Coastguard Worker return getDataTypeVector(scalarType, size);
140*35238bceSAndroid Build Coastguard Worker }
141*35238bceSAndroid Build Coastguard Worker
142*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
143*35238bceSAndroid Build Coastguard Worker return TYPE_INVALID;
144*35238bceSAndroid Build Coastguard Worker }
145*35238bceSAndroid Build Coastguard Worker
randomInterpolation(Random & rnd)146*35238bceSAndroid Build Coastguard Worker VaryingInterpolation randomInterpolation(Random &rnd)
147*35238bceSAndroid Build Coastguard Worker {
148*35238bceSAndroid Build Coastguard Worker static const VaryingInterpolation s_validInterpolations[] = {
149*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_SMOOTH,
150*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_FLAT,
151*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_CENTROID,
152*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_DEFAULT,
153*35238bceSAndroid Build Coastguard Worker };
154*35238bceSAndroid Build Coastguard Worker return s_validInterpolations[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_validInterpolations) - 1)];
155*35238bceSAndroid Build Coastguard Worker }
156*35238bceSAndroid Build Coastguard Worker
getGluInterpolation(VaryingInterpolation interpolation)157*35238bceSAndroid Build Coastguard Worker glu::Interpolation getGluInterpolation(VaryingInterpolation interpolation)
158*35238bceSAndroid Build Coastguard Worker {
159*35238bceSAndroid Build Coastguard Worker switch (interpolation)
160*35238bceSAndroid Build Coastguard Worker {
161*35238bceSAndroid Build Coastguard Worker case VARYINGINTERPOLATION_SMOOTH:
162*35238bceSAndroid Build Coastguard Worker return glu::INTERPOLATION_SMOOTH;
163*35238bceSAndroid Build Coastguard Worker case VARYINGINTERPOLATION_FLAT:
164*35238bceSAndroid Build Coastguard Worker return glu::INTERPOLATION_FLAT;
165*35238bceSAndroid Build Coastguard Worker case VARYINGINTERPOLATION_CENTROID:
166*35238bceSAndroid Build Coastguard Worker return glu::INTERPOLATION_CENTROID;
167*35238bceSAndroid Build Coastguard Worker case VARYINGINTERPOLATION_DEFAULT:
168*35238bceSAndroid Build Coastguard Worker return glu::INTERPOLATION_LAST; //!< Last means no qualifier, i.e. default
169*35238bceSAndroid Build Coastguard Worker default:
170*35238bceSAndroid Build Coastguard Worker DE_FATAL("Invalid interpolation");
171*35238bceSAndroid Build Coastguard Worker return glu::INTERPOLATION_LAST;
172*35238bceSAndroid Build Coastguard Worker }
173*35238bceSAndroid Build Coastguard Worker }
174*35238bceSAndroid Build Coastguard Worker
175*35238bceSAndroid Build Coastguard Worker // used only for debug quick checks
176*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG)
getVaryingInterpolation(glu::Interpolation interpolation)177*35238bceSAndroid Build Coastguard Worker VaryingInterpolation getVaryingInterpolation(glu::Interpolation interpolation)
178*35238bceSAndroid Build Coastguard Worker {
179*35238bceSAndroid Build Coastguard Worker switch (interpolation)
180*35238bceSAndroid Build Coastguard Worker {
181*35238bceSAndroid Build Coastguard Worker case glu::INTERPOLATION_SMOOTH:
182*35238bceSAndroid Build Coastguard Worker return VARYINGINTERPOLATION_SMOOTH;
183*35238bceSAndroid Build Coastguard Worker case glu::INTERPOLATION_FLAT:
184*35238bceSAndroid Build Coastguard Worker return VARYINGINTERPOLATION_FLAT;
185*35238bceSAndroid Build Coastguard Worker case glu::INTERPOLATION_CENTROID:
186*35238bceSAndroid Build Coastguard Worker return VARYINGINTERPOLATION_CENTROID;
187*35238bceSAndroid Build Coastguard Worker case glu::INTERPOLATION_LAST:
188*35238bceSAndroid Build Coastguard Worker return VARYINGINTERPOLATION_DEFAULT; //!< Last means no qualifier, i.e. default
189*35238bceSAndroid Build Coastguard Worker default:
190*35238bceSAndroid Build Coastguard Worker DE_FATAL("Invalid interpolation");
191*35238bceSAndroid Build Coastguard Worker return VARYINGINTERPOLATION_LAST;
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker #endif
195*35238bceSAndroid Build Coastguard Worker
196*35238bceSAndroid Build Coastguard Worker enum BindingKind
197*35238bceSAndroid Build Coastguard Worker {
198*35238bceSAndroid Build Coastguard Worker BINDING_NAME,
199*35238bceSAndroid Build Coastguard Worker BINDING_LOCATION,
200*35238bceSAndroid Build Coastguard Worker BINDING_LAST
201*35238bceSAndroid Build Coastguard Worker };
202*35238bceSAndroid Build Coastguard Worker
randomBinding(Random & rnd)203*35238bceSAndroid Build Coastguard Worker BindingKind randomBinding(Random &rnd)
204*35238bceSAndroid Build Coastguard Worker {
205*35238bceSAndroid Build Coastguard Worker return rnd.getBool() ? BINDING_LOCATION : BINDING_NAME;
206*35238bceSAndroid Build Coastguard Worker }
207*35238bceSAndroid Build Coastguard Worker
printInputColor(ostringstream & oss,const VariableDeclaration & input)208*35238bceSAndroid Build Coastguard Worker void printInputColor(ostringstream &oss, const VariableDeclaration &input)
209*35238bceSAndroid Build Coastguard Worker {
210*35238bceSAndroid Build Coastguard Worker using namespace glu;
211*35238bceSAndroid Build Coastguard Worker
212*35238bceSAndroid Build Coastguard Worker const DataType basicType = input.varType.getBasicType();
213*35238bceSAndroid Build Coastguard Worker string exp = input.name;
214*35238bceSAndroid Build Coastguard Worker
215*35238bceSAndroid Build Coastguard Worker switch (getDataTypeScalarType(basicType))
216*35238bceSAndroid Build Coastguard Worker {
217*35238bceSAndroid Build Coastguard Worker case TYPE_FLOAT:
218*35238bceSAndroid Build Coastguard Worker break;
219*35238bceSAndroid Build Coastguard Worker
220*35238bceSAndroid Build Coastguard Worker case TYPE_INT:
221*35238bceSAndroid Build Coastguard Worker case TYPE_UINT:
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker DataType floatType = getDataTypeFloatScalars(basicType);
224*35238bceSAndroid Build Coastguard Worker exp = string() + "(" + getDataTypeName(floatType) + "(" + exp + ") / 255.0" + ")";
225*35238bceSAndroid Build Coastguard Worker break;
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker
228*35238bceSAndroid Build Coastguard Worker default:
229*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
230*35238bceSAndroid Build Coastguard Worker }
231*35238bceSAndroid Build Coastguard Worker
232*35238bceSAndroid Build Coastguard Worker if (isDataTypeScalarOrVector(basicType))
233*35238bceSAndroid Build Coastguard Worker {
234*35238bceSAndroid Build Coastguard Worker switch (getDataTypeScalarSize(basicType))
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker case 1:
237*35238bceSAndroid Build Coastguard Worker oss << "hsv(vec3(" << exp << ", 1.0, 1.0))";
238*35238bceSAndroid Build Coastguard Worker break;
239*35238bceSAndroid Build Coastguard Worker case 2:
240*35238bceSAndroid Build Coastguard Worker oss << "hsv(vec3(" << exp << ", 1.0))";
241*35238bceSAndroid Build Coastguard Worker break;
242*35238bceSAndroid Build Coastguard Worker case 3:
243*35238bceSAndroid Build Coastguard Worker oss << "vec4(" << exp << ", 1.0)";
244*35238bceSAndroid Build Coastguard Worker break;
245*35238bceSAndroid Build Coastguard Worker case 4:
246*35238bceSAndroid Build Coastguard Worker oss << exp;
247*35238bceSAndroid Build Coastguard Worker break;
248*35238bceSAndroid Build Coastguard Worker default:
249*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
250*35238bceSAndroid Build Coastguard Worker }
251*35238bceSAndroid Build Coastguard Worker }
252*35238bceSAndroid Build Coastguard Worker else if (isDataTypeMatrix(basicType))
253*35238bceSAndroid Build Coastguard Worker {
254*35238bceSAndroid Build Coastguard Worker int rows = getDataTypeMatrixNumRows(basicType);
255*35238bceSAndroid Build Coastguard Worker int columns = getDataTypeMatrixNumColumns(basicType);
256*35238bceSAndroid Build Coastguard Worker
257*35238bceSAndroid Build Coastguard Worker if (rows == columns)
258*35238bceSAndroid Build Coastguard Worker oss << "hsv(vec3(determinant(" << exp << ")))";
259*35238bceSAndroid Build Coastguard Worker else
260*35238bceSAndroid Build Coastguard Worker {
261*35238bceSAndroid Build Coastguard Worker if (rows != 3 && columns >= 3)
262*35238bceSAndroid Build Coastguard Worker {
263*35238bceSAndroid Build Coastguard Worker exp = "transpose(" + exp + ")";
264*35238bceSAndroid Build Coastguard Worker std::swap(rows, columns);
265*35238bceSAndroid Build Coastguard Worker }
266*35238bceSAndroid Build Coastguard Worker exp = exp + "[0]";
267*35238bceSAndroid Build Coastguard Worker if (rows > 3)
268*35238bceSAndroid Build Coastguard Worker exp = exp + ".xyz";
269*35238bceSAndroid Build Coastguard Worker oss << "hsv(" << exp << ")";
270*35238bceSAndroid Build Coastguard Worker }
271*35238bceSAndroid Build Coastguard Worker }
272*35238bceSAndroid Build Coastguard Worker else
273*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
274*35238bceSAndroid Build Coastguard Worker }
275*35238bceSAndroid Build Coastguard Worker
276*35238bceSAndroid Build Coastguard Worker // Representation for the varyings between vertex and fragment shaders
277*35238bceSAndroid Build Coastguard Worker
278*35238bceSAndroid Build Coastguard Worker struct VaryingParams
279*35238bceSAndroid Build Coastguard Worker {
VaryingParamsdeqp::gles31::Functional::__anonf652bf1a0111::VaryingParams280*35238bceSAndroid Build Coastguard Worker VaryingParams(void)
281*35238bceSAndroid Build Coastguard Worker : count(0)
282*35238bceSAndroid Build Coastguard Worker , type(glu::TYPE_LAST)
283*35238bceSAndroid Build Coastguard Worker , binding(BINDING_LAST)
284*35238bceSAndroid Build Coastguard Worker , vtxInterp(VARYINGINTERPOLATION_LAST)
285*35238bceSAndroid Build Coastguard Worker , frgInterp(VARYINGINTERPOLATION_LAST)
286*35238bceSAndroid Build Coastguard Worker {
287*35238bceSAndroid Build Coastguard Worker }
288*35238bceSAndroid Build Coastguard Worker
289*35238bceSAndroid Build Coastguard Worker int count;
290*35238bceSAndroid Build Coastguard Worker DataType type;
291*35238bceSAndroid Build Coastguard Worker BindingKind binding;
292*35238bceSAndroid Build Coastguard Worker VaryingInterpolation vtxInterp;
293*35238bceSAndroid Build Coastguard Worker VaryingInterpolation frgInterp;
294*35238bceSAndroid Build Coastguard Worker };
295*35238bceSAndroid Build Coastguard Worker
296*35238bceSAndroid Build Coastguard Worker struct VaryingInterface
297*35238bceSAndroid Build Coastguard Worker {
298*35238bceSAndroid Build Coastguard Worker vector<VariableDeclaration> vtxOutputs;
299*35238bceSAndroid Build Coastguard Worker vector<VariableDeclaration> frgInputs;
300*35238bceSAndroid Build Coastguard Worker };
301*35238bceSAndroid Build Coastguard Worker
302*35238bceSAndroid Build Coastguard Worker // Generate corresponding input and output variable declarations that may vary
303*35238bceSAndroid Build Coastguard Worker // in compatible ways.
304*35238bceSAndroid Build Coastguard Worker
chooseInterpolation(VaryingInterpolation param,DataType type,Random & rnd)305*35238bceSAndroid Build Coastguard Worker VaryingInterpolation chooseInterpolation(VaryingInterpolation param, DataType type, Random &rnd)
306*35238bceSAndroid Build Coastguard Worker {
307*35238bceSAndroid Build Coastguard Worker if (glu::getDataTypeScalarType(type) != glu::TYPE_FLOAT)
308*35238bceSAndroid Build Coastguard Worker return VARYINGINTERPOLATION_FLAT;
309*35238bceSAndroid Build Coastguard Worker
310*35238bceSAndroid Build Coastguard Worker if (param == VARYINGINTERPOLATION_RANDOM)
311*35238bceSAndroid Build Coastguard Worker return randomInterpolation(rnd);
312*35238bceSAndroid Build Coastguard Worker
313*35238bceSAndroid Build Coastguard Worker return param;
314*35238bceSAndroid Build Coastguard Worker }
315*35238bceSAndroid Build Coastguard Worker
isSSOCompatibleInterpolation(VaryingInterpolation vertexInterpolation,VaryingInterpolation fragmentInterpolation)316*35238bceSAndroid Build Coastguard Worker bool isSSOCompatibleInterpolation(VaryingInterpolation vertexInterpolation, VaryingInterpolation fragmentInterpolation)
317*35238bceSAndroid Build Coastguard Worker {
318*35238bceSAndroid Build Coastguard Worker // interpolations must be fully specified
319*35238bceSAndroid Build Coastguard Worker DE_ASSERT(vertexInterpolation != VARYINGINTERPOLATION_RANDOM);
320*35238bceSAndroid Build Coastguard Worker DE_ASSERT(vertexInterpolation < VARYINGINTERPOLATION_LAST);
321*35238bceSAndroid Build Coastguard Worker DE_ASSERT(fragmentInterpolation != VARYINGINTERPOLATION_RANDOM);
322*35238bceSAndroid Build Coastguard Worker DE_ASSERT(fragmentInterpolation < VARYINGINTERPOLATION_LAST);
323*35238bceSAndroid Build Coastguard Worker
324*35238bceSAndroid Build Coastguard Worker // interpolation can only be either smooth or flat. Auxiliary storage does not matter.
325*35238bceSAndroid Build Coastguard Worker const bool isSmoothVtx =
326*35238bceSAndroid Build Coastguard Worker (vertexInterpolation == VARYINGINTERPOLATION_SMOOTH) || //!< trivial
327*35238bceSAndroid Build Coastguard Worker (vertexInterpolation == VARYINGINTERPOLATION_DEFAULT) || //!< default to smooth
328*35238bceSAndroid Build Coastguard Worker (vertexInterpolation == VARYINGINTERPOLATION_CENTROID); //!< default to smooth, ignore storage
329*35238bceSAndroid Build Coastguard Worker const bool isSmoothFrag =
330*35238bceSAndroid Build Coastguard Worker (fragmentInterpolation == VARYINGINTERPOLATION_SMOOTH) || //!< trivial
331*35238bceSAndroid Build Coastguard Worker (fragmentInterpolation == VARYINGINTERPOLATION_DEFAULT) || //!< default to smooth
332*35238bceSAndroid Build Coastguard Worker (fragmentInterpolation == VARYINGINTERPOLATION_CENTROID); //!< default to smooth, ignore storage
333*35238bceSAndroid Build Coastguard Worker // Khronos bug #12630: flat / smooth qualifiers must match in SSO
334*35238bceSAndroid Build Coastguard Worker return isSmoothVtx == isSmoothFrag;
335*35238bceSAndroid Build Coastguard Worker }
336*35238bceSAndroid Build Coastguard Worker
genVaryingInterface(const VaryingParams & params,Random & rnd)337*35238bceSAndroid Build Coastguard Worker VaryingInterface genVaryingInterface(const VaryingParams ¶ms, Random &rnd)
338*35238bceSAndroid Build Coastguard Worker {
339*35238bceSAndroid Build Coastguard Worker using namespace glu;
340*35238bceSAndroid Build Coastguard Worker
341*35238bceSAndroid Build Coastguard Worker VaryingInterface ret;
342*35238bceSAndroid Build Coastguard Worker int offset = 0;
343*35238bceSAndroid Build Coastguard Worker
344*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < params.count; ++varNdx)
345*35238bceSAndroid Build Coastguard Worker {
346*35238bceSAndroid Build Coastguard Worker const BindingKind binding = ((params.binding == BINDING_LAST) ? randomBinding(rnd) : params.binding);
347*35238bceSAndroid Build Coastguard Worker const DataType type = ((params.type == TYPE_LAST) ? randomType(rnd) : params.type);
348*35238bceSAndroid Build Coastguard Worker const VaryingInterpolation vtxInterp = chooseInterpolation(params.vtxInterp, type, rnd);
349*35238bceSAndroid Build Coastguard Worker const VaryingInterpolation frgInterp = chooseInterpolation(params.frgInterp, type, rnd);
350*35238bceSAndroid Build Coastguard Worker const VaryingInterpolation vtxCompatInterp =
351*35238bceSAndroid Build Coastguard Worker (isSSOCompatibleInterpolation(vtxInterp, frgInterp)) ? (vtxInterp) : (frgInterp);
352*35238bceSAndroid Build Coastguard Worker const int loc = ((binding == BINDING_LOCATION) ? offset : -1);
353*35238bceSAndroid Build Coastguard Worker const string ndxStr = de::toString(varNdx);
354*35238bceSAndroid Build Coastguard Worker const string vtxName = ((binding == BINDING_NAME) ? "var" + ndxStr : "vtxVar" + ndxStr);
355*35238bceSAndroid Build Coastguard Worker const string frgName = ((binding == BINDING_NAME) ? "var" + ndxStr : "frgVar" + ndxStr);
356*35238bceSAndroid Build Coastguard Worker const VarType varType(type, PRECISION_HIGHP);
357*35238bceSAndroid Build Coastguard Worker
358*35238bceSAndroid Build Coastguard Worker offset += getDataTypeNumLocations(type);
359*35238bceSAndroid Build Coastguard Worker
360*35238bceSAndroid Build Coastguard Worker // Over 16 locations aren't necessarily supported, so halt here.
361*35238bceSAndroid Build Coastguard Worker if (offset > 16)
362*35238bceSAndroid Build Coastguard Worker break;
363*35238bceSAndroid Build Coastguard Worker
364*35238bceSAndroid Build Coastguard Worker ret.vtxOutputs.push_back(
365*35238bceSAndroid Build Coastguard Worker VariableDeclaration(varType, vtxName, STORAGE_OUT, getGluInterpolation(vtxCompatInterp), loc));
366*35238bceSAndroid Build Coastguard Worker ret.frgInputs.push_back(VariableDeclaration(varType, frgName, STORAGE_IN, getGluInterpolation(frgInterp), loc));
367*35238bceSAndroid Build Coastguard Worker }
368*35238bceSAndroid Build Coastguard Worker
369*35238bceSAndroid Build Coastguard Worker return ret;
370*35238bceSAndroid Build Coastguard Worker }
371*35238bceSAndroid Build Coastguard Worker
372*35238bceSAndroid Build Coastguard Worker // Create vertex output variable declarations that are maximally compatible
373*35238bceSAndroid Build Coastguard Worker // with the fragment input variables.
374*35238bceSAndroid Build Coastguard Worker
varyingCompatVtxOutputs(const VaryingInterface & varyings)375*35238bceSAndroid Build Coastguard Worker vector<VariableDeclaration> varyingCompatVtxOutputs(const VaryingInterface &varyings)
376*35238bceSAndroid Build Coastguard Worker {
377*35238bceSAndroid Build Coastguard Worker vector<VariableDeclaration> outputs = varyings.vtxOutputs;
378*35238bceSAndroid Build Coastguard Worker
379*35238bceSAndroid Build Coastguard Worker for (size_t i = 0; i < outputs.size(); ++i)
380*35238bceSAndroid Build Coastguard Worker {
381*35238bceSAndroid Build Coastguard Worker outputs[i].interpolation = varyings.frgInputs[i].interpolation;
382*35238bceSAndroid Build Coastguard Worker outputs[i].name = varyings.frgInputs[i].name;
383*35238bceSAndroid Build Coastguard Worker }
384*35238bceSAndroid Build Coastguard Worker
385*35238bceSAndroid Build Coastguard Worker return outputs;
386*35238bceSAndroid Build Coastguard Worker }
387*35238bceSAndroid Build Coastguard Worker
388*35238bceSAndroid Build Coastguard Worker // Shader source generation
389*35238bceSAndroid Build Coastguard Worker
printFloat(ostringstream & oss,double d)390*35238bceSAndroid Build Coastguard Worker void printFloat(ostringstream &oss, double d)
391*35238bceSAndroid Build Coastguard Worker {
392*35238bceSAndroid Build Coastguard Worker oss.setf(oss.fixed | oss.internal);
393*35238bceSAndroid Build Coastguard Worker oss.precision(4);
394*35238bceSAndroid Build Coastguard Worker oss.width(7);
395*35238bceSAndroid Build Coastguard Worker oss << d;
396*35238bceSAndroid Build Coastguard Worker }
397*35238bceSAndroid Build Coastguard Worker
printFloatDeclaration(ostringstream & oss,const string & varName,bool uniform,GLfloat value=0.0)398*35238bceSAndroid Build Coastguard Worker void printFloatDeclaration(ostringstream &oss, const string &varName, bool uniform, GLfloat value = 0.0)
399*35238bceSAndroid Build Coastguard Worker {
400*35238bceSAndroid Build Coastguard Worker using namespace glu;
401*35238bceSAndroid Build Coastguard Worker
402*35238bceSAndroid Build Coastguard Worker const VarType varType(TYPE_FLOAT, PRECISION_HIGHP);
403*35238bceSAndroid Build Coastguard Worker
404*35238bceSAndroid Build Coastguard Worker if (uniform)
405*35238bceSAndroid Build Coastguard Worker oss << VariableDeclaration(varType, varName, STORAGE_UNIFORM) << ";\n";
406*35238bceSAndroid Build Coastguard Worker else
407*35238bceSAndroid Build Coastguard Worker oss << VariableDeclaration(varType, varName, STORAGE_CONST) << " = " << de::floatToString(value, 6) << ";\n";
408*35238bceSAndroid Build Coastguard Worker }
409*35238bceSAndroid Build Coastguard Worker
printRandomInitializer(ostringstream & oss,DataType type,Random & rnd)410*35238bceSAndroid Build Coastguard Worker void printRandomInitializer(ostringstream &oss, DataType type, Random &rnd)
411*35238bceSAndroid Build Coastguard Worker {
412*35238bceSAndroid Build Coastguard Worker using namespace glu;
413*35238bceSAndroid Build Coastguard Worker const int size = getDataTypeScalarSize(type);
414*35238bceSAndroid Build Coastguard Worker
415*35238bceSAndroid Build Coastguard Worker if (size > 0)
416*35238bceSAndroid Build Coastguard Worker oss << getDataTypeName(type) << "(";
417*35238bceSAndroid Build Coastguard Worker
418*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < size; ++i)
419*35238bceSAndroid Build Coastguard Worker {
420*35238bceSAndroid Build Coastguard Worker oss << (i == 0 ? "" : ", ");
421*35238bceSAndroid Build Coastguard Worker switch (getDataTypeScalarType(type))
422*35238bceSAndroid Build Coastguard Worker {
423*35238bceSAndroid Build Coastguard Worker case TYPE_FLOAT:
424*35238bceSAndroid Build Coastguard Worker printFloat(oss, rnd.getInt(0, 16) / 16.0);
425*35238bceSAndroid Build Coastguard Worker break;
426*35238bceSAndroid Build Coastguard Worker
427*35238bceSAndroid Build Coastguard Worker case TYPE_INT:
428*35238bceSAndroid Build Coastguard Worker case TYPE_UINT:
429*35238bceSAndroid Build Coastguard Worker oss << rnd.getInt(0, 255);
430*35238bceSAndroid Build Coastguard Worker break;
431*35238bceSAndroid Build Coastguard Worker
432*35238bceSAndroid Build Coastguard Worker case TYPE_BOOL:
433*35238bceSAndroid Build Coastguard Worker oss << (rnd.getBool() ? "true" : "false");
434*35238bceSAndroid Build Coastguard Worker break;
435*35238bceSAndroid Build Coastguard Worker
436*35238bceSAndroid Build Coastguard Worker default:
437*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
438*35238bceSAndroid Build Coastguard Worker }
439*35238bceSAndroid Build Coastguard Worker }
440*35238bceSAndroid Build Coastguard Worker
441*35238bceSAndroid Build Coastguard Worker if (size > 0)
442*35238bceSAndroid Build Coastguard Worker oss << ")";
443*35238bceSAndroid Build Coastguard Worker }
444*35238bceSAndroid Build Coastguard Worker
genVtxShaderSrc(uint32_t seed,const vector<VariableDeclaration> & outputs,const string & varName,bool uniform,float value=0.0)445*35238bceSAndroid Build Coastguard Worker string genVtxShaderSrc(uint32_t seed, const vector<VariableDeclaration> &outputs, const string &varName, bool uniform,
446*35238bceSAndroid Build Coastguard Worker float value = 0.0)
447*35238bceSAndroid Build Coastguard Worker {
448*35238bceSAndroid Build Coastguard Worker ostringstream oss;
449*35238bceSAndroid Build Coastguard Worker Random rnd(seed);
450*35238bceSAndroid Build Coastguard Worker enum
451*35238bceSAndroid Build Coastguard Worker {
452*35238bceSAndroid Build Coastguard Worker NUM_COMPONENTS = 2
453*35238bceSAndroid Build Coastguard Worker };
454*35238bceSAndroid Build Coastguard Worker static const int s_quadrants[][NUM_COMPONENTS] = {{1, 1}, {-1, 1}, {1, -1}};
455*35238bceSAndroid Build Coastguard Worker
456*35238bceSAndroid Build Coastguard Worker oss << "#version 310 es\n";
457*35238bceSAndroid Build Coastguard Worker
458*35238bceSAndroid Build Coastguard Worker printFloatDeclaration(oss, varName, uniform, value);
459*35238bceSAndroid Build Coastguard Worker
460*35238bceSAndroid Build Coastguard Worker for (vector<VariableDeclaration>::const_iterator it = outputs.begin(); it != outputs.end(); ++it)
461*35238bceSAndroid Build Coastguard Worker oss << *it << ";\n";
462*35238bceSAndroid Build Coastguard Worker
463*35238bceSAndroid Build Coastguard Worker oss << "const vec2 triangle[3] = vec2[3](\n";
464*35238bceSAndroid Build Coastguard Worker
465*35238bceSAndroid Build Coastguard Worker for (int vertexNdx = 0; vertexNdx < DE_LENGTH_OF_ARRAY(s_quadrants); ++vertexNdx)
466*35238bceSAndroid Build Coastguard Worker {
467*35238bceSAndroid Build Coastguard Worker oss << "\tvec2(";
468*35238bceSAndroid Build Coastguard Worker
469*35238bceSAndroid Build Coastguard Worker for (int componentNdx = 0; componentNdx < NUM_COMPONENTS; ++componentNdx)
470*35238bceSAndroid Build Coastguard Worker {
471*35238bceSAndroid Build Coastguard Worker printFloat(oss, s_quadrants[vertexNdx][componentNdx] * rnd.getInt(4, 16) / 16.0);
472*35238bceSAndroid Build Coastguard Worker oss << (componentNdx < 1 ? ", " : "");
473*35238bceSAndroid Build Coastguard Worker }
474*35238bceSAndroid Build Coastguard Worker
475*35238bceSAndroid Build Coastguard Worker oss << ")" << (vertexNdx < 2 ? "," : "") << "\n";
476*35238bceSAndroid Build Coastguard Worker }
477*35238bceSAndroid Build Coastguard Worker oss << ");\n";
478*35238bceSAndroid Build Coastguard Worker
479*35238bceSAndroid Build Coastguard Worker for (vector<VariableDeclaration>::const_iterator it = outputs.begin(); it != outputs.end(); ++it)
480*35238bceSAndroid Build Coastguard Worker {
481*35238bceSAndroid Build Coastguard Worker const DataType type = it->varType.getBasicType();
482*35238bceSAndroid Build Coastguard Worker const string typeName = glu::getDataTypeName(type);
483*35238bceSAndroid Build Coastguard Worker
484*35238bceSAndroid Build Coastguard Worker oss << "const " << typeName << " " << it->name << "Inits[3] = " << typeName << "[3](\n";
485*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < 3; ++i)
486*35238bceSAndroid Build Coastguard Worker {
487*35238bceSAndroid Build Coastguard Worker oss << (i == 0 ? "\t" : ",\n\t");
488*35238bceSAndroid Build Coastguard Worker printRandomInitializer(oss, type, rnd);
489*35238bceSAndroid Build Coastguard Worker }
490*35238bceSAndroid Build Coastguard Worker oss << ");\n";
491*35238bceSAndroid Build Coastguard Worker }
492*35238bceSAndroid Build Coastguard Worker
493*35238bceSAndroid Build Coastguard Worker oss << "void main (void)\n"
494*35238bceSAndroid Build Coastguard Worker << "{\n"
495*35238bceSAndroid Build Coastguard Worker << "\tgl_Position = vec4(" << varName << " * triangle[gl_VertexID], 0.0, 1.0);\n";
496*35238bceSAndroid Build Coastguard Worker
497*35238bceSAndroid Build Coastguard Worker for (vector<VariableDeclaration>::const_iterator it = outputs.begin(); it != outputs.end(); ++it)
498*35238bceSAndroid Build Coastguard Worker oss << "\t" << it->name << " = " << it->name << "Inits[gl_VertexID];\n";
499*35238bceSAndroid Build Coastguard Worker
500*35238bceSAndroid Build Coastguard Worker oss << "}\n";
501*35238bceSAndroid Build Coastguard Worker
502*35238bceSAndroid Build Coastguard Worker return oss.str();
503*35238bceSAndroid Build Coastguard Worker }
504*35238bceSAndroid Build Coastguard Worker
genFrgShaderSrc(uint32_t seed,const vector<VariableDeclaration> & inputs,const string & varName,bool uniform,float value=0.0)505*35238bceSAndroid Build Coastguard Worker string genFrgShaderSrc(uint32_t seed, const vector<VariableDeclaration> &inputs, const string &varName, bool uniform,
506*35238bceSAndroid Build Coastguard Worker float value = 0.0)
507*35238bceSAndroid Build Coastguard Worker {
508*35238bceSAndroid Build Coastguard Worker Random rnd(seed);
509*35238bceSAndroid Build Coastguard Worker ostringstream oss;
510*35238bceSAndroid Build Coastguard Worker
511*35238bceSAndroid Build Coastguard Worker oss.precision(4);
512*35238bceSAndroid Build Coastguard Worker oss.width(7);
513*35238bceSAndroid Build Coastguard Worker oss << "#version 310 es\n";
514*35238bceSAndroid Build Coastguard Worker
515*35238bceSAndroid Build Coastguard Worker oss << "precision highp float;\n";
516*35238bceSAndroid Build Coastguard Worker
517*35238bceSAndroid Build Coastguard Worker oss << "out vec4 fragColor;\n";
518*35238bceSAndroid Build Coastguard Worker
519*35238bceSAndroid Build Coastguard Worker printFloatDeclaration(oss, varName, uniform, value);
520*35238bceSAndroid Build Coastguard Worker
521*35238bceSAndroid Build Coastguard Worker for (vector<VariableDeclaration>::const_iterator it = inputs.begin(); it != inputs.end(); ++it)
522*35238bceSAndroid Build Coastguard Worker oss << *it << ";\n";
523*35238bceSAndroid Build Coastguard Worker
524*35238bceSAndroid Build Coastguard Worker // glsl % isn't defined for negative numbers
525*35238bceSAndroid Build Coastguard Worker oss << "int imod (int n, int d)"
526*35238bceSAndroid Build Coastguard Worker << "\n"
527*35238bceSAndroid Build Coastguard Worker << "{"
528*35238bceSAndroid Build Coastguard Worker << "\n"
529*35238bceSAndroid Build Coastguard Worker << "\t"
530*35238bceSAndroid Build Coastguard Worker << "return (n < 0 ? d - 1 - (-1 - n) % d : n % d);"
531*35238bceSAndroid Build Coastguard Worker << "\n"
532*35238bceSAndroid Build Coastguard Worker << "}"
533*35238bceSAndroid Build Coastguard Worker << "\n";
534*35238bceSAndroid Build Coastguard Worker
535*35238bceSAndroid Build Coastguard Worker oss << "vec4 hsv (vec3 hsv)"
536*35238bceSAndroid Build Coastguard Worker << "{"
537*35238bceSAndroid Build Coastguard Worker << "\n"
538*35238bceSAndroid Build Coastguard Worker << "\tfloat h = hsv.x * 3.0;\n"
539*35238bceSAndroid Build Coastguard Worker << "\tfloat r = max(0.0, 1.0 - h) + max(0.0, h - 2.0);\n"
540*35238bceSAndroid Build Coastguard Worker << "\tfloat g = max(0.0, 1.0 - abs(h - 1.0));\n"
541*35238bceSAndroid Build Coastguard Worker << "\tfloat b = max(0.0, 1.0 - abs(h - 2.0));\n"
542*35238bceSAndroid Build Coastguard Worker << "\tvec3 hs = mix(vec3(1.0), vec3(r, g, b), hsv.y);\n"
543*35238bceSAndroid Build Coastguard Worker << "\treturn vec4(hsv.z * hs, 1.0);\n"
544*35238bceSAndroid Build Coastguard Worker << "}\n";
545*35238bceSAndroid Build Coastguard Worker
546*35238bceSAndroid Build Coastguard Worker oss << "void main (void)\n"
547*35238bceSAndroid Build Coastguard Worker << "{\n";
548*35238bceSAndroid Build Coastguard Worker
549*35238bceSAndroid Build Coastguard Worker oss << "\t"
550*35238bceSAndroid Build Coastguard Worker << "fragColor = vec4(vec3(" << varName << "), 1.0);"
551*35238bceSAndroid Build Coastguard Worker << "\n";
552*35238bceSAndroid Build Coastguard Worker
553*35238bceSAndroid Build Coastguard Worker if (inputs.size() > 0)
554*35238bceSAndroid Build Coastguard Worker {
555*35238bceSAndroid Build Coastguard Worker oss << "\t"
556*35238bceSAndroid Build Coastguard Worker << "switch (imod(int(0.5 * (";
557*35238bceSAndroid Build Coastguard Worker
558*35238bceSAndroid Build Coastguard Worker printFloat(oss, rnd.getFloat(0.5f, 2.0f));
559*35238bceSAndroid Build Coastguard Worker oss << " * gl_FragCoord.x - ";
560*35238bceSAndroid Build Coastguard Worker
561*35238bceSAndroid Build Coastguard Worker printFloat(oss, rnd.getFloat(0.5f, 2.0f));
562*35238bceSAndroid Build Coastguard Worker oss << " * gl_FragCoord.y)), " << inputs.size() << "))"
563*35238bceSAndroid Build Coastguard Worker << "\n"
564*35238bceSAndroid Build Coastguard Worker << "\t"
565*35238bceSAndroid Build Coastguard Worker << "{"
566*35238bceSAndroid Build Coastguard Worker << "\n";
567*35238bceSAndroid Build Coastguard Worker
568*35238bceSAndroid Build Coastguard Worker for (size_t i = 0; i < inputs.size(); ++i)
569*35238bceSAndroid Build Coastguard Worker {
570*35238bceSAndroid Build Coastguard Worker oss << "\t\t"
571*35238bceSAndroid Build Coastguard Worker << "case " << i << ":"
572*35238bceSAndroid Build Coastguard Worker << "\n"
573*35238bceSAndroid Build Coastguard Worker << "\t\t\t"
574*35238bceSAndroid Build Coastguard Worker << "fragColor *= ";
575*35238bceSAndroid Build Coastguard Worker
576*35238bceSAndroid Build Coastguard Worker printInputColor(oss, inputs[i]);
577*35238bceSAndroid Build Coastguard Worker
578*35238bceSAndroid Build Coastguard Worker oss << ";"
579*35238bceSAndroid Build Coastguard Worker << "\n"
580*35238bceSAndroid Build Coastguard Worker << "\t\t\t"
581*35238bceSAndroid Build Coastguard Worker << "break;"
582*35238bceSAndroid Build Coastguard Worker << "\n";
583*35238bceSAndroid Build Coastguard Worker }
584*35238bceSAndroid Build Coastguard Worker
585*35238bceSAndroid Build Coastguard Worker oss << "\t\t"
586*35238bceSAndroid Build Coastguard Worker << "case " << inputs.size() << ":\n"
587*35238bceSAndroid Build Coastguard Worker << "\t\t\t"
588*35238bceSAndroid Build Coastguard Worker << "fragColor = vec4(1.0, 0.0, 1.0, 1.0);"
589*35238bceSAndroid Build Coastguard Worker << "\n";
590*35238bceSAndroid Build Coastguard Worker oss << "\t\t\t"
591*35238bceSAndroid Build Coastguard Worker << "break;"
592*35238bceSAndroid Build Coastguard Worker << "\n";
593*35238bceSAndroid Build Coastguard Worker
594*35238bceSAndroid Build Coastguard Worker oss << "\t\t"
595*35238bceSAndroid Build Coastguard Worker << "case -1:\n"
596*35238bceSAndroid Build Coastguard Worker << "\t\t\t"
597*35238bceSAndroid Build Coastguard Worker << "fragColor = vec4(1.0, 1.0, 0.0, 1.0);"
598*35238bceSAndroid Build Coastguard Worker << "\n";
599*35238bceSAndroid Build Coastguard Worker oss << "\t\t\t"
600*35238bceSAndroid Build Coastguard Worker << "break;"
601*35238bceSAndroid Build Coastguard Worker << "\n";
602*35238bceSAndroid Build Coastguard Worker
603*35238bceSAndroid Build Coastguard Worker oss << "\t\t"
604*35238bceSAndroid Build Coastguard Worker << "default:"
605*35238bceSAndroid Build Coastguard Worker << "\n"
606*35238bceSAndroid Build Coastguard Worker << "\t\t\t"
607*35238bceSAndroid Build Coastguard Worker << "fragColor = vec4(1.0, 1.0, 0.0, 1.0);"
608*35238bceSAndroid Build Coastguard Worker << "\n";
609*35238bceSAndroid Build Coastguard Worker
610*35238bceSAndroid Build Coastguard Worker oss << "\t"
611*35238bceSAndroid Build Coastguard Worker << "}\n";
612*35238bceSAndroid Build Coastguard Worker }
613*35238bceSAndroid Build Coastguard Worker
614*35238bceSAndroid Build Coastguard Worker oss << "}\n";
615*35238bceSAndroid Build Coastguard Worker
616*35238bceSAndroid Build Coastguard Worker return oss.str();
617*35238bceSAndroid Build Coastguard Worker }
618*35238bceSAndroid Build Coastguard Worker
619*35238bceSAndroid Build Coastguard Worker // ProgramWrapper
620*35238bceSAndroid Build Coastguard Worker
621*35238bceSAndroid Build Coastguard Worker class ProgramWrapper
622*35238bceSAndroid Build Coastguard Worker {
623*35238bceSAndroid Build Coastguard Worker public:
~ProgramWrapper(void)624*35238bceSAndroid Build Coastguard Worker virtual ~ProgramWrapper(void)
625*35238bceSAndroid Build Coastguard Worker {
626*35238bceSAndroid Build Coastguard Worker }
627*35238bceSAndroid Build Coastguard Worker
628*35238bceSAndroid Build Coastguard Worker virtual GLuint getProgramName(void) = 0;
629*35238bceSAndroid Build Coastguard Worker virtual void writeToLog(TestLog &log) = 0;
630*35238bceSAndroid Build Coastguard Worker };
631*35238bceSAndroid Build Coastguard Worker
632*35238bceSAndroid Build Coastguard Worker class ShaderProgramWrapper : public ProgramWrapper
633*35238bceSAndroid Build Coastguard Worker {
634*35238bceSAndroid Build Coastguard Worker public:
ShaderProgramWrapper(const RenderContext & renderCtx,const ProgramSources & sources)635*35238bceSAndroid Build Coastguard Worker ShaderProgramWrapper(const RenderContext &renderCtx, const ProgramSources &sources)
636*35238bceSAndroid Build Coastguard Worker : m_shaderProgram(renderCtx, sources)
637*35238bceSAndroid Build Coastguard Worker {
638*35238bceSAndroid Build Coastguard Worker }
~ShaderProgramWrapper(void)639*35238bceSAndroid Build Coastguard Worker ~ShaderProgramWrapper(void)
640*35238bceSAndroid Build Coastguard Worker {
641*35238bceSAndroid Build Coastguard Worker }
642*35238bceSAndroid Build Coastguard Worker
getProgramName(void)643*35238bceSAndroid Build Coastguard Worker GLuint getProgramName(void)
644*35238bceSAndroid Build Coastguard Worker {
645*35238bceSAndroid Build Coastguard Worker return m_shaderProgram.getProgram();
646*35238bceSAndroid Build Coastguard Worker }
getShaderProgram(void)647*35238bceSAndroid Build Coastguard Worker ShaderProgram &getShaderProgram(void)
648*35238bceSAndroid Build Coastguard Worker {
649*35238bceSAndroid Build Coastguard Worker return m_shaderProgram;
650*35238bceSAndroid Build Coastguard Worker }
writeToLog(TestLog & log)651*35238bceSAndroid Build Coastguard Worker void writeToLog(TestLog &log)
652*35238bceSAndroid Build Coastguard Worker {
653*35238bceSAndroid Build Coastguard Worker log << m_shaderProgram;
654*35238bceSAndroid Build Coastguard Worker }
655*35238bceSAndroid Build Coastguard Worker
656*35238bceSAndroid Build Coastguard Worker private:
657*35238bceSAndroid Build Coastguard Worker ShaderProgram m_shaderProgram;
658*35238bceSAndroid Build Coastguard Worker };
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker class RawProgramWrapper : public ProgramWrapper
661*35238bceSAndroid Build Coastguard Worker {
662*35238bceSAndroid Build Coastguard Worker public:
RawProgramWrapper(const RenderContext & renderCtx,GLuint programName,ShaderType shaderType,const string & source)663*35238bceSAndroid Build Coastguard Worker RawProgramWrapper(const RenderContext &renderCtx, GLuint programName, ShaderType shaderType, const string &source)
664*35238bceSAndroid Build Coastguard Worker : m_program(renderCtx, programName)
665*35238bceSAndroid Build Coastguard Worker , m_shaderType(shaderType)
666*35238bceSAndroid Build Coastguard Worker , m_source(source)
667*35238bceSAndroid Build Coastguard Worker {
668*35238bceSAndroid Build Coastguard Worker }
~RawProgramWrapper(void)669*35238bceSAndroid Build Coastguard Worker ~RawProgramWrapper(void)
670*35238bceSAndroid Build Coastguard Worker {
671*35238bceSAndroid Build Coastguard Worker }
672*35238bceSAndroid Build Coastguard Worker
getProgramName(void)673*35238bceSAndroid Build Coastguard Worker GLuint getProgramName(void)
674*35238bceSAndroid Build Coastguard Worker {
675*35238bceSAndroid Build Coastguard Worker return m_program.getProgram();
676*35238bceSAndroid Build Coastguard Worker }
getProgram(void)677*35238bceSAndroid Build Coastguard Worker Program &getProgram(void)
678*35238bceSAndroid Build Coastguard Worker {
679*35238bceSAndroid Build Coastguard Worker return m_program;
680*35238bceSAndroid Build Coastguard Worker }
681*35238bceSAndroid Build Coastguard Worker void writeToLog(TestLog &log);
682*35238bceSAndroid Build Coastguard Worker
683*35238bceSAndroid Build Coastguard Worker private:
684*35238bceSAndroid Build Coastguard Worker Program m_program;
685*35238bceSAndroid Build Coastguard Worker ShaderType m_shaderType;
686*35238bceSAndroid Build Coastguard Worker const string m_source;
687*35238bceSAndroid Build Coastguard Worker };
688*35238bceSAndroid Build Coastguard Worker
writeToLog(TestLog & log)689*35238bceSAndroid Build Coastguard Worker void RawProgramWrapper::writeToLog(TestLog &log)
690*35238bceSAndroid Build Coastguard Worker {
691*35238bceSAndroid Build Coastguard Worker const string info = m_program.getInfoLog();
692*35238bceSAndroid Build Coastguard Worker qpShaderType qpType = glu::getLogShaderType(m_shaderType);
693*35238bceSAndroid Build Coastguard Worker
694*35238bceSAndroid Build Coastguard Worker log << TestLog::ShaderProgram(true, info)
695*35238bceSAndroid Build Coastguard Worker << TestLog::Shader(qpType, m_source, true, "[Shader created by glCreateShaderProgramv()]")
696*35238bceSAndroid Build Coastguard Worker << TestLog::EndShaderProgram;
697*35238bceSAndroid Build Coastguard Worker }
698*35238bceSAndroid Build Coastguard Worker
699*35238bceSAndroid Build Coastguard Worker // ProgramParams
700*35238bceSAndroid Build Coastguard Worker
701*35238bceSAndroid Build Coastguard Worker struct ProgramParams
702*35238bceSAndroid Build Coastguard Worker {
ProgramParamsdeqp::gles31::Functional::__anonf652bf1a0111::ProgramParams703*35238bceSAndroid Build Coastguard Worker ProgramParams(uint32_t vtxSeed_, GLfloat vtxScale_, uint32_t frgSeed_, GLfloat frgScale_)
704*35238bceSAndroid Build Coastguard Worker : vtxSeed(vtxSeed_)
705*35238bceSAndroid Build Coastguard Worker , vtxScale(vtxScale_)
706*35238bceSAndroid Build Coastguard Worker , frgSeed(frgSeed_)
707*35238bceSAndroid Build Coastguard Worker , frgScale(frgScale_)
708*35238bceSAndroid Build Coastguard Worker {
709*35238bceSAndroid Build Coastguard Worker }
710*35238bceSAndroid Build Coastguard Worker uint32_t vtxSeed;
711*35238bceSAndroid Build Coastguard Worker GLfloat vtxScale;
712*35238bceSAndroid Build Coastguard Worker uint32_t frgSeed;
713*35238bceSAndroid Build Coastguard Worker GLfloat frgScale;
714*35238bceSAndroid Build Coastguard Worker };
715*35238bceSAndroid Build Coastguard Worker
genProgramParams(Random & rnd)716*35238bceSAndroid Build Coastguard Worker ProgramParams genProgramParams(Random &rnd)
717*35238bceSAndroid Build Coastguard Worker {
718*35238bceSAndroid Build Coastguard Worker const uint32_t vtxSeed = rnd.getUint32();
719*35238bceSAndroid Build Coastguard Worker const GLfloat vtxScale = (float)rnd.getInt(8, 16) / 16.0f;
720*35238bceSAndroid Build Coastguard Worker const uint32_t frgSeed = rnd.getUint32();
721*35238bceSAndroid Build Coastguard Worker const GLfloat frgScale = (float)rnd.getInt(0, 16) / 16.0f;
722*35238bceSAndroid Build Coastguard Worker
723*35238bceSAndroid Build Coastguard Worker return ProgramParams(vtxSeed, vtxScale, frgSeed, frgScale);
724*35238bceSAndroid Build Coastguard Worker }
725*35238bceSAndroid Build Coastguard Worker
726*35238bceSAndroid Build Coastguard Worker // TestParams
727*35238bceSAndroid Build Coastguard Worker
728*35238bceSAndroid Build Coastguard Worker struct TestParams
729*35238bceSAndroid Build Coastguard Worker {
730*35238bceSAndroid Build Coastguard Worker bool initSingle;
731*35238bceSAndroid Build Coastguard Worker bool switchVtx;
732*35238bceSAndroid Build Coastguard Worker bool switchFrg;
733*35238bceSAndroid Build Coastguard Worker bool useUniform;
734*35238bceSAndroid Build Coastguard Worker bool useSameName;
735*35238bceSAndroid Build Coastguard Worker bool useCreateHelper;
736*35238bceSAndroid Build Coastguard Worker bool useProgramUniform;
737*35238bceSAndroid Build Coastguard Worker VaryingParams varyings;
738*35238bceSAndroid Build Coastguard Worker };
739*35238bceSAndroid Build Coastguard Worker
paramsSeed(const TestParams & params)740*35238bceSAndroid Build Coastguard Worker uint32_t paramsSeed(const TestParams ¶ms)
741*35238bceSAndroid Build Coastguard Worker {
742*35238bceSAndroid Build Coastguard Worker uint32_t paramCode =
743*35238bceSAndroid Build Coastguard Worker (params.initSingle << 0 | params.switchVtx << 1 | params.switchFrg << 2 | params.useUniform << 3 |
744*35238bceSAndroid Build Coastguard Worker params.useSameName << 4 | params.useCreateHelper << 5 | params.useProgramUniform << 6);
745*35238bceSAndroid Build Coastguard Worker
746*35238bceSAndroid Build Coastguard Worker paramCode = deUint32Hash(paramCode) + params.varyings.count;
747*35238bceSAndroid Build Coastguard Worker paramCode = deUint32Hash(paramCode) + params.varyings.type;
748*35238bceSAndroid Build Coastguard Worker paramCode = deUint32Hash(paramCode) + params.varyings.binding;
749*35238bceSAndroid Build Coastguard Worker paramCode = deUint32Hash(paramCode) + params.varyings.vtxInterp;
750*35238bceSAndroid Build Coastguard Worker paramCode = deUint32Hash(paramCode) + params.varyings.frgInterp;
751*35238bceSAndroid Build Coastguard Worker
752*35238bceSAndroid Build Coastguard Worker return deUint32Hash(paramCode);
753*35238bceSAndroid Build Coastguard Worker }
754*35238bceSAndroid Build Coastguard Worker
paramsCode(const TestParams & params)755*35238bceSAndroid Build Coastguard Worker string paramsCode(const TestParams ¶ms)
756*35238bceSAndroid Build Coastguard Worker {
757*35238bceSAndroid Build Coastguard Worker using namespace glu;
758*35238bceSAndroid Build Coastguard Worker
759*35238bceSAndroid Build Coastguard Worker ostringstream oss;
760*35238bceSAndroid Build Coastguard Worker
761*35238bceSAndroid Build Coastguard Worker oss << (params.initSingle ? "1" : "2") << (params.switchVtx ? "v" : "") << (params.switchFrg ? "f" : "")
762*35238bceSAndroid Build Coastguard Worker << (params.useProgramUniform ? "p" : "") << (params.useUniform ? "u" : "") << (params.useSameName ? "s" : "")
763*35238bceSAndroid Build Coastguard Worker << (params.useCreateHelper ? "c" : "") << de::toString(params.varyings.count)
764*35238bceSAndroid Build Coastguard Worker << (params.varyings.binding == BINDING_NAME ? "n" :
765*35238bceSAndroid Build Coastguard Worker params.varyings.binding == BINDING_LOCATION ? "l" :
766*35238bceSAndroid Build Coastguard Worker params.varyings.binding == BINDING_LAST ? "r" :
767*35238bceSAndroid Build Coastguard Worker "")
768*35238bceSAndroid Build Coastguard Worker << (params.varyings.vtxInterp == VARYINGINTERPOLATION_SMOOTH ? "m" :
769*35238bceSAndroid Build Coastguard Worker params.varyings.vtxInterp == VARYINGINTERPOLATION_CENTROID ? "e" :
770*35238bceSAndroid Build Coastguard Worker params.varyings.vtxInterp == VARYINGINTERPOLATION_FLAT ? "a" :
771*35238bceSAndroid Build Coastguard Worker params.varyings.vtxInterp == VARYINGINTERPOLATION_RANDOM ? "r" :
772*35238bceSAndroid Build Coastguard Worker "o")
773*35238bceSAndroid Build Coastguard Worker << (params.varyings.frgInterp == VARYINGINTERPOLATION_SMOOTH ? "m" :
774*35238bceSAndroid Build Coastguard Worker params.varyings.frgInterp == VARYINGINTERPOLATION_CENTROID ? "e" :
775*35238bceSAndroid Build Coastguard Worker params.varyings.frgInterp == VARYINGINTERPOLATION_FLAT ? "a" :
776*35238bceSAndroid Build Coastguard Worker params.varyings.frgInterp == VARYINGINTERPOLATION_RANDOM ? "r" :
777*35238bceSAndroid Build Coastguard Worker "o");
778*35238bceSAndroid Build Coastguard Worker return oss.str();
779*35238bceSAndroid Build Coastguard Worker }
780*35238bceSAndroid Build Coastguard Worker
paramsValid(const TestParams & params)781*35238bceSAndroid Build Coastguard Worker bool paramsValid(const TestParams ¶ms)
782*35238bceSAndroid Build Coastguard Worker {
783*35238bceSAndroid Build Coastguard Worker using namespace glu;
784*35238bceSAndroid Build Coastguard Worker
785*35238bceSAndroid Build Coastguard Worker // Final pipeline has a single program?
786*35238bceSAndroid Build Coastguard Worker if (params.initSingle)
787*35238bceSAndroid Build Coastguard Worker {
788*35238bceSAndroid Build Coastguard Worker // Cannot have conflicting names for uniforms or constants
789*35238bceSAndroid Build Coastguard Worker if (params.useSameName)
790*35238bceSAndroid Build Coastguard Worker return false;
791*35238bceSAndroid Build Coastguard Worker
792*35238bceSAndroid Build Coastguard Worker // CreateShaderProgram would never get called
793*35238bceSAndroid Build Coastguard Worker if (!params.switchVtx && !params.switchFrg && params.useCreateHelper)
794*35238bceSAndroid Build Coastguard Worker return false;
795*35238bceSAndroid Build Coastguard Worker
796*35238bceSAndroid Build Coastguard Worker // Must switch either all or nothing
797*35238bceSAndroid Build Coastguard Worker if (params.switchVtx != params.switchFrg)
798*35238bceSAndroid Build Coastguard Worker return false;
799*35238bceSAndroid Build Coastguard Worker }
800*35238bceSAndroid Build Coastguard Worker
801*35238bceSAndroid Build Coastguard Worker // ProgramUniform would never get called
802*35238bceSAndroid Build Coastguard Worker if (params.useProgramUniform && !params.useUniform)
803*35238bceSAndroid Build Coastguard Worker return false;
804*35238bceSAndroid Build Coastguard Worker
805*35238bceSAndroid Build Coastguard Worker // Interpolation is meaningless if we don't use an in/out variable.
806*35238bceSAndroid Build Coastguard Worker if (params.varyings.count == 0 && !(params.varyings.vtxInterp == VARYINGINTERPOLATION_LAST &&
807*35238bceSAndroid Build Coastguard Worker params.varyings.frgInterp == VARYINGINTERPOLATION_LAST))
808*35238bceSAndroid Build Coastguard Worker return false;
809*35238bceSAndroid Build Coastguard Worker
810*35238bceSAndroid Build Coastguard Worker // Mismatch by flat / smooth is not allowed. See Khronos bug #12630
811*35238bceSAndroid Build Coastguard Worker // \note: iterpolations might be RANDOM, causing generated varyings potentially match / mismatch anyway.
812*35238bceSAndroid Build Coastguard Worker // This is checked later on. Here, we just make sure that we don't force the generator to generate
813*35238bceSAndroid Build Coastguard Worker // only invalid varying configurations, i.e. there exists a valid varying configuration for this
814*35238bceSAndroid Build Coastguard Worker // test param config.
815*35238bceSAndroid Build Coastguard Worker if ((params.varyings.vtxInterp != VARYINGINTERPOLATION_RANDOM) &&
816*35238bceSAndroid Build Coastguard Worker (params.varyings.frgInterp != VARYINGINTERPOLATION_RANDOM) &&
817*35238bceSAndroid Build Coastguard Worker (params.varyings.vtxInterp == VARYINGINTERPOLATION_FLAT) !=
818*35238bceSAndroid Build Coastguard Worker (params.varyings.frgInterp == VARYINGINTERPOLATION_FLAT))
819*35238bceSAndroid Build Coastguard Worker return false;
820*35238bceSAndroid Build Coastguard Worker
821*35238bceSAndroid Build Coastguard Worker return true;
822*35238bceSAndroid Build Coastguard Worker }
823*35238bceSAndroid Build Coastguard Worker
824*35238bceSAndroid Build Coastguard Worker // used only for debug quick checks
825*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG)
varyingsValid(const VaryingInterface & varyings)826*35238bceSAndroid Build Coastguard Worker bool varyingsValid(const VaryingInterface &varyings)
827*35238bceSAndroid Build Coastguard Worker {
828*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)varyings.vtxOutputs.size(); ++ndx)
829*35238bceSAndroid Build Coastguard Worker {
830*35238bceSAndroid Build Coastguard Worker const VaryingInterpolation vertexInterpolation =
831*35238bceSAndroid Build Coastguard Worker getVaryingInterpolation(varyings.vtxOutputs[ndx].interpolation);
832*35238bceSAndroid Build Coastguard Worker const VaryingInterpolation fragmentInterpolation =
833*35238bceSAndroid Build Coastguard Worker getVaryingInterpolation(varyings.frgInputs[ndx].interpolation);
834*35238bceSAndroid Build Coastguard Worker
835*35238bceSAndroid Build Coastguard Worker if (!isSSOCompatibleInterpolation(vertexInterpolation, fragmentInterpolation))
836*35238bceSAndroid Build Coastguard Worker return false;
837*35238bceSAndroid Build Coastguard Worker }
838*35238bceSAndroid Build Coastguard Worker
839*35238bceSAndroid Build Coastguard Worker return true;
840*35238bceSAndroid Build Coastguard Worker }
841*35238bceSAndroid Build Coastguard Worker #endif
842*35238bceSAndroid Build Coastguard Worker
logParams(TestLog & log,const TestParams & params)843*35238bceSAndroid Build Coastguard Worker void logParams(TestLog &log, const TestParams ¶ms)
844*35238bceSAndroid Build Coastguard Worker {
845*35238bceSAndroid Build Coastguard Worker // We don't log operational details here since those are shown
846*35238bceSAndroid Build Coastguard Worker // in the log messages during execution.
847*35238bceSAndroid Build Coastguard Worker MessageBuilder msg = log.message();
848*35238bceSAndroid Build Coastguard Worker
849*35238bceSAndroid Build Coastguard Worker msg << "Pipeline configuration:\n";
850*35238bceSAndroid Build Coastguard Worker
851*35238bceSAndroid Build Coastguard Worker msg << "Vertex and fragment shaders have " << (params.useUniform ? "uniform" : "constant") << "s with "
852*35238bceSAndroid Build Coastguard Worker << (params.useSameName ? "the same name" : "different names") << ".\n";
853*35238bceSAndroid Build Coastguard Worker
854*35238bceSAndroid Build Coastguard Worker if (params.varyings.count == 0)
855*35238bceSAndroid Build Coastguard Worker msg << "There are no varyings.\n";
856*35238bceSAndroid Build Coastguard Worker else
857*35238bceSAndroid Build Coastguard Worker {
858*35238bceSAndroid Build Coastguard Worker if (params.varyings.count == 1)
859*35238bceSAndroid Build Coastguard Worker msg << "There is one varying.\n";
860*35238bceSAndroid Build Coastguard Worker else
861*35238bceSAndroid Build Coastguard Worker msg << "There are " << params.varyings.count << " varyings.\n";
862*35238bceSAndroid Build Coastguard Worker
863*35238bceSAndroid Build Coastguard Worker if (params.varyings.type == glu::TYPE_LAST)
864*35238bceSAndroid Build Coastguard Worker msg << "Varyings are of random types.\n";
865*35238bceSAndroid Build Coastguard Worker else
866*35238bceSAndroid Build Coastguard Worker msg << "Varyings are of type '" << glu::getDataTypeName(params.varyings.type) << "'.\n";
867*35238bceSAndroid Build Coastguard Worker
868*35238bceSAndroid Build Coastguard Worker msg << "Varying outputs and inputs correspond ";
869*35238bceSAndroid Build Coastguard Worker switch (params.varyings.binding)
870*35238bceSAndroid Build Coastguard Worker {
871*35238bceSAndroid Build Coastguard Worker case BINDING_NAME:
872*35238bceSAndroid Build Coastguard Worker msg << "by name.\n";
873*35238bceSAndroid Build Coastguard Worker break;
874*35238bceSAndroid Build Coastguard Worker case BINDING_LOCATION:
875*35238bceSAndroid Build Coastguard Worker msg << "by location.\n";
876*35238bceSAndroid Build Coastguard Worker break;
877*35238bceSAndroid Build Coastguard Worker case BINDING_LAST:
878*35238bceSAndroid Build Coastguard Worker msg << "randomly either by name or by location.\n";
879*35238bceSAndroid Build Coastguard Worker break;
880*35238bceSAndroid Build Coastguard Worker default:
881*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
882*35238bceSAndroid Build Coastguard Worker }
883*35238bceSAndroid Build Coastguard Worker
884*35238bceSAndroid Build Coastguard Worker msg << "In the vertex shader the varyings are qualified ";
885*35238bceSAndroid Build Coastguard Worker if (params.varyings.vtxInterp == VARYINGINTERPOLATION_DEFAULT)
886*35238bceSAndroid Build Coastguard Worker msg << "with no interpolation qualifiers.\n";
887*35238bceSAndroid Build Coastguard Worker else if (params.varyings.vtxInterp == VARYINGINTERPOLATION_RANDOM)
888*35238bceSAndroid Build Coastguard Worker msg << "with a random interpolation qualifier.\n";
889*35238bceSAndroid Build Coastguard Worker else
890*35238bceSAndroid Build Coastguard Worker msg << "'" << glu::getInterpolationName(getGluInterpolation(params.varyings.vtxInterp)) << "'.\n";
891*35238bceSAndroid Build Coastguard Worker
892*35238bceSAndroid Build Coastguard Worker msg << "In the fragment shader the varyings are qualified ";
893*35238bceSAndroid Build Coastguard Worker if (params.varyings.frgInterp == VARYINGINTERPOLATION_DEFAULT)
894*35238bceSAndroid Build Coastguard Worker msg << "with no interpolation qualifiers.\n";
895*35238bceSAndroid Build Coastguard Worker else if (params.varyings.frgInterp == VARYINGINTERPOLATION_RANDOM)
896*35238bceSAndroid Build Coastguard Worker msg << "with a random interpolation qualifier.\n";
897*35238bceSAndroid Build Coastguard Worker else
898*35238bceSAndroid Build Coastguard Worker msg << "'" << glu::getInterpolationName(getGluInterpolation(params.varyings.frgInterp)) << "'.\n";
899*35238bceSAndroid Build Coastguard Worker }
900*35238bceSAndroid Build Coastguard Worker
901*35238bceSAndroid Build Coastguard Worker msg << TestLog::EndMessage;
902*35238bceSAndroid Build Coastguard Worker
903*35238bceSAndroid Build Coastguard Worker log.writeMessage("");
904*35238bceSAndroid Build Coastguard Worker }
905*35238bceSAndroid Build Coastguard Worker
genParams(uint32_t seed)906*35238bceSAndroid Build Coastguard Worker TestParams genParams(uint32_t seed)
907*35238bceSAndroid Build Coastguard Worker {
908*35238bceSAndroid Build Coastguard Worker Random rnd(seed);
909*35238bceSAndroid Build Coastguard Worker TestParams params;
910*35238bceSAndroid Build Coastguard Worker int tryNdx = 0;
911*35238bceSAndroid Build Coastguard Worker
912*35238bceSAndroid Build Coastguard Worker do
913*35238bceSAndroid Build Coastguard Worker {
914*35238bceSAndroid Build Coastguard Worker params.initSingle = rnd.getBool();
915*35238bceSAndroid Build Coastguard Worker params.switchVtx = rnd.getBool();
916*35238bceSAndroid Build Coastguard Worker params.switchFrg = rnd.getBool();
917*35238bceSAndroid Build Coastguard Worker params.useUniform = rnd.getBool();
918*35238bceSAndroid Build Coastguard Worker params.useProgramUniform = params.useUniform && rnd.getBool();
919*35238bceSAndroid Build Coastguard Worker params.useCreateHelper = rnd.getBool();
920*35238bceSAndroid Build Coastguard Worker params.useSameName = rnd.getBool();
921*35238bceSAndroid Build Coastguard Worker {
922*35238bceSAndroid Build Coastguard Worker int i = rnd.getInt(-1, 3);
923*35238bceSAndroid Build Coastguard Worker params.varyings.count = (i == -1 ? 0 : 1 << i);
924*35238bceSAndroid Build Coastguard Worker }
925*35238bceSAndroid Build Coastguard Worker if (params.varyings.count > 0)
926*35238bceSAndroid Build Coastguard Worker {
927*35238bceSAndroid Build Coastguard Worker params.varyings.type = glu::TYPE_LAST;
928*35238bceSAndroid Build Coastguard Worker params.varyings.binding = BINDING_LAST;
929*35238bceSAndroid Build Coastguard Worker params.varyings.vtxInterp = VARYINGINTERPOLATION_RANDOM;
930*35238bceSAndroid Build Coastguard Worker params.varyings.frgInterp = VARYINGINTERPOLATION_RANDOM;
931*35238bceSAndroid Build Coastguard Worker }
932*35238bceSAndroid Build Coastguard Worker else
933*35238bceSAndroid Build Coastguard Worker {
934*35238bceSAndroid Build Coastguard Worker params.varyings.type = glu::TYPE_INVALID;
935*35238bceSAndroid Build Coastguard Worker params.varyings.binding = BINDING_LAST;
936*35238bceSAndroid Build Coastguard Worker params.varyings.vtxInterp = VARYINGINTERPOLATION_LAST;
937*35238bceSAndroid Build Coastguard Worker params.varyings.frgInterp = VARYINGINTERPOLATION_LAST;
938*35238bceSAndroid Build Coastguard Worker }
939*35238bceSAndroid Build Coastguard Worker
940*35238bceSAndroid Build Coastguard Worker tryNdx += 1;
941*35238bceSAndroid Build Coastguard Worker } while (!paramsValid(params) && tryNdx < 16);
942*35238bceSAndroid Build Coastguard Worker
943*35238bceSAndroid Build Coastguard Worker DE_ASSERT(paramsValid(params));
944*35238bceSAndroid Build Coastguard Worker
945*35238bceSAndroid Build Coastguard Worker return params;
946*35238bceSAndroid Build Coastguard Worker }
947*35238bceSAndroid Build Coastguard Worker
948*35238bceSAndroid Build Coastguard Worker // Program pipeline wrapper that retains references to component programs.
949*35238bceSAndroid Build Coastguard Worker
950*35238bceSAndroid Build Coastguard Worker struct Pipeline
951*35238bceSAndroid Build Coastguard Worker {
Pipelinedeqp::gles31::Functional::__anonf652bf1a0111::Pipeline952*35238bceSAndroid Build Coastguard Worker Pipeline(MovePtr<ProgramPipeline> pipeline_, MovePtr<ProgramWrapper> fullProg_, MovePtr<ProgramWrapper> vtxProg_,
953*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> frgProg_)
954*35238bceSAndroid Build Coastguard Worker : pipeline(pipeline_)
955*35238bceSAndroid Build Coastguard Worker , fullProg(fullProg_)
956*35238bceSAndroid Build Coastguard Worker , vtxProg(vtxProg_)
957*35238bceSAndroid Build Coastguard Worker , frgProg(frgProg_)
958*35238bceSAndroid Build Coastguard Worker {
959*35238bceSAndroid Build Coastguard Worker }
960*35238bceSAndroid Build Coastguard Worker
getVertexProgramdeqp::gles31::Functional::__anonf652bf1a0111::Pipeline961*35238bceSAndroid Build Coastguard Worker ProgramWrapper &getVertexProgram(void) const
962*35238bceSAndroid Build Coastguard Worker {
963*35238bceSAndroid Build Coastguard Worker return vtxProg ? *vtxProg : *fullProg;
964*35238bceSAndroid Build Coastguard Worker }
965*35238bceSAndroid Build Coastguard Worker
getFragmentProgramdeqp::gles31::Functional::__anonf652bf1a0111::Pipeline966*35238bceSAndroid Build Coastguard Worker ProgramWrapper &getFragmentProgram(void) const
967*35238bceSAndroid Build Coastguard Worker {
968*35238bceSAndroid Build Coastguard Worker return frgProg ? *frgProg : *fullProg;
969*35238bceSAndroid Build Coastguard Worker }
970*35238bceSAndroid Build Coastguard Worker
971*35238bceSAndroid Build Coastguard Worker UniquePtr<ProgramPipeline> pipeline;
972*35238bceSAndroid Build Coastguard Worker UniquePtr<ProgramWrapper> fullProg;
973*35238bceSAndroid Build Coastguard Worker UniquePtr<ProgramWrapper> vtxProg;
974*35238bceSAndroid Build Coastguard Worker UniquePtr<ProgramWrapper> frgProg;
975*35238bceSAndroid Build Coastguard Worker };
976*35238bceSAndroid Build Coastguard Worker
logPipeline(TestLog & log,const Pipeline & pipeline)977*35238bceSAndroid Build Coastguard Worker void logPipeline(TestLog &log, const Pipeline &pipeline)
978*35238bceSAndroid Build Coastguard Worker {
979*35238bceSAndroid Build Coastguard Worker ProgramWrapper &vtxProg = pipeline.getVertexProgram();
980*35238bceSAndroid Build Coastguard Worker ProgramWrapper &frgProg = pipeline.getFragmentProgram();
981*35238bceSAndroid Build Coastguard Worker
982*35238bceSAndroid Build Coastguard Worker log.writeMessage("// Failed program pipeline:");
983*35238bceSAndroid Build Coastguard Worker if (&vtxProg == &frgProg)
984*35238bceSAndroid Build Coastguard Worker {
985*35238bceSAndroid Build Coastguard Worker log.writeMessage("// Common program for both vertex and fragment stages:");
986*35238bceSAndroid Build Coastguard Worker vtxProg.writeToLog(log);
987*35238bceSAndroid Build Coastguard Worker }
988*35238bceSAndroid Build Coastguard Worker else
989*35238bceSAndroid Build Coastguard Worker {
990*35238bceSAndroid Build Coastguard Worker log.writeMessage("// Vertex stage program:");
991*35238bceSAndroid Build Coastguard Worker vtxProg.writeToLog(log);
992*35238bceSAndroid Build Coastguard Worker log.writeMessage("// Fragment stage program:");
993*35238bceSAndroid Build Coastguard Worker frgProg.writeToLog(log);
994*35238bceSAndroid Build Coastguard Worker }
995*35238bceSAndroid Build Coastguard Worker }
996*35238bceSAndroid Build Coastguard Worker
997*35238bceSAndroid Build Coastguard Worker // Rectangle
998*35238bceSAndroid Build Coastguard Worker
999*35238bceSAndroid Build Coastguard Worker struct Rectangle
1000*35238bceSAndroid Build Coastguard Worker {
Rectangledeqp::gles31::Functional::__anonf652bf1a0111::Rectangle1001*35238bceSAndroid Build Coastguard Worker Rectangle(int x_, int y_, int width_, int height_) : x(x_), y(y_), width(width_), height(height_)
1002*35238bceSAndroid Build Coastguard Worker {
1003*35238bceSAndroid Build Coastguard Worker }
1004*35238bceSAndroid Build Coastguard Worker int x;
1005*35238bceSAndroid Build Coastguard Worker int y;
1006*35238bceSAndroid Build Coastguard Worker int width;
1007*35238bceSAndroid Build Coastguard Worker int height;
1008*35238bceSAndroid Build Coastguard Worker };
1009*35238bceSAndroid Build Coastguard Worker
setViewport(const RenderContext & renderCtx,const Rectangle & rect)1010*35238bceSAndroid Build Coastguard Worker void setViewport(const RenderContext &renderCtx, const Rectangle &rect)
1011*35238bceSAndroid Build Coastguard Worker {
1012*35238bceSAndroid Build Coastguard Worker renderCtx.getFunctions().viewport(rect.x, rect.y, rect.width, rect.height);
1013*35238bceSAndroid Build Coastguard Worker }
1014*35238bceSAndroid Build Coastguard Worker
readRectangle(const RenderContext & renderCtx,const Rectangle & rect,Surface & dst)1015*35238bceSAndroid Build Coastguard Worker void readRectangle(const RenderContext &renderCtx, const Rectangle &rect, Surface &dst)
1016*35238bceSAndroid Build Coastguard Worker {
1017*35238bceSAndroid Build Coastguard Worker dst.setSize(rect.width, rect.height);
1018*35238bceSAndroid Build Coastguard Worker glu::readPixels(renderCtx, rect.x, rect.y, dst.getAccess());
1019*35238bceSAndroid Build Coastguard Worker }
1020*35238bceSAndroid Build Coastguard Worker
randomViewport(const RenderContext & ctx,Random & rnd,GLint maxWidth,GLint maxHeight)1021*35238bceSAndroid Build Coastguard Worker Rectangle randomViewport(const RenderContext &ctx, Random &rnd, GLint maxWidth, GLint maxHeight)
1022*35238bceSAndroid Build Coastguard Worker {
1023*35238bceSAndroid Build Coastguard Worker const RenderTarget &target = ctx.getRenderTarget();
1024*35238bceSAndroid Build Coastguard Worker GLint width = de::min(target.getWidth(), maxWidth);
1025*35238bceSAndroid Build Coastguard Worker GLint xOff = rnd.getInt(0, target.getWidth() - width);
1026*35238bceSAndroid Build Coastguard Worker GLint height = de::min(target.getHeight(), maxHeight);
1027*35238bceSAndroid Build Coastguard Worker GLint yOff = rnd.getInt(0, target.getHeight() - height);
1028*35238bceSAndroid Build Coastguard Worker
1029*35238bceSAndroid Build Coastguard Worker return Rectangle(xOff, yOff, width, height);
1030*35238bceSAndroid Build Coastguard Worker }
1031*35238bceSAndroid Build Coastguard Worker
1032*35238bceSAndroid Build Coastguard Worker // SeparateShaderTest
1033*35238bceSAndroid Build Coastguard Worker
1034*35238bceSAndroid Build Coastguard Worker class SeparateShaderTest : public TestCase, private CallLogWrapper
1035*35238bceSAndroid Build Coastguard Worker {
1036*35238bceSAndroid Build Coastguard Worker public:
1037*35238bceSAndroid Build Coastguard Worker typedef void (SeparateShaderTest::*TestFunc)(MovePtr<Pipeline> &pipeOut);
1038*35238bceSAndroid Build Coastguard Worker
1039*35238bceSAndroid Build Coastguard Worker SeparateShaderTest(Context &ctx, const string &name, const string &description, int iterations,
1040*35238bceSAndroid Build Coastguard Worker const TestParams ¶ms, TestFunc testFunc);
1041*35238bceSAndroid Build Coastguard Worker
1042*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
1043*35238bceSAndroid Build Coastguard Worker
1044*35238bceSAndroid Build Coastguard Worker void testPipelineRendering(MovePtr<Pipeline> &pipeOut);
1045*35238bceSAndroid Build Coastguard Worker void testCurrentProgPriority(MovePtr<Pipeline> &pipeOut);
1046*35238bceSAndroid Build Coastguard Worker void testActiveProgramUniform(MovePtr<Pipeline> &pipeOut);
1047*35238bceSAndroid Build Coastguard Worker void testPipelineQueryActive(MovePtr<Pipeline> &pipeOut);
1048*35238bceSAndroid Build Coastguard Worker void testPipelineQueryPrograms(MovePtr<Pipeline> &pipeOut);
1049*35238bceSAndroid Build Coastguard Worker
1050*35238bceSAndroid Build Coastguard Worker private:
1051*35238bceSAndroid Build Coastguard Worker TestLog &log(void);
1052*35238bceSAndroid Build Coastguard Worker const RenderContext &getRenderContext(void);
1053*35238bceSAndroid Build Coastguard Worker
1054*35238bceSAndroid Build Coastguard Worker void setUniform(ProgramWrapper &program, const string &uniformName, GLfloat value, bool useProgramUni);
1055*35238bceSAndroid Build Coastguard Worker
1056*35238bceSAndroid Build Coastguard Worker void drawSurface(Surface &dst, uint32_t seed = 0);
1057*35238bceSAndroid Build Coastguard Worker
1058*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> createShaderProgram(const string *vtxSource, const string *frgSource, bool separable);
1059*35238bceSAndroid Build Coastguard Worker
1060*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> createSingleShaderProgram(ShaderType shaderType, const string &src);
1061*35238bceSAndroid Build Coastguard Worker
1062*35238bceSAndroid Build Coastguard Worker MovePtr<Pipeline> createPipeline(const ProgramParams &pp);
1063*35238bceSAndroid Build Coastguard Worker
1064*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> createReferenceProgram(const ProgramParams &pp);
1065*35238bceSAndroid Build Coastguard Worker
1066*35238bceSAndroid Build Coastguard Worker int m_iterations;
1067*35238bceSAndroid Build Coastguard Worker int m_currentIteration;
1068*35238bceSAndroid Build Coastguard Worker TestParams m_params;
1069*35238bceSAndroid Build Coastguard Worker TestFunc m_testFunc;
1070*35238bceSAndroid Build Coastguard Worker Random m_rnd;
1071*35238bceSAndroid Build Coastguard Worker ResultCollector m_status;
1072*35238bceSAndroid Build Coastguard Worker VaryingInterface m_varyings;
1073*35238bceSAndroid Build Coastguard Worker
1074*35238bceSAndroid Build Coastguard Worker // Per-iteration state required for logging on exception
1075*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> m_fullProg;
1076*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> m_vtxProg;
1077*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> m_frgProg;
1078*35238bceSAndroid Build Coastguard Worker };
1079*35238bceSAndroid Build Coastguard Worker
getRenderContext(void)1080*35238bceSAndroid Build Coastguard Worker const RenderContext &SeparateShaderTest::getRenderContext(void)
1081*35238bceSAndroid Build Coastguard Worker {
1082*35238bceSAndroid Build Coastguard Worker return m_context.getRenderContext();
1083*35238bceSAndroid Build Coastguard Worker }
1084*35238bceSAndroid Build Coastguard Worker
log(void)1085*35238bceSAndroid Build Coastguard Worker TestLog &SeparateShaderTest::log(void)
1086*35238bceSAndroid Build Coastguard Worker {
1087*35238bceSAndroid Build Coastguard Worker return m_testCtx.getLog();
1088*35238bceSAndroid Build Coastguard Worker }
1089*35238bceSAndroid Build Coastguard Worker
SeparateShaderTest(Context & ctx,const string & name,const string & description,int iterations,const TestParams & params,TestFunc testFunc)1090*35238bceSAndroid Build Coastguard Worker SeparateShaderTest::SeparateShaderTest(Context &ctx, const string &name, const string &description, int iterations,
1091*35238bceSAndroid Build Coastguard Worker const TestParams ¶ms, TestFunc testFunc)
1092*35238bceSAndroid Build Coastguard Worker : TestCase(ctx, name.c_str(), description.c_str())
1093*35238bceSAndroid Build Coastguard Worker , CallLogWrapper(ctx.getRenderContext().getFunctions(), log())
1094*35238bceSAndroid Build Coastguard Worker , m_iterations(iterations)
1095*35238bceSAndroid Build Coastguard Worker , m_currentIteration(0)
1096*35238bceSAndroid Build Coastguard Worker , m_params(params)
1097*35238bceSAndroid Build Coastguard Worker , m_testFunc(testFunc)
1098*35238bceSAndroid Build Coastguard Worker , m_rnd(paramsSeed(params))
1099*35238bceSAndroid Build Coastguard Worker , m_status(log(), "// ")
1100*35238bceSAndroid Build Coastguard Worker , m_varyings(genVaryingInterface(params.varyings, m_rnd))
1101*35238bceSAndroid Build Coastguard Worker {
1102*35238bceSAndroid Build Coastguard Worker DE_ASSERT(paramsValid(params));
1103*35238bceSAndroid Build Coastguard Worker DE_ASSERT(varyingsValid(m_varyings));
1104*35238bceSAndroid Build Coastguard Worker }
1105*35238bceSAndroid Build Coastguard Worker
createShaderProgram(const string * vtxSource,const string * frgSource,bool separable)1106*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> SeparateShaderTest::createShaderProgram(const string *vtxSource, const string *frgSource,
1107*35238bceSAndroid Build Coastguard Worker bool separable)
1108*35238bceSAndroid Build Coastguard Worker {
1109*35238bceSAndroid Build Coastguard Worker ProgramSources sources;
1110*35238bceSAndroid Build Coastguard Worker
1111*35238bceSAndroid Build Coastguard Worker if (vtxSource != DE_NULL)
1112*35238bceSAndroid Build Coastguard Worker sources << VertexSource(*vtxSource);
1113*35238bceSAndroid Build Coastguard Worker if (frgSource != DE_NULL)
1114*35238bceSAndroid Build Coastguard Worker sources << FragmentSource(*frgSource);
1115*35238bceSAndroid Build Coastguard Worker sources << ProgramSeparable(separable);
1116*35238bceSAndroid Build Coastguard Worker
1117*35238bceSAndroid Build Coastguard Worker MovePtr<ShaderProgramWrapper> wrapper(new ShaderProgramWrapper(getRenderContext(), sources));
1118*35238bceSAndroid Build Coastguard Worker if (!wrapper->getShaderProgram().isOk())
1119*35238bceSAndroid Build Coastguard Worker {
1120*35238bceSAndroid Build Coastguard Worker log().writeMessage("Couldn't create shader program");
1121*35238bceSAndroid Build Coastguard Worker wrapper->writeToLog(log());
1122*35238bceSAndroid Build Coastguard Worker TCU_FAIL("Couldn't create shader program");
1123*35238bceSAndroid Build Coastguard Worker }
1124*35238bceSAndroid Build Coastguard Worker
1125*35238bceSAndroid Build Coastguard Worker return MovePtr<ProgramWrapper>(wrapper.release());
1126*35238bceSAndroid Build Coastguard Worker }
1127*35238bceSAndroid Build Coastguard Worker
createSingleShaderProgram(ShaderType shaderType,const string & src)1128*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> SeparateShaderTest::createSingleShaderProgram(ShaderType shaderType, const string &src)
1129*35238bceSAndroid Build Coastguard Worker {
1130*35238bceSAndroid Build Coastguard Worker const RenderContext &renderCtx = getRenderContext();
1131*35238bceSAndroid Build Coastguard Worker
1132*35238bceSAndroid Build Coastguard Worker if (m_params.useCreateHelper)
1133*35238bceSAndroid Build Coastguard Worker {
1134*35238bceSAndroid Build Coastguard Worker const char *const srcStr = src.c_str();
1135*35238bceSAndroid Build Coastguard Worker const GLenum glType = glu::getGLShaderType(shaderType);
1136*35238bceSAndroid Build Coastguard Worker const GLuint programName = glCreateShaderProgramv(glType, 1, &srcStr);
1137*35238bceSAndroid Build Coastguard Worker
1138*35238bceSAndroid Build Coastguard Worker if (glGetError() != GL_NO_ERROR || programName == 0)
1139*35238bceSAndroid Build Coastguard Worker {
1140*35238bceSAndroid Build Coastguard Worker qpShaderType qpType = glu::getLogShaderType(shaderType);
1141*35238bceSAndroid Build Coastguard Worker
1142*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "glCreateShaderProgramv() failed" << TestLog::EndMessage
1143*35238bceSAndroid Build Coastguard Worker << TestLog::ShaderProgram(false, "[glCreateShaderProgramv() failed]")
1144*35238bceSAndroid Build Coastguard Worker << TestLog::Shader(qpType, src, false, "[glCreateShaderProgramv() failed]")
1145*35238bceSAndroid Build Coastguard Worker << TestLog::EndShaderProgram;
1146*35238bceSAndroid Build Coastguard Worker TCU_FAIL("glCreateShaderProgramv() failed");
1147*35238bceSAndroid Build Coastguard Worker }
1148*35238bceSAndroid Build Coastguard Worker
1149*35238bceSAndroid Build Coastguard Worker RawProgramWrapper *const wrapper = new RawProgramWrapper(renderCtx, programName, shaderType, src);
1150*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> wrapperPtr(wrapper);
1151*35238bceSAndroid Build Coastguard Worker Program &program = wrapper->getProgram();
1152*35238bceSAndroid Build Coastguard Worker
1153*35238bceSAndroid Build Coastguard Worker if (!program.getLinkStatus())
1154*35238bceSAndroid Build Coastguard Worker {
1155*35238bceSAndroid Build Coastguard Worker log().writeMessage("glCreateShaderProgramv() failed at linking");
1156*35238bceSAndroid Build Coastguard Worker wrapper->writeToLog(log());
1157*35238bceSAndroid Build Coastguard Worker TCU_FAIL("glCreateShaderProgram() failed at linking");
1158*35238bceSAndroid Build Coastguard Worker }
1159*35238bceSAndroid Build Coastguard Worker return wrapperPtr;
1160*35238bceSAndroid Build Coastguard Worker }
1161*35238bceSAndroid Build Coastguard Worker else
1162*35238bceSAndroid Build Coastguard Worker {
1163*35238bceSAndroid Build Coastguard Worker switch (shaderType)
1164*35238bceSAndroid Build Coastguard Worker {
1165*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_VERTEX:
1166*35238bceSAndroid Build Coastguard Worker return createShaderProgram(&src, DE_NULL, true);
1167*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_FRAGMENT:
1168*35238bceSAndroid Build Coastguard Worker return createShaderProgram(DE_NULL, &src, true);
1169*35238bceSAndroid Build Coastguard Worker default:
1170*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible case");
1171*35238bceSAndroid Build Coastguard Worker }
1172*35238bceSAndroid Build Coastguard Worker }
1173*35238bceSAndroid Build Coastguard Worker return MovePtr<ProgramWrapper>(); // Shut up compiler warnings.
1174*35238bceSAndroid Build Coastguard Worker }
1175*35238bceSAndroid Build Coastguard Worker
setUniform(ProgramWrapper & program,const string & uniformName,GLfloat value,bool useProgramUniform)1176*35238bceSAndroid Build Coastguard Worker void SeparateShaderTest::setUniform(ProgramWrapper &program, const string &uniformName, GLfloat value,
1177*35238bceSAndroid Build Coastguard Worker bool useProgramUniform)
1178*35238bceSAndroid Build Coastguard Worker {
1179*35238bceSAndroid Build Coastguard Worker const GLuint progName = program.getProgramName();
1180*35238bceSAndroid Build Coastguard Worker const GLint location = glGetUniformLocation(progName, uniformName.c_str());
1181*35238bceSAndroid Build Coastguard Worker MessageBuilder msg = log().message();
1182*35238bceSAndroid Build Coastguard Worker
1183*35238bceSAndroid Build Coastguard Worker msg << "// Set program " << progName << "'s uniform '" << uniformName << "' to " << value;
1184*35238bceSAndroid Build Coastguard Worker if (useProgramUniform)
1185*35238bceSAndroid Build Coastguard Worker {
1186*35238bceSAndroid Build Coastguard Worker msg << " using glProgramUniform1f";
1187*35238bceSAndroid Build Coastguard Worker glProgramUniform1f(progName, location, value);
1188*35238bceSAndroid Build Coastguard Worker }
1189*35238bceSAndroid Build Coastguard Worker else
1190*35238bceSAndroid Build Coastguard Worker {
1191*35238bceSAndroid Build Coastguard Worker msg << " using glUseProgram and glUniform1f";
1192*35238bceSAndroid Build Coastguard Worker glUseProgram(progName);
1193*35238bceSAndroid Build Coastguard Worker glUniform1f(location, value);
1194*35238bceSAndroid Build Coastguard Worker glUseProgram(0);
1195*35238bceSAndroid Build Coastguard Worker }
1196*35238bceSAndroid Build Coastguard Worker msg << TestLog::EndMessage;
1197*35238bceSAndroid Build Coastguard Worker }
1198*35238bceSAndroid Build Coastguard Worker
createPipeline(const ProgramParams & pp)1199*35238bceSAndroid Build Coastguard Worker MovePtr<Pipeline> SeparateShaderTest::createPipeline(const ProgramParams &pp)
1200*35238bceSAndroid Build Coastguard Worker {
1201*35238bceSAndroid Build Coastguard Worker const bool useUniform = m_params.useUniform;
1202*35238bceSAndroid Build Coastguard Worker const string vtxName = m_params.useSameName ? "scale" : "vtxScale";
1203*35238bceSAndroid Build Coastguard Worker const uint32_t initVtxSeed = m_params.switchVtx ? m_rnd.getUint32() : pp.vtxSeed;
1204*35238bceSAndroid Build Coastguard Worker
1205*35238bceSAndroid Build Coastguard Worker const string frgName = m_params.useSameName ? "scale" : "frgScale";
1206*35238bceSAndroid Build Coastguard Worker const uint32_t initFrgSeed = m_params.switchFrg ? m_rnd.getUint32() : pp.frgSeed;
1207*35238bceSAndroid Build Coastguard Worker const string frgSource = genFrgShaderSrc(initFrgSeed, m_varyings.frgInputs, frgName, useUniform, pp.frgScale);
1208*35238bceSAndroid Build Coastguard Worker
1209*35238bceSAndroid Build Coastguard Worker const RenderContext &renderCtx = getRenderContext();
1210*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramPipeline> pipeline(new ProgramPipeline(renderCtx));
1211*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> fullProg;
1212*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> vtxProg;
1213*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> frgProg;
1214*35238bceSAndroid Build Coastguard Worker
1215*35238bceSAndroid Build Coastguard Worker // We cannot allow a situation where we have a single program with a
1216*35238bceSAndroid Build Coastguard Worker // single uniform, because then the vertex and fragment shader uniforms
1217*35238bceSAndroid Build Coastguard Worker // would not be distinct in the final pipeline, and we are going to test
1218*35238bceSAndroid Build Coastguard Worker // that altering one uniform will not affect the other.
1219*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!(m_params.initSingle && m_params.useSameName && !m_params.switchVtx && !m_params.switchFrg));
1220*35238bceSAndroid Build Coastguard Worker
1221*35238bceSAndroid Build Coastguard Worker if (m_params.initSingle)
1222*35238bceSAndroid Build Coastguard Worker {
1223*35238bceSAndroid Build Coastguard Worker string vtxSource =
1224*35238bceSAndroid Build Coastguard Worker genVtxShaderSrc(initVtxSeed, varyingCompatVtxOutputs(m_varyings), vtxName, useUniform, pp.vtxScale);
1225*35238bceSAndroid Build Coastguard Worker fullProg = createShaderProgram(&vtxSource, &frgSource, true);
1226*35238bceSAndroid Build Coastguard Worker pipeline->useProgramStages(GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, fullProg->getProgramName());
1227*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Created pipeline " << pipeline->getPipeline() << " with two-shader program "
1228*35238bceSAndroid Build Coastguard Worker << fullProg->getProgramName() << TestLog::EndMessage;
1229*35238bceSAndroid Build Coastguard Worker }
1230*35238bceSAndroid Build Coastguard Worker else
1231*35238bceSAndroid Build Coastguard Worker {
1232*35238bceSAndroid Build Coastguard Worker string vtxSource = genVtxShaderSrc(initVtxSeed, m_varyings.vtxOutputs, vtxName, useUniform, pp.vtxScale);
1233*35238bceSAndroid Build Coastguard Worker vtxProg = createSingleShaderProgram(glu::SHADERTYPE_VERTEX, vtxSource);
1234*35238bceSAndroid Build Coastguard Worker pipeline->useProgramStages(GL_VERTEX_SHADER_BIT, vtxProg->getProgramName());
1235*35238bceSAndroid Build Coastguard Worker
1236*35238bceSAndroid Build Coastguard Worker frgProg = createSingleShaderProgram(glu::SHADERTYPE_FRAGMENT, frgSource);
1237*35238bceSAndroid Build Coastguard Worker pipeline->useProgramStages(GL_FRAGMENT_SHADER_BIT, frgProg->getProgramName());
1238*35238bceSAndroid Build Coastguard Worker
1239*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Created pipeline " << pipeline->getPipeline() << " with vertex program "
1240*35238bceSAndroid Build Coastguard Worker << vtxProg->getProgramName() << " and fragment program " << frgProg->getProgramName()
1241*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1242*35238bceSAndroid Build Coastguard Worker }
1243*35238bceSAndroid Build Coastguard Worker
1244*35238bceSAndroid Build Coastguard Worker m_status.check(pipeline->isValid(), "Pipeline is invalid after initialization");
1245*35238bceSAndroid Build Coastguard Worker
1246*35238bceSAndroid Build Coastguard Worker if (m_params.switchVtx)
1247*35238bceSAndroid Build Coastguard Worker {
1248*35238bceSAndroid Build Coastguard Worker string newSource = genVtxShaderSrc(pp.vtxSeed, m_varyings.vtxOutputs, vtxName, useUniform, pp.vtxScale);
1249*35238bceSAndroid Build Coastguard Worker vtxProg = createSingleShaderProgram(glu::SHADERTYPE_VERTEX, newSource);
1250*35238bceSAndroid Build Coastguard Worker pipeline->useProgramStages(GL_VERTEX_SHADER_BIT, vtxProg->getProgramName());
1251*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Switched pipeline " << pipeline->getPipeline()
1252*35238bceSAndroid Build Coastguard Worker << "'s vertex stage to single-shader program " << vtxProg->getProgramName() << TestLog::EndMessage;
1253*35238bceSAndroid Build Coastguard Worker }
1254*35238bceSAndroid Build Coastguard Worker if (m_params.switchFrg)
1255*35238bceSAndroid Build Coastguard Worker {
1256*35238bceSAndroid Build Coastguard Worker string newSource = genFrgShaderSrc(pp.frgSeed, m_varyings.frgInputs, frgName, useUniform, pp.frgScale);
1257*35238bceSAndroid Build Coastguard Worker frgProg = createSingleShaderProgram(glu::SHADERTYPE_FRAGMENT, newSource);
1258*35238bceSAndroid Build Coastguard Worker pipeline->useProgramStages(GL_FRAGMENT_SHADER_BIT, frgProg->getProgramName());
1259*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Switched pipeline " << pipeline->getPipeline()
1260*35238bceSAndroid Build Coastguard Worker << "'s fragment stage to single-shader program " << frgProg->getProgramName() << TestLog::EndMessage;
1261*35238bceSAndroid Build Coastguard Worker }
1262*35238bceSAndroid Build Coastguard Worker
1263*35238bceSAndroid Build Coastguard Worker if (m_params.switchVtx || m_params.switchFrg)
1264*35238bceSAndroid Build Coastguard Worker m_status.check(pipeline->isValid(), "Pipeline became invalid after changing a stage's program");
1265*35238bceSAndroid Build Coastguard Worker
1266*35238bceSAndroid Build Coastguard Worker if (m_params.useUniform)
1267*35238bceSAndroid Build Coastguard Worker {
1268*35238bceSAndroid Build Coastguard Worker ProgramWrapper &vtxStage = *(vtxProg ? vtxProg : fullProg);
1269*35238bceSAndroid Build Coastguard Worker ProgramWrapper &frgStage = *(frgProg ? frgProg : fullProg);
1270*35238bceSAndroid Build Coastguard Worker
1271*35238bceSAndroid Build Coastguard Worker setUniform(vtxStage, vtxName, pp.vtxScale, m_params.useProgramUniform);
1272*35238bceSAndroid Build Coastguard Worker setUniform(frgStage, frgName, pp.frgScale, m_params.useProgramUniform);
1273*35238bceSAndroid Build Coastguard Worker }
1274*35238bceSAndroid Build Coastguard Worker else
1275*35238bceSAndroid Build Coastguard Worker log().writeMessage("// Programs use constants instead of uniforms");
1276*35238bceSAndroid Build Coastguard Worker
1277*35238bceSAndroid Build Coastguard Worker return MovePtr<Pipeline>(new Pipeline(pipeline, fullProg, vtxProg, frgProg));
1278*35238bceSAndroid Build Coastguard Worker }
1279*35238bceSAndroid Build Coastguard Worker
createReferenceProgram(const ProgramParams & pp)1280*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> SeparateShaderTest::createReferenceProgram(const ProgramParams &pp)
1281*35238bceSAndroid Build Coastguard Worker {
1282*35238bceSAndroid Build Coastguard Worker bool useUniform = m_params.useUniform;
1283*35238bceSAndroid Build Coastguard Worker const string vtxSrc =
1284*35238bceSAndroid Build Coastguard Worker genVtxShaderSrc(pp.vtxSeed, varyingCompatVtxOutputs(m_varyings), "vtxScale", useUniform, pp.vtxScale);
1285*35238bceSAndroid Build Coastguard Worker const string frgSrc = genFrgShaderSrc(pp.frgSeed, m_varyings.frgInputs, "frgScale", useUniform, pp.frgScale);
1286*35238bceSAndroid Build Coastguard Worker MovePtr<ProgramWrapper> program = createShaderProgram(&vtxSrc, &frgSrc, false);
1287*35238bceSAndroid Build Coastguard Worker GLuint progName = program->getProgramName();
1288*35238bceSAndroid Build Coastguard Worker
1289*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Created monolithic shader program " << progName << TestLog::EndMessage;
1290*35238bceSAndroid Build Coastguard Worker
1291*35238bceSAndroid Build Coastguard Worker if (useUniform)
1292*35238bceSAndroid Build Coastguard Worker {
1293*35238bceSAndroid Build Coastguard Worker setUniform(*program, "vtxScale", pp.vtxScale, false);
1294*35238bceSAndroid Build Coastguard Worker setUniform(*program, "frgScale", pp.frgScale, false);
1295*35238bceSAndroid Build Coastguard Worker }
1296*35238bceSAndroid Build Coastguard Worker
1297*35238bceSAndroid Build Coastguard Worker return program;
1298*35238bceSAndroid Build Coastguard Worker }
1299*35238bceSAndroid Build Coastguard Worker
drawSurface(Surface & dst,uint32_t seed)1300*35238bceSAndroid Build Coastguard Worker void SeparateShaderTest::drawSurface(Surface &dst, uint32_t seed)
1301*35238bceSAndroid Build Coastguard Worker {
1302*35238bceSAndroid Build Coastguard Worker const RenderContext &renderCtx = getRenderContext();
1303*35238bceSAndroid Build Coastguard Worker Random rnd(seed > 0 ? seed : m_rnd.getUint32());
1304*35238bceSAndroid Build Coastguard Worker Rectangle viewport = randomViewport(renderCtx, rnd, VIEWPORT_SIZE, VIEWPORT_SIZE);
1305*35238bceSAndroid Build Coastguard Worker uint32_t vao = 0;
1306*35238bceSAndroid Build Coastguard Worker
1307*35238bceSAndroid Build Coastguard Worker if (!glu::isContextTypeES(renderCtx.getType()))
1308*35238bceSAndroid Build Coastguard Worker {
1309*35238bceSAndroid Build Coastguard Worker glGenVertexArrays(1, &vao);
1310*35238bceSAndroid Build Coastguard Worker glBindVertexArray(vao);
1311*35238bceSAndroid Build Coastguard Worker }
1312*35238bceSAndroid Build Coastguard Worker
1313*35238bceSAndroid Build Coastguard Worker glClearColor(0.125f, 0.25f, 0.5f, 1.f);
1314*35238bceSAndroid Build Coastguard Worker setViewport(renderCtx, viewport);
1315*35238bceSAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1316*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
1317*35238bceSAndroid Build Coastguard Worker readRectangle(renderCtx, viewport, dst);
1318*35238bceSAndroid Build Coastguard Worker log().writeMessage("// Drew a triangle");
1319*35238bceSAndroid Build Coastguard Worker
1320*35238bceSAndroid Build Coastguard Worker if (vao)
1321*35238bceSAndroid Build Coastguard Worker glDeleteVertexArrays(1, &vao);
1322*35238bceSAndroid Build Coastguard Worker }
1323*35238bceSAndroid Build Coastguard Worker
testPipelineRendering(MovePtr<Pipeline> & pipeOut)1324*35238bceSAndroid Build Coastguard Worker void SeparateShaderTest::testPipelineRendering(MovePtr<Pipeline> &pipeOut)
1325*35238bceSAndroid Build Coastguard Worker {
1326*35238bceSAndroid Build Coastguard Worker ProgramParams pp = genProgramParams(m_rnd);
1327*35238bceSAndroid Build Coastguard Worker Pipeline &pipeline = *(pipeOut = createPipeline(pp));
1328*35238bceSAndroid Build Coastguard Worker GLuint pipeName = pipeline.pipeline->getPipeline();
1329*35238bceSAndroid Build Coastguard Worker UniquePtr<ProgramWrapper> refProgram(createReferenceProgram(pp));
1330*35238bceSAndroid Build Coastguard Worker GLuint refProgName = refProgram->getProgramName();
1331*35238bceSAndroid Build Coastguard Worker Surface refSurface;
1332*35238bceSAndroid Build Coastguard Worker Surface pipelineSurface;
1333*35238bceSAndroid Build Coastguard Worker GLuint drawSeed = m_rnd.getUint32();
1334*35238bceSAndroid Build Coastguard Worker
1335*35238bceSAndroid Build Coastguard Worker glUseProgram(refProgName);
1336*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Use program " << refProgName << TestLog::EndMessage;
1337*35238bceSAndroid Build Coastguard Worker drawSurface(refSurface, drawSeed);
1338*35238bceSAndroid Build Coastguard Worker glUseProgram(0);
1339*35238bceSAndroid Build Coastguard Worker
1340*35238bceSAndroid Build Coastguard Worker glBindProgramPipeline(pipeName);
1341*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Bind pipeline " << pipeName << TestLog::EndMessage;
1342*35238bceSAndroid Build Coastguard Worker drawSurface(pipelineSurface, drawSeed);
1343*35238bceSAndroid Build Coastguard Worker glBindProgramPipeline(0);
1344*35238bceSAndroid Build Coastguard Worker
1345*35238bceSAndroid Build Coastguard Worker {
1346*35238bceSAndroid Build Coastguard Worker const bool result = tcu::fuzzyCompare(m_testCtx.getLog(), "Program pipeline result",
1347*35238bceSAndroid Build Coastguard Worker "Result of comparing a program pipeline with a monolithic program",
1348*35238bceSAndroid Build Coastguard Worker refSurface, pipelineSurface, 0.05f, tcu::COMPARE_LOG_RESULT);
1349*35238bceSAndroid Build Coastguard Worker
1350*35238bceSAndroid Build Coastguard Worker m_status.check(result, "Pipeline rendering differs from equivalent monolithic program");
1351*35238bceSAndroid Build Coastguard Worker }
1352*35238bceSAndroid Build Coastguard Worker }
1353*35238bceSAndroid Build Coastguard Worker
testCurrentProgPriority(MovePtr<Pipeline> & pipeOut)1354*35238bceSAndroid Build Coastguard Worker void SeparateShaderTest::testCurrentProgPriority(MovePtr<Pipeline> &pipeOut)
1355*35238bceSAndroid Build Coastguard Worker {
1356*35238bceSAndroid Build Coastguard Worker ProgramParams pipePp = genProgramParams(m_rnd);
1357*35238bceSAndroid Build Coastguard Worker ProgramParams programPp = genProgramParams(m_rnd);
1358*35238bceSAndroid Build Coastguard Worker Pipeline &pipeline = *(pipeOut = createPipeline(pipePp));
1359*35238bceSAndroid Build Coastguard Worker GLuint pipeName = pipeline.pipeline->getPipeline();
1360*35238bceSAndroid Build Coastguard Worker UniquePtr<ProgramWrapper> program(createReferenceProgram(programPp));
1361*35238bceSAndroid Build Coastguard Worker Surface pipelineSurface;
1362*35238bceSAndroid Build Coastguard Worker Surface refSurface;
1363*35238bceSAndroid Build Coastguard Worker Surface resultSurface;
1364*35238bceSAndroid Build Coastguard Worker uint32_t drawSeed = m_rnd.getUint32();
1365*35238bceSAndroid Build Coastguard Worker
1366*35238bceSAndroid Build Coastguard Worker LOG_CALL(glBindProgramPipeline(pipeName));
1367*35238bceSAndroid Build Coastguard Worker drawSurface(pipelineSurface, drawSeed);
1368*35238bceSAndroid Build Coastguard Worker LOG_CALL(glBindProgramPipeline(0));
1369*35238bceSAndroid Build Coastguard Worker
1370*35238bceSAndroid Build Coastguard Worker LOG_CALL(glUseProgram(program->getProgramName()));
1371*35238bceSAndroid Build Coastguard Worker drawSurface(refSurface, drawSeed);
1372*35238bceSAndroid Build Coastguard Worker LOG_CALL(glUseProgram(0));
1373*35238bceSAndroid Build Coastguard Worker
1374*35238bceSAndroid Build Coastguard Worker LOG_CALL(glUseProgram(program->getProgramName()));
1375*35238bceSAndroid Build Coastguard Worker LOG_CALL(glBindProgramPipeline(pipeName));
1376*35238bceSAndroid Build Coastguard Worker drawSurface(resultSurface, drawSeed);
1377*35238bceSAndroid Build Coastguard Worker LOG_CALL(glBindProgramPipeline(0));
1378*35238bceSAndroid Build Coastguard Worker LOG_CALL(glUseProgram(0));
1379*35238bceSAndroid Build Coastguard Worker
1380*35238bceSAndroid Build Coastguard Worker bool result = tcu::pixelThresholdCompare(m_testCtx.getLog(), "Active program rendering result",
1381*35238bceSAndroid Build Coastguard Worker "Active program rendering result", refSurface, resultSurface,
1382*35238bceSAndroid Build Coastguard Worker tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
1383*35238bceSAndroid Build Coastguard Worker
1384*35238bceSAndroid Build Coastguard Worker m_status.check(result, "glBindProgramPipeline() affects glUseProgram()");
1385*35238bceSAndroid Build Coastguard Worker if (!result)
1386*35238bceSAndroid Build Coastguard Worker log() << TestLog::Image("Pipeline image", "Image produced by pipeline", pipelineSurface);
1387*35238bceSAndroid Build Coastguard Worker }
1388*35238bceSAndroid Build Coastguard Worker
testActiveProgramUniform(MovePtr<Pipeline> & pipeOut)1389*35238bceSAndroid Build Coastguard Worker void SeparateShaderTest::testActiveProgramUniform(MovePtr<Pipeline> &pipeOut)
1390*35238bceSAndroid Build Coastguard Worker {
1391*35238bceSAndroid Build Coastguard Worker ProgramParams refPp = genProgramParams(m_rnd);
1392*35238bceSAndroid Build Coastguard Worker Surface refSurface;
1393*35238bceSAndroid Build Coastguard Worker Surface resultSurface;
1394*35238bceSAndroid Build Coastguard Worker uint32_t drawSeed = m_rnd.getUint32();
1395*35238bceSAndroid Build Coastguard Worker
1396*35238bceSAndroid Build Coastguard Worker DE_UNREF(pipeOut);
1397*35238bceSAndroid Build Coastguard Worker {
1398*35238bceSAndroid Build Coastguard Worker UniquePtr<ProgramWrapper> refProg(createReferenceProgram(refPp));
1399*35238bceSAndroid Build Coastguard Worker GLuint refProgName = refProg->getProgramName();
1400*35238bceSAndroid Build Coastguard Worker
1401*35238bceSAndroid Build Coastguard Worker glUseProgram(refProgName);
1402*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Use reference program " << refProgName << TestLog::EndMessage;
1403*35238bceSAndroid Build Coastguard Worker drawSurface(refSurface, drawSeed);
1404*35238bceSAndroid Build Coastguard Worker glUseProgram(0);
1405*35238bceSAndroid Build Coastguard Worker }
1406*35238bceSAndroid Build Coastguard Worker
1407*35238bceSAndroid Build Coastguard Worker {
1408*35238bceSAndroid Build Coastguard Worker ProgramParams changePp = genProgramParams(m_rnd);
1409*35238bceSAndroid Build Coastguard Worker changePp.vtxSeed = refPp.vtxSeed;
1410*35238bceSAndroid Build Coastguard Worker changePp.frgSeed = refPp.frgSeed;
1411*35238bceSAndroid Build Coastguard Worker UniquePtr<ProgramWrapper> changeProg(createReferenceProgram(changePp));
1412*35238bceSAndroid Build Coastguard Worker GLuint changeName = changeProg->getProgramName();
1413*35238bceSAndroid Build Coastguard Worker ProgramPipeline pipeline(getRenderContext());
1414*35238bceSAndroid Build Coastguard Worker GLint vtxLoc = glGetUniformLocation(changeName, "vtxScale");
1415*35238bceSAndroid Build Coastguard Worker GLint frgLoc = glGetUniformLocation(changeName, "frgScale");
1416*35238bceSAndroid Build Coastguard Worker
1417*35238bceSAndroid Build Coastguard Worker LOG_CALL(glBindProgramPipeline(pipeline.getPipeline()));
1418*35238bceSAndroid Build Coastguard Worker
1419*35238bceSAndroid Build Coastguard Worker pipeline.activeShaderProgram(changeName);
1420*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Set active shader program to " << changeName << TestLog::EndMessage;
1421*35238bceSAndroid Build Coastguard Worker
1422*35238bceSAndroid Build Coastguard Worker glUniform1f(vtxLoc, refPp.vtxScale);
1423*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Set uniform 'vtxScale' to " << refPp.vtxScale << " using glUniform1f"
1424*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1425*35238bceSAndroid Build Coastguard Worker glUniform1f(frgLoc, refPp.frgScale);
1426*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Set uniform 'frgScale' to " << refPp.frgScale << " using glUniform1f"
1427*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1428*35238bceSAndroid Build Coastguard Worker
1429*35238bceSAndroid Build Coastguard Worker pipeline.activeShaderProgram(0);
1430*35238bceSAndroid Build Coastguard Worker LOG_CALL(glBindProgramPipeline(0));
1431*35238bceSAndroid Build Coastguard Worker
1432*35238bceSAndroid Build Coastguard Worker LOG_CALL(glUseProgram(changeName));
1433*35238bceSAndroid Build Coastguard Worker drawSurface(resultSurface, drawSeed);
1434*35238bceSAndroid Build Coastguard Worker LOG_CALL(glUseProgram(0));
1435*35238bceSAndroid Build Coastguard Worker }
1436*35238bceSAndroid Build Coastguard Worker
1437*35238bceSAndroid Build Coastguard Worker bool result =
1438*35238bceSAndroid Build Coastguard Worker tcu::fuzzyCompare(m_testCtx.getLog(), "Active program uniform result", "Active program uniform result",
1439*35238bceSAndroid Build Coastguard Worker refSurface, resultSurface, 0.05f, tcu::COMPARE_LOG_RESULT);
1440*35238bceSAndroid Build Coastguard Worker
1441*35238bceSAndroid Build Coastguard Worker m_status.check(result, "glUniform() did not correctly modify "
1442*35238bceSAndroid Build Coastguard Worker "the active program of the bound pipeline");
1443*35238bceSAndroid Build Coastguard Worker }
1444*35238bceSAndroid Build Coastguard Worker
testPipelineQueryPrograms(MovePtr<Pipeline> & pipeOut)1445*35238bceSAndroid Build Coastguard Worker void SeparateShaderTest::testPipelineQueryPrograms(MovePtr<Pipeline> &pipeOut)
1446*35238bceSAndroid Build Coastguard Worker {
1447*35238bceSAndroid Build Coastguard Worker ProgramParams pipePp = genProgramParams(m_rnd);
1448*35238bceSAndroid Build Coastguard Worker Pipeline &pipeline = *(pipeOut = createPipeline(pipePp));
1449*35238bceSAndroid Build Coastguard Worker GLuint pipeName = pipeline.pipeline->getPipeline();
1450*35238bceSAndroid Build Coastguard Worker GLint queryVtx = 0;
1451*35238bceSAndroid Build Coastguard Worker GLint queryFrg = 0;
1452*35238bceSAndroid Build Coastguard Worker
1453*35238bceSAndroid Build Coastguard Worker LOG_CALL(GLU_CHECK_CALL(glGetProgramPipelineiv(pipeName, GL_VERTEX_SHADER, &queryVtx)));
1454*35238bceSAndroid Build Coastguard Worker m_status.check(GLuint(queryVtx) == pipeline.getVertexProgram().getProgramName(),
1455*35238bceSAndroid Build Coastguard Worker "Program pipeline query reported wrong vertex shader program");
1456*35238bceSAndroid Build Coastguard Worker
1457*35238bceSAndroid Build Coastguard Worker LOG_CALL(GLU_CHECK_CALL(glGetProgramPipelineiv(pipeName, GL_FRAGMENT_SHADER, &queryFrg)));
1458*35238bceSAndroid Build Coastguard Worker m_status.check(GLuint(queryFrg) == pipeline.getFragmentProgram().getProgramName(),
1459*35238bceSAndroid Build Coastguard Worker "Program pipeline query reported wrong fragment shader program");
1460*35238bceSAndroid Build Coastguard Worker }
1461*35238bceSAndroid Build Coastguard Worker
testPipelineQueryActive(MovePtr<Pipeline> & pipeOut)1462*35238bceSAndroid Build Coastguard Worker void SeparateShaderTest::testPipelineQueryActive(MovePtr<Pipeline> &pipeOut)
1463*35238bceSAndroid Build Coastguard Worker {
1464*35238bceSAndroid Build Coastguard Worker ProgramParams pipePp = genProgramParams(m_rnd);
1465*35238bceSAndroid Build Coastguard Worker Pipeline &pipeline = *(pipeOut = createPipeline(pipePp));
1466*35238bceSAndroid Build Coastguard Worker GLuint pipeName = pipeline.pipeline->getPipeline();
1467*35238bceSAndroid Build Coastguard Worker GLuint newActive = pipeline.getVertexProgram().getProgramName();
1468*35238bceSAndroid Build Coastguard Worker GLint queryActive = 0;
1469*35238bceSAndroid Build Coastguard Worker
1470*35238bceSAndroid Build Coastguard Worker LOG_CALL(GLU_CHECK_CALL(glGetProgramPipelineiv(pipeName, GL_ACTIVE_PROGRAM, &queryActive)));
1471*35238bceSAndroid Build Coastguard Worker m_status.check(queryActive == 0, "Program pipeline query reported non-zero initial active program");
1472*35238bceSAndroid Build Coastguard Worker
1473*35238bceSAndroid Build Coastguard Worker pipeline.pipeline->activeShaderProgram(newActive);
1474*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "Set pipeline " << pipeName << "'s active shader program to " << newActive
1475*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1476*35238bceSAndroid Build Coastguard Worker
1477*35238bceSAndroid Build Coastguard Worker LOG_CALL(GLU_CHECK_CALL(glGetProgramPipelineiv(pipeName, GL_ACTIVE_PROGRAM, &queryActive)));
1478*35238bceSAndroid Build Coastguard Worker m_status.check(GLuint(queryActive) == newActive, "Program pipeline query reported incorrect active program");
1479*35238bceSAndroid Build Coastguard Worker
1480*35238bceSAndroid Build Coastguard Worker pipeline.pipeline->activeShaderProgram(0);
1481*35238bceSAndroid Build Coastguard Worker }
1482*35238bceSAndroid Build Coastguard Worker
iterate(void)1483*35238bceSAndroid Build Coastguard Worker TestCase::IterateResult SeparateShaderTest::iterate(void)
1484*35238bceSAndroid Build Coastguard Worker {
1485*35238bceSAndroid Build Coastguard Worker MovePtr<Pipeline> pipeline;
1486*35238bceSAndroid Build Coastguard Worker
1487*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_iterations > 0);
1488*35238bceSAndroid Build Coastguard Worker
1489*35238bceSAndroid Build Coastguard Worker if (m_currentIteration == 0)
1490*35238bceSAndroid Build Coastguard Worker logParams(log(), m_params);
1491*35238bceSAndroid Build Coastguard Worker
1492*35238bceSAndroid Build Coastguard Worker ++m_currentIteration;
1493*35238bceSAndroid Build Coastguard Worker
1494*35238bceSAndroid Build Coastguard Worker try
1495*35238bceSAndroid Build Coastguard Worker {
1496*35238bceSAndroid Build Coastguard Worker (this->*m_testFunc)(pipeline);
1497*35238bceSAndroid Build Coastguard Worker log().writeMessage("");
1498*35238bceSAndroid Build Coastguard Worker }
1499*35238bceSAndroid Build Coastguard Worker catch (const tcu::Exception &)
1500*35238bceSAndroid Build Coastguard Worker {
1501*35238bceSAndroid Build Coastguard Worker if (pipeline)
1502*35238bceSAndroid Build Coastguard Worker logPipeline(log(), *pipeline);
1503*35238bceSAndroid Build Coastguard Worker throw;
1504*35238bceSAndroid Build Coastguard Worker }
1505*35238bceSAndroid Build Coastguard Worker
1506*35238bceSAndroid Build Coastguard Worker if (m_status.getResult() != QP_TEST_RESULT_PASS)
1507*35238bceSAndroid Build Coastguard Worker {
1508*35238bceSAndroid Build Coastguard Worker if (pipeline)
1509*35238bceSAndroid Build Coastguard Worker logPipeline(log(), *pipeline);
1510*35238bceSAndroid Build Coastguard Worker }
1511*35238bceSAndroid Build Coastguard Worker else if (m_currentIteration < m_iterations)
1512*35238bceSAndroid Build Coastguard Worker return CONTINUE;
1513*35238bceSAndroid Build Coastguard Worker
1514*35238bceSAndroid Build Coastguard Worker m_status.setTestContextResult(m_testCtx);
1515*35238bceSAndroid Build Coastguard Worker return STOP;
1516*35238bceSAndroid Build Coastguard Worker }
1517*35238bceSAndroid Build Coastguard Worker
1518*35238bceSAndroid Build Coastguard Worker // Group construction utilities
1519*35238bceSAndroid Build Coastguard Worker
1520*35238bceSAndroid Build Coastguard Worker enum ParamFlags
1521*35238bceSAndroid Build Coastguard Worker {
1522*35238bceSAndroid Build Coastguard Worker PARAMFLAGS_SWITCH_FRAGMENT = 1 << 0,
1523*35238bceSAndroid Build Coastguard Worker PARAMFLAGS_SWITCH_VERTEX = 1 << 1,
1524*35238bceSAndroid Build Coastguard Worker PARAMFLAGS_INIT_SINGLE = 1 << 2,
1525*35238bceSAndroid Build Coastguard Worker PARAMFLAGS_LAST = 1 << 3,
1526*35238bceSAndroid Build Coastguard Worker PARAMFLAGS_MASK = PARAMFLAGS_LAST - 1
1527*35238bceSAndroid Build Coastguard Worker };
1528*35238bceSAndroid Build Coastguard Worker
areCaseParamFlagsValid(ParamFlags flags)1529*35238bceSAndroid Build Coastguard Worker bool areCaseParamFlagsValid(ParamFlags flags)
1530*35238bceSAndroid Build Coastguard Worker {
1531*35238bceSAndroid Build Coastguard Worker const ParamFlags switchAll = ParamFlags(PARAMFLAGS_SWITCH_VERTEX | PARAMFLAGS_SWITCH_FRAGMENT);
1532*35238bceSAndroid Build Coastguard Worker
1533*35238bceSAndroid Build Coastguard Worker if ((flags & PARAMFLAGS_INIT_SINGLE) != 0)
1534*35238bceSAndroid Build Coastguard Worker return (flags & switchAll) == 0 || (flags & switchAll) == switchAll;
1535*35238bceSAndroid Build Coastguard Worker else
1536*35238bceSAndroid Build Coastguard Worker return true;
1537*35238bceSAndroid Build Coastguard Worker }
1538*35238bceSAndroid Build Coastguard Worker
addRenderTest(TestCaseGroup & group,const string & namePrefix,const string & descPrefix,int numIterations,ParamFlags flags,TestParams params)1539*35238bceSAndroid Build Coastguard Worker bool addRenderTest(TestCaseGroup &group, const string &namePrefix, const string &descPrefix, int numIterations,
1540*35238bceSAndroid Build Coastguard Worker ParamFlags flags, TestParams params)
1541*35238bceSAndroid Build Coastguard Worker {
1542*35238bceSAndroid Build Coastguard Worker ostringstream name;
1543*35238bceSAndroid Build Coastguard Worker ostringstream desc;
1544*35238bceSAndroid Build Coastguard Worker
1545*35238bceSAndroid Build Coastguard Worker DE_ASSERT(areCaseParamFlagsValid(flags));
1546*35238bceSAndroid Build Coastguard Worker
1547*35238bceSAndroid Build Coastguard Worker name << namePrefix;
1548*35238bceSAndroid Build Coastguard Worker desc << descPrefix;
1549*35238bceSAndroid Build Coastguard Worker
1550*35238bceSAndroid Build Coastguard Worker params.initSingle = (flags & PARAMFLAGS_INIT_SINGLE) != 0;
1551*35238bceSAndroid Build Coastguard Worker params.switchVtx = (flags & PARAMFLAGS_SWITCH_VERTEX) != 0;
1552*35238bceSAndroid Build Coastguard Worker params.switchFrg = (flags & PARAMFLAGS_SWITCH_FRAGMENT) != 0;
1553*35238bceSAndroid Build Coastguard Worker
1554*35238bceSAndroid Build Coastguard Worker name << (flags & PARAMFLAGS_INIT_SINGLE ? "single_program" : "separate_programs");
1555*35238bceSAndroid Build Coastguard Worker desc << (flags & PARAMFLAGS_INIT_SINGLE ? "Single program with two shaders" : "Separate programs for each shader");
1556*35238bceSAndroid Build Coastguard Worker
1557*35238bceSAndroid Build Coastguard Worker switch (flags & (PARAMFLAGS_SWITCH_FRAGMENT | PARAMFLAGS_SWITCH_VERTEX))
1558*35238bceSAndroid Build Coastguard Worker {
1559*35238bceSAndroid Build Coastguard Worker case 0:
1560*35238bceSAndroid Build Coastguard Worker break;
1561*35238bceSAndroid Build Coastguard Worker case PARAMFLAGS_SWITCH_FRAGMENT:
1562*35238bceSAndroid Build Coastguard Worker name << "_add_fragment";
1563*35238bceSAndroid Build Coastguard Worker desc << ", then add a fragment program";
1564*35238bceSAndroid Build Coastguard Worker break;
1565*35238bceSAndroid Build Coastguard Worker case PARAMFLAGS_SWITCH_VERTEX:
1566*35238bceSAndroid Build Coastguard Worker name << "_add_vertex";
1567*35238bceSAndroid Build Coastguard Worker desc << ", then add a vertex program";
1568*35238bceSAndroid Build Coastguard Worker break;
1569*35238bceSAndroid Build Coastguard Worker case PARAMFLAGS_SWITCH_FRAGMENT | PARAMFLAGS_SWITCH_VERTEX:
1570*35238bceSAndroid Build Coastguard Worker name << "_add_both";
1571*35238bceSAndroid Build Coastguard Worker desc << ", then add both vertex and shader programs";
1572*35238bceSAndroid Build Coastguard Worker break;
1573*35238bceSAndroid Build Coastguard Worker }
1574*35238bceSAndroid Build Coastguard Worker
1575*35238bceSAndroid Build Coastguard Worker if (!paramsValid(params))
1576*35238bceSAndroid Build Coastguard Worker return false;
1577*35238bceSAndroid Build Coastguard Worker
1578*35238bceSAndroid Build Coastguard Worker group.addChild(new SeparateShaderTest(group.getContext(), name.str(), desc.str(), numIterations, params,
1579*35238bceSAndroid Build Coastguard Worker &SeparateShaderTest::testPipelineRendering));
1580*35238bceSAndroid Build Coastguard Worker
1581*35238bceSAndroid Build Coastguard Worker return true;
1582*35238bceSAndroid Build Coastguard Worker }
1583*35238bceSAndroid Build Coastguard Worker
describeInterpolation(const string & stage,VaryingInterpolation qual,ostringstream & name,ostringstream & desc)1584*35238bceSAndroid Build Coastguard Worker void describeInterpolation(const string &stage, VaryingInterpolation qual, ostringstream &name, ostringstream &desc)
1585*35238bceSAndroid Build Coastguard Worker {
1586*35238bceSAndroid Build Coastguard Worker DE_ASSERT(qual < VARYINGINTERPOLATION_RANDOM);
1587*35238bceSAndroid Build Coastguard Worker
1588*35238bceSAndroid Build Coastguard Worker if (qual == VARYINGINTERPOLATION_DEFAULT)
1589*35238bceSAndroid Build Coastguard Worker {
1590*35238bceSAndroid Build Coastguard Worker desc << ", unqualified in " << stage << " shader";
1591*35238bceSAndroid Build Coastguard Worker return;
1592*35238bceSAndroid Build Coastguard Worker }
1593*35238bceSAndroid Build Coastguard Worker else
1594*35238bceSAndroid Build Coastguard Worker {
1595*35238bceSAndroid Build Coastguard Worker const string qualName = glu::getInterpolationName(getGluInterpolation(qual));
1596*35238bceSAndroid Build Coastguard Worker
1597*35238bceSAndroid Build Coastguard Worker name << "_" << stage << "_" << qualName;
1598*35238bceSAndroid Build Coastguard Worker desc << ", qualified '" << qualName << "' in " << stage << " shader";
1599*35238bceSAndroid Build Coastguard Worker }
1600*35238bceSAndroid Build Coastguard Worker }
1601*35238bceSAndroid Build Coastguard Worker
1602*35238bceSAndroid Build Coastguard Worker } // namespace
1603*35238bceSAndroid Build Coastguard Worker
createCommonSeparateShaderTests(Context & ctx)1604*35238bceSAndroid Build Coastguard Worker TestCaseGroup *createCommonSeparateShaderTests(Context &ctx)
1605*35238bceSAndroid Build Coastguard Worker {
1606*35238bceSAndroid Build Coastguard Worker TestParams defaultParams;
1607*35238bceSAndroid Build Coastguard Worker int numIterations = 4;
1608*35238bceSAndroid Build Coastguard Worker TestCaseGroup *group = new TestCaseGroup(ctx, "separate_shader", "Separate shader tests");
1609*35238bceSAndroid Build Coastguard Worker
1610*35238bceSAndroid Build Coastguard Worker defaultParams.useUniform = false;
1611*35238bceSAndroid Build Coastguard Worker defaultParams.initSingle = false;
1612*35238bceSAndroid Build Coastguard Worker defaultParams.switchVtx = false;
1613*35238bceSAndroid Build Coastguard Worker defaultParams.switchFrg = false;
1614*35238bceSAndroid Build Coastguard Worker defaultParams.useCreateHelper = false;
1615*35238bceSAndroid Build Coastguard Worker defaultParams.useProgramUniform = false;
1616*35238bceSAndroid Build Coastguard Worker defaultParams.useSameName = false;
1617*35238bceSAndroid Build Coastguard Worker defaultParams.varyings.count = 0;
1618*35238bceSAndroid Build Coastguard Worker defaultParams.varyings.type = glu::TYPE_INVALID;
1619*35238bceSAndroid Build Coastguard Worker defaultParams.varyings.binding = BINDING_NAME;
1620*35238bceSAndroid Build Coastguard Worker defaultParams.varyings.vtxInterp = VARYINGINTERPOLATION_LAST;
1621*35238bceSAndroid Build Coastguard Worker defaultParams.varyings.frgInterp = VARYINGINTERPOLATION_LAST;
1622*35238bceSAndroid Build Coastguard Worker
1623*35238bceSAndroid Build Coastguard Worker TestCaseGroup *stagesGroup = new TestCaseGroup(ctx, "pipeline", "Pipeline configuration tests");
1624*35238bceSAndroid Build Coastguard Worker group->addChild(stagesGroup);
1625*35238bceSAndroid Build Coastguard Worker
1626*35238bceSAndroid Build Coastguard Worker for (uint32_t flags = 0; flags < PARAMFLAGS_LAST << 2; ++flags)
1627*35238bceSAndroid Build Coastguard Worker {
1628*35238bceSAndroid Build Coastguard Worker TestParams params = defaultParams;
1629*35238bceSAndroid Build Coastguard Worker ostringstream name;
1630*35238bceSAndroid Build Coastguard Worker ostringstream desc;
1631*35238bceSAndroid Build Coastguard Worker
1632*35238bceSAndroid Build Coastguard Worker if (!areCaseParamFlagsValid(ParamFlags(flags & PARAMFLAGS_MASK)))
1633*35238bceSAndroid Build Coastguard Worker continue;
1634*35238bceSAndroid Build Coastguard Worker
1635*35238bceSAndroid Build Coastguard Worker if (flags & (PARAMFLAGS_LAST << 1))
1636*35238bceSAndroid Build Coastguard Worker {
1637*35238bceSAndroid Build Coastguard Worker params.useSameName = true;
1638*35238bceSAndroid Build Coastguard Worker name << "same_";
1639*35238bceSAndroid Build Coastguard Worker desc << "Identically named ";
1640*35238bceSAndroid Build Coastguard Worker }
1641*35238bceSAndroid Build Coastguard Worker else
1642*35238bceSAndroid Build Coastguard Worker {
1643*35238bceSAndroid Build Coastguard Worker name << "different_";
1644*35238bceSAndroid Build Coastguard Worker desc << "Differently named ";
1645*35238bceSAndroid Build Coastguard Worker }
1646*35238bceSAndroid Build Coastguard Worker
1647*35238bceSAndroid Build Coastguard Worker if (flags & PARAMFLAGS_LAST)
1648*35238bceSAndroid Build Coastguard Worker {
1649*35238bceSAndroid Build Coastguard Worker params.useUniform = true;
1650*35238bceSAndroid Build Coastguard Worker name << "uniform_";
1651*35238bceSAndroid Build Coastguard Worker desc << "uniforms, ";
1652*35238bceSAndroid Build Coastguard Worker }
1653*35238bceSAndroid Build Coastguard Worker else
1654*35238bceSAndroid Build Coastguard Worker {
1655*35238bceSAndroid Build Coastguard Worker name << "constant_";
1656*35238bceSAndroid Build Coastguard Worker desc << "constants, ";
1657*35238bceSAndroid Build Coastguard Worker }
1658*35238bceSAndroid Build Coastguard Worker
1659*35238bceSAndroid Build Coastguard Worker addRenderTest(*stagesGroup, name.str(), desc.str(), numIterations, ParamFlags(flags & PARAMFLAGS_MASK), params);
1660*35238bceSAndroid Build Coastguard Worker }
1661*35238bceSAndroid Build Coastguard Worker
1662*35238bceSAndroid Build Coastguard Worker TestCaseGroup *programUniformGroup = new TestCaseGroup(ctx, "program_uniform", "ProgramUniform tests");
1663*35238bceSAndroid Build Coastguard Worker group->addChild(programUniformGroup);
1664*35238bceSAndroid Build Coastguard Worker
1665*35238bceSAndroid Build Coastguard Worker for (uint32_t flags = 0; flags < PARAMFLAGS_LAST; ++flags)
1666*35238bceSAndroid Build Coastguard Worker {
1667*35238bceSAndroid Build Coastguard Worker TestParams params = defaultParams;
1668*35238bceSAndroid Build Coastguard Worker
1669*35238bceSAndroid Build Coastguard Worker if (!areCaseParamFlagsValid(ParamFlags(flags)))
1670*35238bceSAndroid Build Coastguard Worker continue;
1671*35238bceSAndroid Build Coastguard Worker
1672*35238bceSAndroid Build Coastguard Worker params.useUniform = true;
1673*35238bceSAndroid Build Coastguard Worker params.useProgramUniform = true;
1674*35238bceSAndroid Build Coastguard Worker
1675*35238bceSAndroid Build Coastguard Worker addRenderTest(*programUniformGroup, "", "", numIterations, ParamFlags(flags), params);
1676*35238bceSAndroid Build Coastguard Worker }
1677*35238bceSAndroid Build Coastguard Worker
1678*35238bceSAndroid Build Coastguard Worker TestCaseGroup *createShaderProgramGroup =
1679*35238bceSAndroid Build Coastguard Worker new TestCaseGroup(ctx, "create_shader_program", "CreateShaderProgram tests");
1680*35238bceSAndroid Build Coastguard Worker group->addChild(createShaderProgramGroup);
1681*35238bceSAndroid Build Coastguard Worker
1682*35238bceSAndroid Build Coastguard Worker for (uint32_t flags = 0; flags < PARAMFLAGS_LAST; ++flags)
1683*35238bceSAndroid Build Coastguard Worker {
1684*35238bceSAndroid Build Coastguard Worker TestParams params = defaultParams;
1685*35238bceSAndroid Build Coastguard Worker
1686*35238bceSAndroid Build Coastguard Worker if (!areCaseParamFlagsValid(ParamFlags(flags)))
1687*35238bceSAndroid Build Coastguard Worker continue;
1688*35238bceSAndroid Build Coastguard Worker
1689*35238bceSAndroid Build Coastguard Worker params.useCreateHelper = true;
1690*35238bceSAndroid Build Coastguard Worker
1691*35238bceSAndroid Build Coastguard Worker addRenderTest(*createShaderProgramGroup, "", "", numIterations, ParamFlags(flags), params);
1692*35238bceSAndroid Build Coastguard Worker }
1693*35238bceSAndroid Build Coastguard Worker
1694*35238bceSAndroid Build Coastguard Worker TestCaseGroup *interfaceGroup = new TestCaseGroup(ctx, "interface", "Shader interface compatibility tests");
1695*35238bceSAndroid Build Coastguard Worker group->addChild(interfaceGroup);
1696*35238bceSAndroid Build Coastguard Worker
1697*35238bceSAndroid Build Coastguard Worker enum
1698*35238bceSAndroid Build Coastguard Worker {
1699*35238bceSAndroid Build Coastguard Worker NUM_INTERPOLATIONS =
1700*35238bceSAndroid Build Coastguard Worker VARYINGINTERPOLATION_RANDOM, // VARYINGINTERPOLATION_RANDOM is one after last fully specified interpolation
1701*35238bceSAndroid Build Coastguard Worker INTERFACEFLAGS_LAST =
1702*35238bceSAndroid Build Coastguard Worker static_cast<int>(BINDING_LAST) * static_cast<int>(NUM_INTERPOLATIONS) * static_cast<int>(NUM_INTERPOLATIONS)
1703*35238bceSAndroid Build Coastguard Worker };
1704*35238bceSAndroid Build Coastguard Worker
1705*35238bceSAndroid Build Coastguard Worker for (uint32_t flags = 0; flags < INTERFACEFLAGS_LAST; ++flags)
1706*35238bceSAndroid Build Coastguard Worker {
1707*35238bceSAndroid Build Coastguard Worker uint32_t tmpFlags = flags;
1708*35238bceSAndroid Build Coastguard Worker VaryingInterpolation frgInterp = VaryingInterpolation(tmpFlags % NUM_INTERPOLATIONS);
1709*35238bceSAndroid Build Coastguard Worker VaryingInterpolation vtxInterp = VaryingInterpolation((tmpFlags /= NUM_INTERPOLATIONS) % NUM_INTERPOLATIONS);
1710*35238bceSAndroid Build Coastguard Worker BindingKind binding = BindingKind((tmpFlags /= NUM_INTERPOLATIONS) % BINDING_LAST);
1711*35238bceSAndroid Build Coastguard Worker TestParams params = defaultParams;
1712*35238bceSAndroid Build Coastguard Worker ostringstream name;
1713*35238bceSAndroid Build Coastguard Worker ostringstream desc;
1714*35238bceSAndroid Build Coastguard Worker
1715*35238bceSAndroid Build Coastguard Worker params.varyings.count = 1;
1716*35238bceSAndroid Build Coastguard Worker params.varyings.type = glu::TYPE_FLOAT;
1717*35238bceSAndroid Build Coastguard Worker params.varyings.binding = binding;
1718*35238bceSAndroid Build Coastguard Worker params.varyings.vtxInterp = vtxInterp;
1719*35238bceSAndroid Build Coastguard Worker params.varyings.frgInterp = frgInterp;
1720*35238bceSAndroid Build Coastguard Worker
1721*35238bceSAndroid Build Coastguard Worker switch (binding)
1722*35238bceSAndroid Build Coastguard Worker {
1723*35238bceSAndroid Build Coastguard Worker case BINDING_LOCATION:
1724*35238bceSAndroid Build Coastguard Worker name << "same_location";
1725*35238bceSAndroid Build Coastguard Worker desc << "Varyings have same location, ";
1726*35238bceSAndroid Build Coastguard Worker break;
1727*35238bceSAndroid Build Coastguard Worker case BINDING_NAME:
1728*35238bceSAndroid Build Coastguard Worker name << "same_name";
1729*35238bceSAndroid Build Coastguard Worker desc << "Varyings have same name, ";
1730*35238bceSAndroid Build Coastguard Worker break;
1731*35238bceSAndroid Build Coastguard Worker default:
1732*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
1733*35238bceSAndroid Build Coastguard Worker }
1734*35238bceSAndroid Build Coastguard Worker
1735*35238bceSAndroid Build Coastguard Worker describeInterpolation("vertex", vtxInterp, name, desc);
1736*35238bceSAndroid Build Coastguard Worker describeInterpolation("fragment", frgInterp, name, desc);
1737*35238bceSAndroid Build Coastguard Worker
1738*35238bceSAndroid Build Coastguard Worker if (!paramsValid(params))
1739*35238bceSAndroid Build Coastguard Worker continue;
1740*35238bceSAndroid Build Coastguard Worker
1741*35238bceSAndroid Build Coastguard Worker interfaceGroup->addChild(new SeparateShaderTest(ctx, name.str(), desc.str(), numIterations, params,
1742*35238bceSAndroid Build Coastguard Worker &SeparateShaderTest::testPipelineRendering));
1743*35238bceSAndroid Build Coastguard Worker }
1744*35238bceSAndroid Build Coastguard Worker
1745*35238bceSAndroid Build Coastguard Worker uint32_t baseSeed = ctx.getTestContext().getCommandLine().getBaseSeed();
1746*35238bceSAndroid Build Coastguard Worker Random rnd(deStringHash("separate_shader.random") + baseSeed);
1747*35238bceSAndroid Build Coastguard Worker set<string> seen;
1748*35238bceSAndroid Build Coastguard Worker TestCaseGroup *randomGroup = new TestCaseGroup(ctx, "random", "Random pipeline configuration tests");
1749*35238bceSAndroid Build Coastguard Worker group->addChild(randomGroup);
1750*35238bceSAndroid Build Coastguard Worker
1751*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 128; ++i)
1752*35238bceSAndroid Build Coastguard Worker {
1753*35238bceSAndroid Build Coastguard Worker TestParams params;
1754*35238bceSAndroid Build Coastguard Worker string code;
1755*35238bceSAndroid Build Coastguard Worker uint32_t genIterations = 4096;
1756*35238bceSAndroid Build Coastguard Worker
1757*35238bceSAndroid Build Coastguard Worker do
1758*35238bceSAndroid Build Coastguard Worker {
1759*35238bceSAndroid Build Coastguard Worker params = genParams(rnd.getUint32());
1760*35238bceSAndroid Build Coastguard Worker code = paramsCode(params);
1761*35238bceSAndroid Build Coastguard Worker } while (de::contains(seen, code) && --genIterations > 0);
1762*35238bceSAndroid Build Coastguard Worker
1763*35238bceSAndroid Build Coastguard Worker seen.insert(code);
1764*35238bceSAndroid Build Coastguard Worker
1765*35238bceSAndroid Build Coastguard Worker string name = de::toString(i); // Would be code but baseSeed can change
1766*35238bceSAndroid Build Coastguard Worker
1767*35238bceSAndroid Build Coastguard Worker randomGroup->addChild(
1768*35238bceSAndroid Build Coastguard Worker new SeparateShaderTest(ctx, name, name, numIterations, params, &SeparateShaderTest::testPipelineRendering));
1769*35238bceSAndroid Build Coastguard Worker }
1770*35238bceSAndroid Build Coastguard Worker
1771*35238bceSAndroid Build Coastguard Worker TestCaseGroup *apiGroup = new TestCaseGroup(ctx, "api", "Program pipeline API tests");
1772*35238bceSAndroid Build Coastguard Worker group->addChild(apiGroup);
1773*35238bceSAndroid Build Coastguard Worker
1774*35238bceSAndroid Build Coastguard Worker {
1775*35238bceSAndroid Build Coastguard Worker // More or less random parameters. These shouldn't have much effect, so just
1776*35238bceSAndroid Build Coastguard Worker // do a single sample.
1777*35238bceSAndroid Build Coastguard Worker TestParams params = defaultParams;
1778*35238bceSAndroid Build Coastguard Worker params.useUniform = true;
1779*35238bceSAndroid Build Coastguard Worker apiGroup->addChild(new SeparateShaderTest(ctx, "current_program_priority",
1780*35238bceSAndroid Build Coastguard Worker "Test priority between current program and pipeline binding", 1,
1781*35238bceSAndroid Build Coastguard Worker params, &SeparateShaderTest::testCurrentProgPriority));
1782*35238bceSAndroid Build Coastguard Worker apiGroup->addChild(new SeparateShaderTest(ctx, "active_program_uniform",
1783*35238bceSAndroid Build Coastguard Worker "Test that glUniform() affects a pipeline's active program", 1,
1784*35238bceSAndroid Build Coastguard Worker params, &SeparateShaderTest::testActiveProgramUniform));
1785*35238bceSAndroid Build Coastguard Worker
1786*35238bceSAndroid Build Coastguard Worker apiGroup->addChild(new SeparateShaderTest(ctx, "pipeline_programs",
1787*35238bceSAndroid Build Coastguard Worker "Test queries for programs in program pipeline stages", 1, params,
1788*35238bceSAndroid Build Coastguard Worker &SeparateShaderTest::testPipelineQueryPrograms));
1789*35238bceSAndroid Build Coastguard Worker
1790*35238bceSAndroid Build Coastguard Worker apiGroup->addChild(new SeparateShaderTest(ctx, "pipeline_active",
1791*35238bceSAndroid Build Coastguard Worker "Test query for active programs in a program pipeline", 1, params,
1792*35238bceSAndroid Build Coastguard Worker &SeparateShaderTest::testPipelineQueryActive));
1793*35238bceSAndroid Build Coastguard Worker }
1794*35238bceSAndroid Build Coastguard Worker
1795*35238bceSAndroid Build Coastguard Worker return group;
1796*35238bceSAndroid Build Coastguard Worker }
1797*35238bceSAndroid Build Coastguard Worker
createGLESSeparateShaderTests(Context & ctx)1798*35238bceSAndroid Build Coastguard Worker TestCaseGroup *createGLESSeparateShaderTests(Context &ctx)
1799*35238bceSAndroid Build Coastguard Worker {
1800*35238bceSAndroid Build Coastguard Worker TestCaseGroup *group = createCommonSeparateShaderTests(ctx);
1801*35238bceSAndroid Build Coastguard Worker
1802*35238bceSAndroid Build Coastguard Worker TestCaseGroup *interfaceMismatchGroup =
1803*35238bceSAndroid Build Coastguard Worker new TestCaseGroup(ctx, "validation", "Negative program pipeline interface matching");
1804*35238bceSAndroid Build Coastguard Worker group->addChild(interfaceMismatchGroup);
1805*35238bceSAndroid Build Coastguard Worker
1806*35238bceSAndroid Build Coastguard Worker {
1807*35238bceSAndroid Build Coastguard Worker TestCaseGroup *es31Group = new TestCaseGroup(ctx, "es31", "GLSL ES 3.1 pipeline interface matching");
1808*35238bceSAndroid Build Coastguard Worker gls::ShaderLibrary shaderLibrary(ctx.getTestContext(), ctx.getRenderContext(), ctx.getContextInfo());
1809*35238bceSAndroid Build Coastguard Worker const std::vector<tcu::TestNode *> children =
1810*35238bceSAndroid Build Coastguard Worker shaderLibrary.loadShaderFile("shaders/es31/separate_shader_validation.test");
1811*35238bceSAndroid Build Coastguard Worker
1812*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < (int)children.size(); i++)
1813*35238bceSAndroid Build Coastguard Worker es31Group->addChild(children[i]);
1814*35238bceSAndroid Build Coastguard Worker
1815*35238bceSAndroid Build Coastguard Worker interfaceMismatchGroup->addChild(es31Group);
1816*35238bceSAndroid Build Coastguard Worker }
1817*35238bceSAndroid Build Coastguard Worker
1818*35238bceSAndroid Build Coastguard Worker {
1819*35238bceSAndroid Build Coastguard Worker TestCaseGroup *es32Group = new TestCaseGroup(ctx, "es32", "GLSL ES 3.2 pipeline interface matching");
1820*35238bceSAndroid Build Coastguard Worker gls::ShaderLibrary shaderLibrary(ctx.getTestContext(), ctx.getRenderContext(), ctx.getContextInfo());
1821*35238bceSAndroid Build Coastguard Worker const std::vector<tcu::TestNode *> children =
1822*35238bceSAndroid Build Coastguard Worker shaderLibrary.loadShaderFile("shaders/es32/separate_shader_validation.test");
1823*35238bceSAndroid Build Coastguard Worker
1824*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < (int)children.size(); i++)
1825*35238bceSAndroid Build Coastguard Worker es32Group->addChild(children[i]);
1826*35238bceSAndroid Build Coastguard Worker
1827*35238bceSAndroid Build Coastguard Worker interfaceMismatchGroup->addChild(es32Group);
1828*35238bceSAndroid Build Coastguard Worker }
1829*35238bceSAndroid Build Coastguard Worker
1830*35238bceSAndroid Build Coastguard Worker return group;
1831*35238bceSAndroid Build Coastguard Worker }
1832*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1833*35238bceSAndroid Build Coastguard Worker } // namespace gles31
1834*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1835