Merge gerrit/vulkan-cts-1.0.1 into gerrit/vulkan-cts-1.0-dev
[platform/upstream/VK-GL-CTS.git] / modules / glshared / glsLongStressTestUtil.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL (ES) Module
3  * -----------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Utilities for tests with gls::LongStressCase.
22  *//*--------------------------------------------------------------------*/
23
24 #include "glsLongStressTestUtil.hpp"
25 #include "tcuStringTemplate.hpp"
26 #include "deStringUtil.hpp"
27
28 #include "glw.h"
29
30 using tcu::Vec2;
31 using tcu::Vec3;
32 using tcu::Vec4;
33 using tcu::Mat2;
34 using tcu::Mat3;
35 using tcu::Mat4;
36 using de::toString;
37 using std::map;
38 using std::string;
39
40 namespace deqp
41 {
42 namespace gls
43 {
44 namespace LongStressTestUtil
45 {
46
47 template <int Size>
48 static tcu::Matrix<float, Size, Size> translationMat (const float v)
49 {
50         tcu::Matrix<float, Size, Size>  res(1.0f);
51         tcu::Vector<float, Size>                col(v);
52         col[Size-1] = 1.0f;
53         res.setColumn(Size-1, col);
54         return res;
55 }
56
57 // Specializes certain template patterns in templ for GLSL version m_glslVersion; params in additionalParams (optional) are also included in the substitution.
58 string ProgramLibrary::substitute (const string& templ, const map<string, string>& additionalParams) const
59 {
60         const bool                              isGLSL3 = m_glslVersion == glu::GLSL_VERSION_300_ES;
61         map<string, string>             params;
62
63         params["FRAG_HEADER"]           = isGLSL3 ? "#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n" : "";
64         params["VTX_HEADER"]            = isGLSL3 ? "#version 300 es\n" : "";
65         params["VTX_IN"]                        = isGLSL3 ? "in"                                : "attribute";
66         params["VTX_OUT"]                       = isGLSL3 ? "out"                               : "varying";
67         params["FRAG_IN"]                       = isGLSL3 ? "in"                                : "varying";
68         params["FRAG_COLOR"]            = isGLSL3 ? "dEQP_FragColor"    : "gl_FragColor";
69         params["TEXTURE_2D_FUNC"]       = isGLSL3 ? "texture"                   : "texture2D";
70         params["NS"]                            = "${NS}"; // \note Keep these as-is, they're handled by StressCase.
71
72         params.insert(additionalParams.begin(), additionalParams.end());
73
74         return tcu::StringTemplate(templ.c_str()).specialize(params);
75 }
76
77 string ProgramLibrary::substitute (const std::string& templ) const
78 {
79         return substitute(templ, map<string, string>());
80 }
81
82 ProgramLibrary::ProgramLibrary (const glu::GLSLVersion glslVersion)
83         : m_glslVersion (glslVersion)
84 {
85         DE_ASSERT(glslVersion == glu::GLSL_VERSION_100_ES || glslVersion == glu::GLSL_VERSION_300_ES);
86 }
87
88 gls::ProgramContext ProgramLibrary::generateBufferContext (const int numDummyAttributes) const
89 {
90         static const char* const vertexTemplate =
91                 "${VTX_HEADER}"
92                 "${VTX_IN} highp vec3 a_position;\n"
93                 "${VTX_DUMMY_INPUTS}"
94                 "${VTX_OUT} mediump vec4 v_color;\n"
95                 "\n"
96                 "void main (void)\n"
97                 "{\n"
98                 "       gl_Position = vec4(a_position, 1.0);\n"
99                 "       v_color = ${VTX_COLOR_EXPRESSION};\n"
100                 "}\n";
101
102         static const char* const fragmentTemplate =
103                 "${FRAG_HEADER}"
104                 "${FRAG_IN} mediump vec4 v_color;\n"
105                 "\n"
106                 "void main (void)\n"
107                 "{\n"
108                 "       ${FRAG_COLOR} = v_color;\n"
109                 "}\n";
110
111         map<string, string> firstLevelParams;
112
113         {
114                 string vtxDummyInputs;
115                 string vtxColorExpr;
116                 for (int i = 0; i < numDummyAttributes; i++)
117                 {
118                         vtxDummyInputs  += "${VTX_IN} mediump vec4 a_in" + toString(i) + ";\n";
119                         vtxColorExpr    += string() + (i > 0 ? " + " : "") + "a_in" + toString(i);
120                 }
121
122                 firstLevelParams["VTX_DUMMY_INPUTS"]            = substitute(vtxDummyInputs);
123                 firstLevelParams["VTX_COLOR_EXPRESSION"]        = vtxColorExpr;
124         }
125
126         gls::ProgramContext context(substitute(vertexTemplate, firstLevelParams).c_str(), substitute(fragmentTemplate).c_str(), "a_position");
127
128         context.attributes.push_back(gls::VarSpec("a_position", Vec3(-0.1f), Vec3(0.1f)));
129
130         for (int i = 0; i < numDummyAttributes; i++)
131                 context.attributes.push_back(gls::VarSpec("a_in" + de::toString(i), Vec4(0.0f), Vec4(1.0f / (float)numDummyAttributes)));
132
133         return context;
134 }
135
136 gls::ProgramContext ProgramLibrary::generateTextureContext (const int numTextures, const int texWid, const int texHei, const float positionFactor) const
137 {
138         static const char* const vertexTemplate =
139                 "${VTX_HEADER}"
140                 "${VTX_IN} highp vec3 a_position;\n"
141                 "${VTX_IN} mediump vec2 a_texCoord;\n"
142                 "${VTX_OUT} mediump vec2 v_texCoord;\n"
143                 "uniform mediump mat4 u_posTrans;\n"
144                 "\n"
145                 "void main (void)\n"
146                 "{\n"
147                 "       gl_Position = u_posTrans * vec4(a_position, 1.0);\n"
148                 "       v_texCoord = a_texCoord;\n"
149                 "}\n";
150
151         static const char* const fragmentTemplate =
152                 "${FRAG_HEADER}"
153                 "${FRAG_IN} mediump vec2 v_texCoord;\n"
154                 "uniform mediump sampler2D u_sampler;\n"
155                 "\n"
156                 "void main (void)\n"
157                 "{\n"
158                 "       ${FRAG_COLOR} = ${TEXTURE_2D_FUNC}(u_sampler, v_texCoord);\n"
159                 "}\n";
160
161         gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(), "a_position");
162
163         context.attributes.push_back(gls::VarSpec("a_position",         Vec3(-positionFactor),                                          Vec3(positionFactor)));
164         context.attributes.push_back(gls::VarSpec("a_texCoord",         Vec2(0.0f),                                                                     Vec2(1.0f)));
165
166         context.uniforms.push_back(gls::VarSpec("u_sampler",            0));
167         context.uniforms.push_back(gls::VarSpec("u_posTrans",           translationMat<4>(positionFactor-1.0f),         translationMat<4>(1.0f-positionFactor)));
168
169         for (int i = 0; i < numTextures; i++)
170                 context.textureSpecs.push_back(gls::TextureSpec(glu::TextureTestUtil::TEXTURETYPE_2D, 0,
171                                                                                                                 texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, true,
172                                                                                                                 GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
173                                                                                                                 Vec4(0.0f), Vec4(1.0f)));
174
175         return context;
176 }
177
178 gls::ProgramContext ProgramLibrary::generateBufferAndTextureContext (const int numTextures, const int texWid, const int texHei) const
179 {
180         static const char* const vertexTemplate =
181                 "${VTX_HEADER}"
182                 "${VTX_IN} highp vec3 a_position;\n"
183                 "${VTX_TEX_COORD_INPUTS}"
184                 "${VTX_TEX_COORD_OUTPUTS}"
185                 "\n"
186                 "void main (void)\n"
187                 "{\n"
188                 "       gl_Position = vec4(a_position, 1.0);\n"
189                 "${VTX_TEX_COORD_WRITES}"
190                 "}\n";
191
192         static const char* const fragmentTemplate =
193                 "${FRAG_HEADER}"
194                 "${FRAG_TEX_COORD_INPUTS}"
195                 "${FRAG_SAMPLERS}"
196                 "\n"
197                 "void main (void)\n"
198                 "{\n"
199                 "       ${FRAG_COLOR} =${FRAG_COLOR_EXPRESSION};\n"
200                 "}\n";
201
202         map<string, string> firstLevelParams;
203
204         {
205                 string vtxTexCoordInputs;
206                 string vtxTexCoordOutputs;
207                 string vtxTexCoordWrites;
208                 string fragTexCoordInputs;
209                 string fragSamplers;
210                 string fragColorExpression;
211
212                 for (int i = 0; i < numTextures; i++)
213                 {
214                         vtxTexCoordInputs               += "${VTX_IN} mediump vec2 a_texCoord" + toString(i) + ";\n";
215                         vtxTexCoordOutputs              += "${VTX_OUT} mediump vec2 v_texCoord" + toString(i) + ";\n";
216                         vtxTexCoordWrites               += "\tv_texCoord" + toString(i) + " = " + "a_texCoord" + toString(i) + ";\n";
217                         fragTexCoordInputs              += "${FRAG_IN} mediump vec2 v_texCoord" + toString(i) + ";\n";
218                         fragSamplers                    += "uniform mediump sampler2D u_sampler" + toString(i) + ";\n";
219                         fragColorExpression             += string() + (i > 0 ? " +" : "") + "\n\t\t${TEXTURE_2D_FUNC}(u_sampler" + toString(i) + ", v_texCoord" + toString(i) + ")";
220                 }
221
222                 firstLevelParams["VTX_TEX_COORD_INPUTS"]        = substitute(vtxTexCoordInputs);
223                 firstLevelParams["VTX_TEX_COORD_OUTPUTS"]       = substitute(vtxTexCoordOutputs);
224                 firstLevelParams["VTX_TEX_COORD_WRITES"]        = vtxTexCoordWrites;
225                 firstLevelParams["FRAG_TEX_COORD_INPUTS"]       = substitute(fragTexCoordInputs);
226                 firstLevelParams["FRAG_SAMPLERS"]                       = fragSamplers;
227                 firstLevelParams["FRAG_COLOR_EXPRESSION"]       = substitute(fragColorExpression);
228         }
229
230         gls::ProgramContext context(substitute(vertexTemplate, firstLevelParams).c_str(), substitute(fragmentTemplate, firstLevelParams).c_str(), "a_position");
231
232         context.attributes.push_back(gls::VarSpec("a_position", Vec3(-0.1f), Vec3(0.1f)));
233
234         for (int i = 0; i < numTextures; i++)
235         {
236                 context.attributes.push_back(gls::VarSpec("a_texCoord" + de::toString(i), Vec2(0.0f), Vec2(1.0f)));
237                 context.uniforms.push_back(gls::VarSpec("u_sampler" + de::toString(i), i));
238                 context.textureSpecs.push_back(gls::TextureSpec(glu::TextureTestUtil::TEXTURETYPE_2D, i,
239                                                                                                                 texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, true,
240                                                                                                                 GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
241                                                                                                                 Vec4(0.0f), Vec4(1.0f / (float)numTextures)));
242         }
243
244         return context;
245 }
246
247 gls::ProgramContext ProgramLibrary::generateFragmentPointLightContext (const int texWid, const int texHei) const
248 {
249         static const char* const vertexTemplate =
250                 "${VTX_HEADER}"
251                 "struct Material\n"
252                 "{\n"
253                 "       mediump vec3    ambientColor;\n"
254                 "       mediump vec4    diffuseColor;\n"
255                 "       mediump vec3    emissiveColor;\n"
256                 "       mediump vec3    specularColor;\n"
257                 "       mediump float   shininess;\n"
258                 "};\n"
259                 "\n"
260                 "struct Light\n"
261                 "{\n"
262                 "       mediump vec3    color;\n"
263                 "       mediump vec4    position;\n"
264                 "       mediump vec3    direction;\n"
265                 "       mediump float   constantAttenuation;\n"
266                 "       mediump float   linearAttenuation;\n"
267                 "       mediump float   quadraticAttenuation;\n"
268                 "};\n"
269                 "\n"
270                 "${VTX_IN} highp vec4   a_position${NS};\n"
271                 "${VTX_IN} mediump vec3 a_normal${NS};\n"
272                 "${VTX_IN} mediump vec3 a_color${NS};\n"
273                 "${VTX_IN} mediump vec4 a_texCoord0${NS};\n"
274                 "\n"
275                 "uniform Material               u_material${NS};\n"
276                 "uniform Light                  u_light${NS}[1];\n"
277                 "uniform highp mat4             u_mvpMatrix${NS};\n"
278                 "uniform mediump mat4   u_modelViewMatrix${NS};\n"
279                 "uniform mediump mat3   u_normalMatrix${NS};\n"
280                 "uniform mediump mat4   u_texCoordMatrix0${NS};\n"
281                 "\n"
282                 "${VTX_OUT} mediump vec4        v_baseColor${NS};\n"
283                 "${VTX_OUT} mediump vec2        v_texCoord0${NS};\n"
284                 "\n"
285                 "${VTX_OUT} mediump vec3        v_eyeNormal${NS};\n"
286                 "${VTX_OUT} mediump vec3        v_directionToLight${NS}[1];\n"
287                 "${VTX_OUT} mediump float       v_distanceToLight${NS}[1];\n"
288                 "\n"
289                 "vec3 direction (vec4 from, vec4 to)\n"
290                 "{\n"
291                 "       return vec3(to.xyz * from.w - from.xyz * to.w);\n"
292                 "}\n"
293                 "\n"
294                 "void main (void)\n"
295                 "{\n"
296                 "       gl_Position = u_mvpMatrix${NS} * a_position${NS};\n"
297                 "       v_texCoord0${NS} = (u_texCoordMatrix0${NS} * a_texCoord0${NS}).xy;\n"
298                 "\n"
299                 "       mediump vec4 eyePosition        = u_modelViewMatrix${NS} * a_position${NS};\n"
300                 "       mediump vec3 eyeNormal          = normalize(u_normalMatrix${NS} * a_normal${NS});\n"
301                 "\n"
302                 "       vec4 color       = vec4(0.0, 0.0, 0.0, 1.0);\n"
303                 "       color.rgb       += u_material${NS}.emissiveColor;\n"
304                 "\n"
305                 "       color.a         *= u_material${NS}.diffuseColor.a;\n"
306                 "\n"
307                 "       v_baseColor${NS} = color;\n"
308                 "\n"
309                 "       v_distanceToLight${NS}[0]       = distance(eyePosition, u_light${NS}[0].position);\n"
310                 "       v_directionToLight${NS}[0]      = normalize(direction(eyePosition, u_light${NS}[0].position));\n"
311                 "\n"
312                 "       v_eyeNormal${NS}                        = eyeNormal;\n"
313                 "}\n";
314
315         static const char* const fragmentTemplate =
316                 "${FRAG_HEADER}"
317                 "struct Light\n"
318                 "{\n"
319                 "       mediump vec3    color;\n"
320                 "       mediump vec4    position;\n"
321                 "       mediump vec3    direction;\n"
322                 "       mediump float   constantAttenuation;\n"
323                 "       mediump float   linearAttenuation;\n"
324                 "       mediump float   quadraticAttenuation;\n"
325                 "};\n"
326                 "\n"
327                 "struct Material\n"
328                 "{\n"
329                 "       mediump vec3    ambientColor;\n"
330                 "       mediump vec4    diffuseColor;\n"
331                 "       mediump vec3    emissiveColor;\n"
332                 "       mediump vec3    specularColor;\n"
333                 "       mediump float   shininess;\n"
334                 "};\n"
335                 "\n"
336                 "uniform sampler2D              u_sampler0${NS};\n"
337                 "uniform Light                  u_light${NS}[1];\n"
338                 "uniform Material               u_material${NS};\n"
339                 "\n"
340                 "${FRAG_IN} mediump vec4        v_baseColor${NS};\n"
341                 "${FRAG_IN} mediump vec2        v_texCoord0${NS};\n"
342                 "\n"
343                 "${FRAG_IN} mediump vec3        v_eyeNormal${NS};\n"
344                 "${FRAG_IN} mediump vec3        v_directionToLight${NS}[1];\n"
345                 "${FRAG_IN} mediump float       v_distanceToLight${NS}[1];\n"
346                 "\n"
347                 "mediump vec3 computeLighting (Light light, mediump vec3 directionToLight, mediump vec3 vertexEyeNormal)\n"
348                 "{\n"
349                 "       mediump float   normalDotDirection      = max(dot(vertexEyeNormal, directionToLight), 0.0);\n"
350                 "       mediump vec3    color                           = normalDotDirection * u_material${NS}.diffuseColor.rgb * light.color;\n"
351                 "\n"
352                 "       if (normalDotDirection != 0.0)\n"
353                 "       {\n"
354                 "               mediump vec3 h = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
355                 "               color.rgb += pow(max(dot(vertexEyeNormal, h), 0.0), u_material${NS}.shininess) * u_material${NS}.specularColor * light.color;\n"
356                 "       }\n"
357                 "\n"
358                 "       return color;\n"
359                 "}\n"
360                 "\n"
361                 "mediump float computePointLightAttenuation (Light light, mediump float distanceToLight)\n"
362                 "{\n"
363                 "       mediump float   constantAttenuation             = light.constantAttenuation;\n"
364                 "       mediump float   linearAttenuation               = light.linearAttenuation * distanceToLight;\n"
365                 "       mediump float   quadraticAttenuation    = light.quadraticAttenuation * distanceToLight * distanceToLight;\n"
366                 "\n"
367                 "       return 1.0 / (constantAttenuation + linearAttenuation + quadraticAttenuation);\n"
368                 "}\n"
369                 "\n"
370                 "void main (void)\n"
371                 "{\n"
372                 "       mediump vec3 eyeNormal  = normalize(v_eyeNormal${NS});\n"
373                 "       mediump vec4 color              = v_baseColor${NS};\n"
374                 "\n"
375                 "       color.rgb += computePointLightAttenuation(u_light${NS}[0], v_distanceToLight${NS}[0]) * computeLighting(u_light${NS}[0], normalize(v_directionToLight${NS}[0]), eyeNormal);\n"
376                 "\n"
377                 "       color *= ${TEXTURE_2D_FUNC}(u_sampler0${NS}, v_texCoord0${NS});\n"
378                 "\n"
379                 "       ${FRAG_COLOR} = color;\n"
380                 "}\n";
381
382         gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(), "a_position${NS}");
383
384         context.attributes.push_back(gls::VarSpec("a_position${NS}",                                            Vec4(-1.0f),                            Vec4(1.0f)));
385         context.attributes.push_back(gls::VarSpec("a_normal${NS}",                                                      Vec3(-1.0f),                            Vec3(1.0f)));
386         context.attributes.push_back(gls::VarSpec("a_texCoord0${NS}",                                           Vec4(-1.0f),                            Vec4(1.0f)));
387
388         context.uniforms.push_back(gls::VarSpec("u_material${NS}.ambientColor",                         Vec3(0.0f),                                     Vec3(1.0f)));
389         context.uniforms.push_back(gls::VarSpec("u_material${NS}.diffuseColor",                         Vec4(0.0f),                                     Vec4(1.0f)));
390         context.uniforms.push_back(gls::VarSpec("u_material${NS}.emissiveColor",                        Vec3(0.0f),                                     Vec3(1.0f)));
391         context.uniforms.push_back(gls::VarSpec("u_material${NS}.specularColor",                        Vec3(0.0f),                                     Vec3(1.0f)));
392         context.uniforms.push_back(gls::VarSpec("u_material${NS}.shininess",                            0.0f,                                           1.0f));
393
394         context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].color",                                        Vec3(0.0f),                                     Vec3(1.0f)));
395         context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].position",                                     Vec4(-1.0f),                            Vec4(1.0f)));
396         context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].direction",                            Vec3(-1.0f),                            Vec3(1.0f)));
397         context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].constantAttenuation",          0.1f,                                           1.0f));
398         context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].linearAttenuation",            0.1f,                                           1.0f));
399         context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].quadraticAttenuation",         0.1f,                                           1.0f));
400
401         context.uniforms.push_back(gls::VarSpec("u_mvpMatrix${NS}",                                                     translationMat<4>(-0.2f),       translationMat<4>(0.2f)));
402         context.uniforms.push_back(gls::VarSpec("u_modelViewMatrix${NS}",                                       translationMat<4>(-0.2f),       translationMat<4>(0.2f)));
403         context.uniforms.push_back(gls::VarSpec("u_normalMatrix${NS}",                                          translationMat<3>(-0.2f),       translationMat<3>(0.2f)));
404         context.uniforms.push_back(gls::VarSpec("u_texCoordMatrix0${NS}",                                       translationMat<4>(-0.2f),       translationMat<4>(0.2f)));
405
406         context.uniforms.push_back(gls::VarSpec("u_sampler0${NS}", 0));
407
408         context.textureSpecs.push_back(gls::TextureSpec(glu::TextureTestUtil::TEXTURETYPE_2D, 0,
409                                                                                                         texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA,
410                                                                                                         true, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
411                                                                                                         Vec4(0.0f), Vec4(1.0f)));
412
413         return context;
414 }
415
416 gls::ProgramContext ProgramLibrary::generateVertexUniformLoopLightContext (const int texWid, const int texHei) const
417 {
418         static const char* const vertexTemplate =
419                 "${VTX_HEADER}"
420                 "struct Material {\n"
421                 "       mediump vec3 ambientColor;\n"
422                 "       mediump vec4 diffuseColor;\n"
423                 "       mediump vec3 emissiveColor;\n"
424                 "       mediump vec3 specularColor;\n"
425                 "       mediump float shininess;\n"
426                 "};\n"
427                 "struct Light {\n"
428                 "       mediump vec3 color;\n"
429                 "       mediump vec4 position;\n"
430                 "       mediump vec3 direction;\n"
431                 "       mediump float constantAttenuation;\n"
432                 "       mediump float linearAttenuation;\n"
433                 "       mediump float quadraticAttenuation;\n"
434                 "       mediump float spotExponent;\n"
435                 "       mediump float spotCutoff;\n"
436                 "};\n"
437                 "${VTX_IN} highp vec4 a_position${NS};\n"
438                 "${VTX_IN} mediump vec3 a_normal${NS};\n"
439                 "${VTX_IN} mediump vec4 a_texCoord0${NS};\n"
440                 "uniform Material u_material${NS};\n"
441                 "uniform Light u_directionalLight${NS}[1];\n"
442                 "uniform mediump int u_directionalLightCount${NS};\n"
443                 "uniform Light u_spotLight${NS}[4];\n"
444                 "uniform mediump int u_spotLightCount${NS};\n"
445                 "uniform highp mat4 u_mvpMatrix${NS};\n"
446                 "uniform highp mat4 u_modelViewMatrix${NS};\n"
447                 "uniform mediump mat3 u_normalMatrix${NS};\n"
448                 "uniform mediump mat4 u_texCoordMatrix0${NS};\n"
449                 "${VTX_OUT} mediump vec4 v_color${NS};\n"
450                 "${VTX_OUT} mediump vec2 v_texCoord0${NS};\n"
451                 "mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
452                 "{\n"
453                 "       return vec3(to.xyz * from.w - from.xyz * to.w);\n"
454                 "}\n"
455                 "\n"
456                 "mediump vec3 computeLighting (\n"
457                 "       mediump vec3 directionToLight,\n"
458                 "       mediump vec3 halfVector,\n"
459                 "       mediump vec3 normal,\n"
460                 "       mediump vec3 lightColor,\n"
461                 "       mediump vec3 diffuseColor,\n"
462                 "       mediump vec3 specularColor,\n"
463                 "       mediump float shininess)\n"
464                 "{\n"
465                 "       mediump float normalDotDirection  = max(dot(normal, directionToLight), 0.0);\n"
466                 "       mediump vec3  color               = normalDotDirection * diffuseColor * lightColor;\n"
467                 "\n"
468                 "       if (normalDotDirection != 0.0)\n"
469                 "               color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
470                 "\n"
471                 "       return color;\n"
472                 "}\n"
473                 "\n"
474                 "mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump float linearAtt, mediump float quadraticAtt)\n"
475                 "{\n"
476                 "       return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
477                 "}\n"
478                 "\n"
479                 "mediump float computeSpotAttenuation (\n"
480                 "       mediump vec3  directionToLight,\n"
481                 "       mediump vec3  lightDir,\n"
482                 "       mediump float spotExponent,\n"
483                 "       mediump float spotCutoff)\n"
484                 "{\n"
485                 "       mediump float spotEffect = dot(lightDir, normalize(-directionToLight));\n"
486                 "\n"
487                 "       if (spotEffect < spotCutoff)\n"
488                 "               spotEffect = 0.0;\n"
489                 "\n"
490                 "       spotEffect = pow(spotEffect, spotExponent);\n"
491                 "       return spotEffect;\n"
492                 "}\n"
493                 "\n"
494                 "void main (void)\n"
495                 "{\n"
496                 "       highp vec4 position = a_position${NS};\n"
497                 "       highp vec3 normal = a_normal${NS};\n"
498                 "       gl_Position = u_mvpMatrix${NS} * position;\n"
499                 "       v_texCoord0${NS} = (u_texCoordMatrix0${NS} * a_texCoord0${NS}).xy;\n"
500                 "       mediump vec4 color = vec4(u_material${NS}.emissiveColor, u_material${NS}.diffuseColor.a);\n"
501                 "\n"
502                 "       highp vec4 eyePosition = u_modelViewMatrix${NS} * position;\n"
503                 "       mediump vec3 eyeNormal = normalize(u_normalMatrix${NS} * normal);\n"
504                 "       for (int i = 0; i < u_directionalLightCount${NS}; i++)\n"
505                 "       {\n"
506                 "               mediump vec3 directionToLight = -u_directionalLight${NS}[i].direction;\n"
507                 "               mediump vec3 halfVector = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
508                 "               color.rgb += computeLighting(directionToLight, halfVector, eyeNormal, u_directionalLight${NS}[i].color, u_material${NS}.diffuseColor.rgb, u_material${NS}.specularColor, u_material${NS}.shininess);\n"
509                 "       }\n"
510                 "\n"
511                 "       for (int i = 0; i < u_spotLightCount${NS}; i++)\n"
512                 "       {\n"
513                 "               mediump float distanceToLight = distance(eyePosition, u_spotLight${NS}[i].position);\n"
514                 "               mediump vec3 directionToLight = normalize(direction(eyePosition, u_spotLight${NS}[i].position));\n"
515                 "               mediump vec3 halfVector = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
516                 "               color.rgb += computeLighting(directionToLight, halfVector, eyeNormal, u_spotLight${NS}[i].color, u_material${NS}.diffuseColor.rgb, u_material${NS}.specularColor, u_material${NS}.shininess) * computeDistanceAttenuation(distanceToLight, u_spotLight${NS}[i].constantAttenuation, u_spotLight${NS}[i].linearAttenuation, u_spotLight${NS}[i].quadraticAttenuation) * computeSpotAttenuation(directionToLight, u_spotLight${NS}[i].direction, u_spotLight${NS}[i].spotExponent, u_spotLight${NS}[i].spotCutoff);\n"
517                 "       }\n"
518                 "\n"
519                 "\n"
520                 "       v_color${NS} = color;\n"
521                 "}\n";
522
523         static const char* const fragmentTemplate =
524                 "${FRAG_HEADER}"
525                 "uniform sampler2D u_sampler0${NS};\n"
526                 "${FRAG_IN} mediump vec4 v_color${NS};\n"
527                 "${FRAG_IN} mediump vec2 v_texCoord0${NS};\n"
528                 "void main (void)\n"
529                 "{\n"
530                 "       mediump vec2 texCoord0 = v_texCoord0${NS};\n"
531                 "       mediump vec4 color = v_color${NS};\n"
532                 "       color *= ${TEXTURE_2D_FUNC}(u_sampler0${NS}, texCoord0);\n"
533                 "       ${FRAG_COLOR} = color;\n"
534                 "}\n";
535
536         gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(), "a_position${NS}");
537
538         context.attributes.push_back    (gls::VarSpec("a_position${NS}",                                                                        Vec4(-1.0f),                            Vec4(1.0f)));
539         context.attributes.push_back    (gls::VarSpec("a_normal${NS}",                                                                          Vec3(-1.0f),                            Vec3(1.0f)));
540         context.attributes.push_back    (gls::VarSpec("a_texCoord0${NS}",                                                                       Vec4(-1.0f),                            Vec4(1.0f)));
541
542         context.uniforms.push_back              (gls::VarSpec("u_material${NS}.ambientColor",                                           Vec3(0.0f),                                     Vec3(1.0f)));
543         context.uniforms.push_back              (gls::VarSpec("u_material${NS}.diffuseColor",                                           Vec4(0.0f),                                     Vec4(1.0f)));
544         context.uniforms.push_back              (gls::VarSpec("u_material${NS}.emissiveColor",                                          Vec3(0.0f),                                     Vec3(1.0f)));
545         context.uniforms.push_back              (gls::VarSpec("u_material${NS}.specularColor",                                          Vec3(0.0f),                                     Vec3(1.0f)));
546         context.uniforms.push_back              (gls::VarSpec("u_material${NS}.shininess",                                                      0.0f,                                           1.0f));
547
548         context.uniforms.push_back              (gls::VarSpec("u_directionalLight${NS}[0].color",                                       Vec3(0.0f),                                     Vec3(1.0f)));
549         context.uniforms.push_back              (gls::VarSpec("u_directionalLight${NS}[0].position",                            Vec4(-1.0f),                            Vec4(1.0f)));
550         context.uniforms.push_back              (gls::VarSpec("u_directionalLight${NS}[0].direction",                           Vec3(-1.0f),                            Vec3(1.0f)));
551         context.uniforms.push_back              (gls::VarSpec("u_directionalLight${NS}[0].constantAttenuation",         0.1f,                                           1.0f));
552         context.uniforms.push_back              (gls::VarSpec("u_directionalLight${NS}[0].linearAttenuation",           0.1f,                                           1.0f));
553         context.uniforms.push_back              (gls::VarSpec("u_directionalLight${NS}[0].quadraticAttenuation",        0.1f,                                           1.0f));
554         context.uniforms.push_back              (gls::VarSpec("u_directionalLight${NS}[0].spotExponent",                        0.1f,                                           1.0f));
555         context.uniforms.push_back              (gls::VarSpec("u_directionalLight${NS}[0].spotCutoff",                          0.1f,                                           1.0f));
556
557         context.uniforms.push_back              (gls::VarSpec("u_directionalLightCount${NS}",                                           1));
558
559         for (int i = 0; i < 4; i++)
560         {
561                 const std::string ndxStr = de::toString(i);
562
563                 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].color",                                   Vec3(0.0f),                                     Vec3(1.0f)));
564                 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].position",                                Vec4(-1.0f),                            Vec4(1.0f)));
565                 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].direction",                               Vec3(-1.0f),                            Vec3(1.0f)));
566                 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].constantAttenuation",             0.1f,                                           1.0f));
567                 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].linearAttenuation",               0.1f,                                           1.0f));
568                 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].quadraticAttenuation",    0.1f,                                           1.0f));
569                 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].spotExponent",                    0.1f,                                           1.0f));
570                 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].spotCutoff",                              0.1f,                                           1.0f));
571         }
572
573         context.uniforms.push_back              (gls::VarSpec("u_spotLightCount${NS}",                                                          4));
574
575         context.uniforms.push_back              (gls::VarSpec("u_mvpMatrix${NS}",                                                                       translationMat<4>(-0.2f),       translationMat<4>(0.2f)));
576         context.uniforms.push_back              (gls::VarSpec("u_modelViewMatrix${NS}",                                                         translationMat<4>(-0.2f),       translationMat<4>(0.2f)));
577         context.uniforms.push_back              (gls::VarSpec("u_normalMatrix${NS}",                                                            translationMat<3>(-0.2f),       translationMat<3>(0.2f)));
578         context.uniforms.push_back              (gls::VarSpec("u_texCoordMatrix0${NS}",                                                         translationMat<4>(-0.2f),       translationMat<4>(0.2f)));
579
580         context.uniforms.push_back              (gls::VarSpec("u_sampler0${NS}",                                                                        0));
581
582         context.textureSpecs.push_back  (gls::TextureSpec(glu::TextureTestUtil::TEXTURETYPE_2D, 0,
583                                                                                                           texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA,
584                                                                                                           true, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
585                                                                                                           Vec4(0.0f), Vec4(1.0f)));
586
587         return context;
588 }
589
590 } // StressTestUtil
591 } // gls
592 } // deqp