Always apply flat qualifier to double inputs, same as int/uint
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcFragDepthTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2016 Google Inc.
6  * Copyright (c) 2016 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */ /*!
21  * \file
22  * \brief gl_FragDepth tests.
23  */ /*-------------------------------------------------------------------*/
24
25 #include "glcFragDepthTests.hpp"
26 #include "deMath.h"
27 #include "deRandom.hpp"
28 #include "deString.h"
29 #include "gluDrawUtil.hpp"
30 #include "gluPixelTransfer.hpp"
31 #include "gluShaderProgram.hpp"
32 #include "glwEnums.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuImageCompare.hpp"
35 #include "tcuRenderTarget.hpp"
36 #include "tcuStringTemplate.hpp"
37 #include "tcuSurface.hpp"
38 #include "tcuTestLog.hpp"
39 #include "tcuVector.hpp"
40
41 // For setupDefaultUniforms()
42 #include "glcShaderRenderCase.hpp"
43
44 namespace deqp
45 {
46
47 using tcu::Vec2;
48 using tcu::Vec3;
49 using tcu::Vec4;
50 using tcu::TestLog;
51 using std::string;
52 using std::vector;
53
54 typedef float (*EvalFragDepthFunc)(const Vec2& coord);
55
56 static const char* s_vertexShaderSrc = "${VERSION_DECL}\n"
57                                                                            "in highp vec4 a_position;\n"
58                                                                            "in highp vec2 a_coord;\n"
59                                                                            "out highp vec2 v_coord;\n"
60                                                                            "void main (void)\n"
61                                                                            "{\n"
62                                                                            "   gl_Position = a_position;\n"
63                                                                            "   v_coord = a_coord;\n"
64                                                                            "}\n";
65 static const char* s_defaultFragmentShaderSrc = "${VERSION_DECL}\n"
66                                                                                                 "uniform highp vec4 u_color;\n"
67                                                                                                 "layout(location = 0) out mediump vec4 o_color;\n"
68                                                                                                 "void main (void)\n"
69                                                                                                 "{\n"
70                                                                                                 "   o_color = u_color;\n"
71                                                                                                 "}\n";
72
73 template <typename T>
74 static inline bool compare(deUint32 func, T a, T b)
75 {
76         switch (func)
77         {
78         case GL_NEVER:
79                 return false;
80         case GL_ALWAYS:
81                 return true;
82         case GL_LESS:
83                 return a < b;
84         case GL_LEQUAL:
85                 return a <= b;
86         case GL_EQUAL:
87                 return a == b;
88         case GL_NOTEQUAL:
89                 return a != b;
90         case GL_GEQUAL:
91                 return a >= b;
92         case GL_GREATER:
93                 return a > b;
94         default:
95                 DE_ASSERT(DE_FALSE);
96                 return false;
97         }
98 }
99
100 static std::string specializeVersion(const std::string& source, glu::GLSLVersion version)
101 {
102         DE_ASSERT(version == glu::GLSL_VERSION_300_ES || version == glu::GLSL_VERSION_310_ES ||
103                           version >= glu::GLSL_VERSION_330);
104         std::map<std::string, std::string> args;
105         args["VERSION_DECL"] = glu::getGLSLVersionDeclaration(version);
106         return tcu::StringTemplate(source.c_str()).specialize(args);
107 }
108
109 class FragDepthCompareCase : public TestCase
110 {
111 public:
112         FragDepthCompareCase(Context& context, const char* name, const char* desc, glu::GLSLVersion glslVersion,
113                                                  const char* fragSrc, EvalFragDepthFunc evalFunc, deUint32 compareFunc);
114         ~FragDepthCompareCase(void);
115
116         IterateResult iterate(void);
117
118 private:
119         glu::GLSLVersion  m_glslVersion;
120         string                    m_fragSrc;
121         EvalFragDepthFunc m_evalFunc;
122         deUint32                  m_compareFunc;
123 };
124
125 FragDepthCompareCase::FragDepthCompareCase(Context& context, const char* name, const char* desc,
126                                                                                    glu::GLSLVersion glslVersion, const char* fragSrc,
127                                                                                    EvalFragDepthFunc evalFunc, deUint32 compareFunc)
128         : TestCase(context, name, desc)
129         , m_glslVersion(glslVersion)
130         , m_fragSrc(fragSrc)
131         , m_evalFunc(evalFunc)
132         , m_compareFunc(compareFunc)
133 {
134 }
135
136 FragDepthCompareCase::~FragDepthCompareCase(void)
137 {
138 }
139
140 FragDepthCompareCase::IterateResult FragDepthCompareCase::iterate(void)
141 {
142         TestLog&                                 log = m_testCtx.getLog();
143         const glw::Functions&   gl  = m_context.getRenderContext().getFunctions();
144         de::Random                               rnd(deStringHash(getName()));
145         const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
146         int                                              viewportW      = de::min(128, renderTarget.getWidth());
147         int                                              viewportH      = de::min(128, renderTarget.getHeight());
148         int                                              viewportX      = rnd.getInt(0, renderTarget.getWidth() - viewportW);
149         int                                              viewportY      = rnd.getInt(0, renderTarget.getHeight() - viewportH);
150         tcu::Surface                     renderedFrame(viewportW, viewportH);
151         tcu::Surface                     referenceFrame(viewportW, viewportH);
152         const float                              constDepth = 0.1f;
153
154         if (renderTarget.getDepthBits() == 0)
155                 throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);
156
157         gl.viewport(viewportX, viewportY, viewportW, viewportH);
158         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
159         gl.enable(GL_DEPTH_TEST);
160
161         static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
162
163         // Fill viewport with 2 quads - one with constant depth and another with d = [-1..1]
164         {
165                 glu::ShaderProgram basicQuadProgram(
166                         m_context.getRenderContext(),
167                         glu::makeVtxFragSources(specializeVersion(s_vertexShaderSrc, m_glslVersion).c_str(),
168                                                                         specializeVersion(s_defaultFragmentShaderSrc, m_glslVersion).c_str()));
169
170                 if (!basicQuadProgram.isOk())
171                 {
172                         log << basicQuadProgram;
173                         TCU_FAIL("Compile failed");
174                 }
175
176                 const float constDepthCoord[] = { -1.0f, -1.0f, constDepth, 1.0f, -1.0f, +1.0f, constDepth, 1.0f,
177                                                                                   0.0f,  -1.0f, constDepth, 1.0f, 0.0f,  +1.0f, constDepth, 1.0f };
178                 const float varyingDepthCoord[] = { 0.0f,  -1.0f, +1.0f, 1.0f, 0.0f,  +1.0f, 0.0f,  1.0f,
179                                                                                         +1.0f, -1.0f, 0.0f,  1.0f, +1.0f, +1.0f, -1.0f, 1.0f };
180
181                 gl.useProgram(basicQuadProgram.getProgram());
182                 gl.uniform4f(gl.getUniformLocation(basicQuadProgram.getProgram(), "u_color"), 0.0f, 0.0f, 1.0f, 1.0f);
183                 gl.depthFunc(GL_ALWAYS);
184
185                 {
186                         glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &constDepthCoord[0]);
187                         glu::draw(m_context.getRenderContext(), basicQuadProgram.getProgram(), 1, &posBinding,
188                                           glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
189                 }
190
191                 {
192                         glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &varyingDepthCoord[0]);
193                         glu::draw(m_context.getRenderContext(), basicQuadProgram.getProgram(), 1, &posBinding,
194                                           glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
195                 }
196
197                 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw base quads");
198         }
199
200         // Render with depth test.
201         {
202                 glu::ShaderProgram program(m_context.getRenderContext(),
203                                                                    glu::makeVtxFragSources(specializeVersion(s_vertexShaderSrc, m_glslVersion).c_str(),
204                                                                                                                    specializeVersion(m_fragSrc, m_glslVersion).c_str()));
205                 log << program;
206
207                 if (!program.isOk())
208                         TCU_FAIL("Compile failed");
209
210                 const float coord[]     = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
211                 const float position[] = { -1.0f, -1.0f, +1.0f, 1.0f, -1.0f, +1.0f, 0.0f,  1.0f,
212                                                                    +1.0f, -1.0f, 0.0f,  1.0f, +1.0f, +1.0f, -1.0f, 1.0f };
213
214                 gl.useProgram(program.getProgram());
215                 gl.depthFunc(m_compareFunc);
216                 gl.uniform4f(gl.getUniformLocation(program.getProgram(), "u_color"), 0.0f, 1.0f, 0.0f, 1.0f);
217
218                 // Setup default helper uniforms.
219                 setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());
220
221                 {
222                         glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("a_position", 4, 4, 0, &position[0]),
223                                                                                                            glu::va::Float("a_coord", 2, 4, 0, &coord[0]) };
224                         glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
225                                           &vertexArrays[0], glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
226                 }
227
228                 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw test quad");
229         }
230
231         glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());
232
233         // Render reference.
234         for (int y = 0; y < referenceFrame.getHeight(); y++)
235         {
236                 float yf   = ((float)y + 0.5f) / (float)referenceFrame.getHeight();
237                 int   half = de::clamp((int)((float)referenceFrame.getWidth() * 0.5f + 0.5f), 0, referenceFrame.getWidth());
238
239                 // Fill left half - comparison to constant 0.5
240                 for (int x = 0; x < half; x++)
241                 {
242                         float xf        = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
243                         float d         = m_evalFunc(Vec2(xf, yf));
244                         bool  dpass = compare(m_compareFunc, d, constDepth * 0.5f + 0.5f);
245
246                         referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green() : tcu::RGBA::blue());
247                 }
248
249                 // Fill right half - comparison to interpolated depth
250                 for (int x = half; x < referenceFrame.getWidth(); x++)
251                 {
252                         float xf        = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
253                         float xh        = ((float)x - (float)half + 0.5f) / (float)(referenceFrame.getWidth() - half);
254                         float rd        = 1.0f - (xh + yf) * 0.5f;
255                         float d         = m_evalFunc(Vec2(xf, yf));
256                         bool  dpass = compare(m_compareFunc, d, rd);
257
258                         referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green() : tcu::RGBA::blue());
259                 }
260         }
261
262         bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f,
263                                                                   tcu::COMPARE_LOG_RESULT);
264         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
265         return STOP;
266 }
267
268 class FragDepthWriteCase : public TestCase
269 {
270 public:
271         FragDepthWriteCase(Context& context, const char* name, const char* desc, glu::GLSLVersion glslVersion,
272                                            const char* fragSrc, EvalFragDepthFunc evalFunc);
273         ~FragDepthWriteCase(void);
274
275         IterateResult iterate(void);
276
277 private:
278         glu::GLSLVersion  m_glslVersion;
279         string                    m_fragSrc;
280         EvalFragDepthFunc m_evalFunc;
281 };
282
283 FragDepthWriteCase::FragDepthWriteCase(Context& context, const char* name, const char* desc,
284                                                                            glu::GLSLVersion glslVersion, const char* fragSrc, EvalFragDepthFunc evalFunc)
285         : TestCase(context, name, desc), m_glslVersion(glslVersion), m_fragSrc(fragSrc), m_evalFunc(evalFunc)
286 {
287 }
288
289 FragDepthWriteCase::~FragDepthWriteCase(void)
290 {
291 }
292
293 FragDepthWriteCase::IterateResult FragDepthWriteCase::iterate(void)
294 {
295         TestLog&                                 log = m_testCtx.getLog();
296         const glw::Functions&   gl  = m_context.getRenderContext().getFunctions();
297         de::Random                               rnd(deStringHash(getName()));
298         const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
299         int                                              viewportW      = de::min(128, renderTarget.getWidth());
300         int                                              viewportH      = de::min(128, renderTarget.getHeight());
301         int                                              viewportX      = rnd.getInt(0, renderTarget.getWidth() - viewportW);
302         int                                              viewportY      = rnd.getInt(0, renderTarget.getHeight() - viewportH);
303         tcu::Surface                     renderedFrame(viewportW, viewportH);
304         tcu::Surface                     referenceFrame(viewportW, viewportH);
305         const int                                numDepthSteps = 16;
306         const float                              depthStep       = 1.0f / (float)(numDepthSteps - 1);
307
308         if (renderTarget.getDepthBits() == 0)
309                 throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);
310
311         gl.viewport(viewportX, viewportY, viewportW, viewportH);
312         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
313         gl.enable(GL_DEPTH_TEST);
314         gl.depthFunc(GL_LESS);
315
316         static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
317
318         // Render with given shader.
319         {
320                 glu::ShaderProgram program(m_context.getRenderContext(),
321                                                                    glu::makeVtxFragSources(specializeVersion(s_vertexShaderSrc, m_glslVersion).c_str(),
322                                                                                                                    specializeVersion(m_fragSrc, m_glslVersion).c_str()));
323                 log << program;
324
325                 if (!program.isOk())
326                         TCU_FAIL("Compile failed");
327
328                 const float coord[]     = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
329                 const float position[] = { -1.0f, -1.0f, +1.0f, 1.0f, -1.0f, +1.0f, 0.0f,  1.0f,
330                                                                    +1.0f, -1.0f, 0.0f,  1.0f, +1.0f, +1.0f, -1.0f, 1.0f };
331
332                 gl.useProgram(program.getProgram());
333                 gl.uniform4f(gl.getUniformLocation(program.getProgram(), "u_color"), 0.0f, 1.0f, 0.0f, 1.0f);
334
335                 // Setup default helper uniforms.
336                 setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());
337
338                 {
339                         glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("a_position", 4, 4, 0, &position[0]),
340                                                                                                            glu::va::Float("a_coord", 2, 4, 0, &coord[0]) };
341                         glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
342                                           &vertexArrays[0], glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
343                 }
344
345                 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw test quad");
346         }
347
348         // Visualize by rendering full-screen quads with increasing depth and color.
349         {
350                 glu::ShaderProgram program(
351                         m_context.getRenderContext(),
352                         glu::makeVtxFragSources(specializeVersion(s_vertexShaderSrc, m_glslVersion).c_str(),
353                                                                         specializeVersion(s_defaultFragmentShaderSrc, m_glslVersion).c_str()));
354                 if (!program.isOk())
355                 {
356                         log << program;
357                         TCU_FAIL("Compile failed");
358                 }
359
360                 int posLoc   = gl.getAttribLocation(program.getProgram(), "a_position");
361                 int colorLoc = gl.getUniformLocation(program.getProgram(), "u_color");
362
363                 gl.useProgram(program.getProgram());
364                 gl.depthMask(GL_FALSE);
365
366                 for (int stepNdx = 0; stepNdx < numDepthSteps; stepNdx++)
367                 {
368                         float f         = (float)stepNdx * depthStep;
369                         float depth = f * 2.0f - 1.0f;
370                         Vec4  color = Vec4(f, f, f, 1.0f);
371
372                         const float position[] = { -1.0f, -1.0f, depth, 1.0f, -1.0f, +1.0f, depth, 1.0f,
373                                                                            +1.0f, -1.0f, depth, 1.0f, +1.0f, +1.0f, depth, 1.0f };
374                         glu::VertexArrayBinding posBinding = glu::va::Float(posLoc, 4, 4, 0, &position[0]);
375
376                         gl.uniform4fv(colorLoc, 1, color.getPtr());
377                         glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
378                                           glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
379                 }
380
381                 GLU_EXPECT_NO_ERROR(gl.getError(), "Visualization draw");
382         }
383
384         glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());
385
386         // Render reference.
387         for (int y = 0; y < referenceFrame.getHeight(); y++)
388         {
389                 for (int x = 0; x < referenceFrame.getWidth(); x++)
390                 {
391                         float xf   = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
392                         float yf   = ((float)y + 0.5f) / (float)referenceFrame.getHeight();
393                         float d = m_evalFunc(Vec2(xf, yf));
394                         int   step = (int)deFloatFloor(d / depthStep);
395                         int   col  = de::clamp(deRoundFloatToInt32((float)step * depthStep * 255.0f), 0, 255);
396
397                         referenceFrame.setPixel(x, y, tcu::RGBA(col, col, col, 0xff));
398                 }
399         }
400
401         bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f,
402                                                                   tcu::COMPARE_LOG_RESULT);
403         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
404         return STOP;
405 }
406
407 FragDepthTests::FragDepthTests(Context& context, glu::GLSLVersion glslVersion)
408         : TestCaseGroup(context, "fragdepth", "gl_FragDepth tests"), m_glslVersion(glslVersion)
409 {
410 }
411
412 FragDepthTests::~FragDepthTests(void)
413 {
414 }
415
416 static float evalConstDepth(const Vec2& coord)
417 {
418         DE_UNREF(coord);
419         return 0.5f;
420 }
421 static float evalDynamicDepth(const Vec2& coord)
422 {
423         return (coord.x() + coord.y()) * 0.5f;
424 }
425 static float evalNoWrite(const Vec2& coord)
426 {
427         return 1.0f - (coord.x() + coord.y()) * 0.5f;
428 }
429
430 static float evalDynamicConditionalDepth(const Vec2& coord)
431 {
432         float d = (coord.x() + coord.y()) * 0.5f;
433         if (coord.y() < 0.5f)
434                 return d;
435         else
436                 return 1.0f - d;
437 }
438
439 void FragDepthTests::init(void)
440 {
441         static const struct
442         {
443                 const char*               name;
444                 const char*               desc;
445                 EvalFragDepthFunc evalFunc;
446                 const char*               fragSrc;
447         } cases[] = {
448                 { "no_write", "No gl_FragDepth write", evalNoWrite, "${VERSION_DECL}\n"
449                                                                                                                         "uniform highp vec4 u_color;\n"
450                                                                                                                         "layout(location = 0) out mediump vec4 o_color;\n"
451                                                                                                                         "void main (void)\n"
452                                                                                                                         "{\n"
453                                                                                                                         "   o_color = u_color;\n"
454                                                                                                                         "}\n" },
455                 { "const", "Const depth write", evalConstDepth, "${VERSION_DECL}\n"
456                                                                                                                 "uniform highp vec4 u_color;\n"
457                                                                                                                 "layout(location = 0) out mediump vec4 o_color;\n"
458                                                                                                                 "void main (void)\n"
459                                                                                                                 "{\n"
460                                                                                                                 "   o_color = u_color;\n"
461                                                                                                                 "   gl_FragDepth = 0.5;\n"
462                                                                                                                 "}\n" },
463                 { "uniform", "Uniform depth write", evalConstDepth, "${VERSION_DECL}\n"
464                                                                                                                         "uniform highp vec4 u_color;\n"
465                                                                                                                         "uniform highp float uf_half;\n"
466                                                                                                                         "layout(location = 0) out mediump vec4 o_color;\n"
467                                                                                                                         "void main (void)\n"
468                                                                                                                         "{\n"
469                                                                                                                         "   o_color = u_color;\n"
470                                                                                                                         "   gl_FragDepth = uf_half;\n"
471                                                                                                                         "}\n" },
472                 { "dynamic", "Dynamic depth write", evalDynamicDepth, "${VERSION_DECL}\n"
473                                                                                                                           "uniform highp vec4 u_color;\n"
474                                                                                                                           "in highp vec2 v_coord;\n"
475                                                                                                                           "layout(location = 0) out mediump vec4 o_color;\n"
476                                                                                                                           "void main (void)\n"
477                                                                                                                           "{\n"
478                                                                                                                           "   o_color = u_color;\n"
479                                                                                                                           "   gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n"
480                                                                                                                           "}\n" },
481                 { "fragcoord_z", "gl_FragDepth write from gl_FragCoord.z", evalNoWrite,
482                   "${VERSION_DECL}\n"
483                   "uniform highp vec4 u_color;\n"
484                   "layout(location = 0) out mediump vec4 o_color;\n"
485                   "void main (void)\n"
486                   "{\n"
487                   "   o_color = u_color;\n"
488                   "   gl_FragDepth = gl_FragCoord.z;\n"
489                   "}\n" },
490                 { "uniform_conditional_write", "Uniform conditional write", evalDynamicDepth,
491                   "${VERSION_DECL}\n"
492                   "uniform highp vec4 u_color;\n"
493                   "uniform bool ub_true;\n"
494                   "in highp vec2 v_coord;\n"
495                   "layout(location = 0) out mediump vec4 o_color;\n"
496                   "void main (void)\n"
497                   "{\n"
498                   "   o_color = u_color;\n"
499                   "   if (ub_true)\n"
500                   "       gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n"
501                   "}\n" },
502                 { "dynamic_conditional_write", "Uniform conditional write", evalDynamicConditionalDepth,
503                   "${VERSION_DECL}\n"
504                   "uniform highp vec4 u_color;\n"
505                   "uniform bool ub_true;\n"
506                   "in highp vec2 v_coord;\n"
507                   "layout(location = 0) out mediump vec4 o_color;\n"
508                   "void main (void)\n"
509                   "{\n"
510                   "   o_color = u_color;\n"
511                   "   mediump float d = (v_coord.x+v_coord.y)*0.5f;\n"
512                   "   if (v_coord.y < 0.5)\n"
513                   "       gl_FragDepth = d;\n"
514                   "   else\n"
515                   "       gl_FragDepth = 1.0 - d;\n"
516                   "}\n" },
517                 { "uniform_loop_write", "Uniform loop write", evalConstDepth, "${VERSION_DECL}\n"
518                                                                                                                                           "uniform highp vec4 u_color;\n"
519                                                                                                                                           "uniform int ui_two;\n"
520                                                                                                                                           "uniform highp float uf_fourth;\n"
521                                                                                                                                           "in highp vec2 v_coord;\n"
522                                                                                                                                           "layout(location = 0) out mediump vec4 o_color;\n"
523                                                                                                                                           "void main (void)\n"
524                                                                                                                                           "{\n"
525                                                                                                                                           "   o_color = u_color;\n"
526                                                                                                                                           "   gl_FragDepth = 0.0;\n"
527                                                                                                                                           "   for (int i = 0; i < ui_two; i++)\n"
528                                                                                                                                           "       gl_FragDepth += uf_fourth;\n"
529                                                                                                                                           "}\n" },
530                 { "write_in_function", "Uniform loop write", evalDynamicDepth,
531                   "${VERSION_DECL}\n"
532                   "uniform highp vec4 u_color;\n"
533                   "uniform highp float uf_half;\n"
534                   "in highp vec2 v_coord;\n"
535                   "layout(location = 0) out mediump vec4 o_color;\n"
536                   "void myfunc (highp vec2 coord)\n"
537                   "{\n"
538                   "   gl_FragDepth = (coord.x+coord.y)*0.5;\n"
539                   "}\n"
540                   "void main (void)\n"
541                   "{\n"
542                   "   o_color = u_color;\n"
543                   "   myfunc(v_coord);\n"
544                   "}\n" }
545         };
546
547         // .write
548         tcu::TestCaseGroup* writeGroup = new tcu::TestCaseGroup(m_testCtx, "write", "gl_FragDepth write tests");
549         addChild(writeGroup);
550         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
551                 writeGroup->addChild(new FragDepthWriteCase(m_context, cases[ndx].name, cases[ndx].desc, m_glslVersion,
552                                                                                                         cases[ndx].fragSrc, cases[ndx].evalFunc));
553
554         // .compare
555         tcu::TestCaseGroup* compareGroup =
556                 new tcu::TestCaseGroup(m_testCtx, "compare", "gl_FragDepth used with depth comparison");
557         addChild(compareGroup);
558         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
559                 compareGroup->addChild(new FragDepthCompareCase(m_context, cases[ndx].name, cases[ndx].desc, m_glslVersion,
560                                                                                                                 cases[ndx].fragSrc, cases[ndx].evalFunc, GL_LESS));
561 }
562
563 } // deqp