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 std::string;
48 using std::vector;
49 using tcu::TestLog;
50 using tcu::Vec2;
51 using tcu::Vec3;
52 using tcu::Vec4;
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>
compare(uint32_t func,T a,T b)74 static inline bool compare(uint32_t 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(false);
96 return false;
97 }
98 }
99
specializeVersion(const std::string & source,glu::GLSLVersion version)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, uint32_t 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 uint32_t m_compareFunc;
123 };
124
FragDepthCompareCase(Context & context,const char * name,const char * desc,glu::GLSLVersion glslVersion,const char * fragSrc,EvalFragDepthFunc evalFunc,uint32_t compareFunc)125 FragDepthCompareCase::FragDepthCompareCase(Context &context, const char *name, const char *desc,
126 glu::GLSLVersion glslVersion, const char *fragSrc,
127 EvalFragDepthFunc evalFunc, uint32_t 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
~FragDepthCompareCase(void)136 FragDepthCompareCase::~FragDepthCompareCase(void)
137 {
138 }
139
iterate(void)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 uint16_t 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
FragDepthWriteCase(Context & context,const char * name,const char * desc,glu::GLSLVersion glslVersion,const char * fragSrc,EvalFragDepthFunc evalFunc)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)
286 , m_glslVersion(glslVersion)
287 , m_fragSrc(fragSrc)
288 , m_evalFunc(evalFunc)
289 {
290 }
291
~FragDepthWriteCase(void)292 FragDepthWriteCase::~FragDepthWriteCase(void)
293 {
294 }
295
iterate(void)296 FragDepthWriteCase::IterateResult FragDepthWriteCase::iterate(void)
297 {
298 TestLog &log = m_testCtx.getLog();
299 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
300 de::Random rnd(deStringHash(getName()));
301 const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
302 int viewportW = de::min(128, renderTarget.getWidth());
303 int viewportH = de::min(128, renderTarget.getHeight());
304 int viewportX = rnd.getInt(0, renderTarget.getWidth() - viewportW);
305 int viewportY = rnd.getInt(0, renderTarget.getHeight() - viewportH);
306 tcu::Surface renderedFrame(viewportW, viewportH);
307 tcu::Surface referenceFrame(viewportW, viewportH);
308 const int numDepthSteps = 16;
309 const float depthStep = 1.0f / (float)(numDepthSteps - 1);
310
311 if (renderTarget.getDepthBits() == 0)
312 throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);
313
314 gl.viewport(viewportX, viewportY, viewportW, viewportH);
315 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
316 gl.enable(GL_DEPTH_TEST);
317 gl.depthFunc(GL_LESS);
318
319 static const uint16_t quadIndices[] = {0, 1, 2, 2, 1, 3};
320
321 // Render with given shader.
322 {
323 glu::ShaderProgram program(m_context.getRenderContext(),
324 glu::makeVtxFragSources(specializeVersion(s_vertexShaderSrc, m_glslVersion).c_str(),
325 specializeVersion(m_fragSrc, m_glslVersion).c_str()));
326 log << program;
327
328 if (!program.isOk())
329 TCU_FAIL("Compile failed");
330
331 const float coord[] = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f};
332 const float position[] = {-1.0f, -1.0f, +1.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f,
333 +1.0f, -1.0f, 0.0f, 1.0f, +1.0f, +1.0f, -1.0f, 1.0f};
334
335 gl.useProgram(program.getProgram());
336 gl.uniform4f(gl.getUniformLocation(program.getProgram(), "u_color"), 0.0f, 1.0f, 0.0f, 1.0f);
337
338 // Setup default helper uniforms.
339 setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());
340
341 {
342 glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 4, 4, 0, &position[0]),
343 glu::va::Float("a_coord", 2, 4, 0, &coord[0])};
344 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
345 &vertexArrays[0], glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
346 }
347
348 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw test quad");
349 }
350
351 // Visualize by rendering full-screen quads with increasing depth and color.
352 {
353 glu::ShaderProgram program(
354 m_context.getRenderContext(),
355 glu::makeVtxFragSources(specializeVersion(s_vertexShaderSrc, m_glslVersion).c_str(),
356 specializeVersion(s_defaultFragmentShaderSrc, m_glslVersion).c_str()));
357 if (!program.isOk())
358 {
359 log << program;
360 TCU_FAIL("Compile failed");
361 }
362
363 int posLoc = gl.getAttribLocation(program.getProgram(), "a_position");
364 int colorLoc = gl.getUniformLocation(program.getProgram(), "u_color");
365
366 gl.useProgram(program.getProgram());
367 gl.depthMask(GL_FALSE);
368
369 for (int stepNdx = 0; stepNdx < numDepthSteps; stepNdx++)
370 {
371 float f = (float)stepNdx * depthStep;
372 float depth = f * 2.0f - 1.0f;
373 Vec4 color = Vec4(f, f, f, 1.0f);
374
375 const float position[] = {-1.0f, -1.0f, depth, 1.0f, -1.0f, +1.0f, depth, 1.0f,
376 +1.0f, -1.0f, depth, 1.0f, +1.0f, +1.0f, depth, 1.0f};
377 glu::VertexArrayBinding posBinding = glu::va::Float(posLoc, 4, 4, 0, &position[0]);
378
379 gl.uniform4fv(colorLoc, 1, color.getPtr());
380 glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
381 glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
382 }
383
384 GLU_EXPECT_NO_ERROR(gl.getError(), "Visualization draw");
385 }
386
387 glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());
388
389 // Render reference.
390 for (int y = 0; y < referenceFrame.getHeight(); y++)
391 {
392 for (int x = 0; x < referenceFrame.getWidth(); x++)
393 {
394 float xf = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
395 float yf = ((float)y + 0.5f) / (float)referenceFrame.getHeight();
396 float d = m_evalFunc(Vec2(xf, yf));
397 int step = (int)deFloatFloor(d / depthStep);
398 int col = de::clamp(deRoundFloatToInt32((float)step * depthStep * 255.0f), 0, 255);
399
400 referenceFrame.setPixel(x, y, tcu::RGBA(col, col, col, 0xff));
401 }
402 }
403
404 bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f,
405 tcu::COMPARE_LOG_RESULT);
406 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
407 return STOP;
408 }
409
FragDepthTests(Context & context,glu::GLSLVersion glslVersion)410 FragDepthTests::FragDepthTests(Context &context, glu::GLSLVersion glslVersion)
411 : TestCaseGroup(context, "fragdepth", "gl_FragDepth tests")
412 , m_glslVersion(glslVersion)
413 {
414 }
415
~FragDepthTests(void)416 FragDepthTests::~FragDepthTests(void)
417 {
418 }
419
evalConstDepth(const Vec2 & coord)420 static float evalConstDepth(const Vec2 &coord)
421 {
422 DE_UNREF(coord);
423 return 0.5f;
424 }
evalDynamicDepth(const Vec2 & coord)425 static float evalDynamicDepth(const Vec2 &coord)
426 {
427 return (coord.x() + coord.y()) * 0.5f;
428 }
evalNoWrite(const Vec2 & coord)429 static float evalNoWrite(const Vec2 &coord)
430 {
431 return 1.0f - (coord.x() + coord.y()) * 0.5f;
432 }
433
evalDynamicConditionalDepth(const Vec2 & coord)434 static float evalDynamicConditionalDepth(const Vec2 &coord)
435 {
436 float d = (coord.x() + coord.y()) * 0.5f;
437 if (coord.y() < 0.5f)
438 return d;
439 else
440 return 1.0f - d;
441 }
442
init(void)443 void FragDepthTests::init(void)
444 {
445 static const struct
446 {
447 const char *name;
448 const char *desc;
449 EvalFragDepthFunc evalFunc;
450 const char *fragSrc;
451 } cases[] = {{"no_write", "No gl_FragDepth write", evalNoWrite,
452 "${VERSION_DECL}\n"
453 "uniform highp vec4 u_color;\n"
454 "layout(location = 0) out mediump vec4 o_color;\n"
455 "void main (void)\n"
456 "{\n"
457 " o_color = u_color;\n"
458 "}\n"},
459 {"const", "Const depth write", evalConstDepth,
460 "${VERSION_DECL}\n"
461 "uniform highp vec4 u_color;\n"
462 "layout(location = 0) out mediump vec4 o_color;\n"
463 "void main (void)\n"
464 "{\n"
465 " o_color = u_color;\n"
466 " gl_FragDepth = 0.5;\n"
467 "}\n"},
468 {"uniform", "Uniform depth write", evalConstDepth,
469 "${VERSION_DECL}\n"
470 "uniform highp vec4 u_color;\n"
471 "uniform highp float uf_half;\n"
472 "layout(location = 0) out mediump vec4 o_color;\n"
473 "void main (void)\n"
474 "{\n"
475 " o_color = u_color;\n"
476 " gl_FragDepth = uf_half;\n"
477 "}\n"},
478 {"dynamic", "Dynamic depth write", evalDynamicDepth,
479 "${VERSION_DECL}\n"
480 "uniform highp vec4 u_color;\n"
481 "in highp vec2 v_coord;\n"
482 "layout(location = 0) out mediump vec4 o_color;\n"
483 "void main (void)\n"
484 "{\n"
485 " o_color = u_color;\n"
486 " gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n"
487 "}\n"},
488 {"fragcoord_z", "gl_FragDepth write from gl_FragCoord.z", evalNoWrite,
489 "${VERSION_DECL}\n"
490 "uniform highp vec4 u_color;\n"
491 "layout(location = 0) out mediump vec4 o_color;\n"
492 "void main (void)\n"
493 "{\n"
494 " o_color = u_color;\n"
495 " gl_FragDepth = gl_FragCoord.z;\n"
496 "}\n"},
497 {"uniform_conditional_write", "Uniform conditional write", evalDynamicDepth,
498 "${VERSION_DECL}\n"
499 "uniform highp vec4 u_color;\n"
500 "uniform bool ub_true;\n"
501 "in highp vec2 v_coord;\n"
502 "layout(location = 0) out mediump vec4 o_color;\n"
503 "void main (void)\n"
504 "{\n"
505 " o_color = u_color;\n"
506 " if (ub_true)\n"
507 " gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n"
508 "}\n"},
509 {"dynamic_conditional_write", "Uniform conditional write", evalDynamicConditionalDepth,
510 "${VERSION_DECL}\n"
511 "uniform highp vec4 u_color;\n"
512 "uniform bool ub_true;\n"
513 "in highp vec2 v_coord;\n"
514 "layout(location = 0) out mediump vec4 o_color;\n"
515 "void main (void)\n"
516 "{\n"
517 " o_color = u_color;\n"
518 " mediump float d = (v_coord.x+v_coord.y)*0.5f;\n"
519 " if (v_coord.y < 0.5)\n"
520 " gl_FragDepth = d;\n"
521 " else\n"
522 " gl_FragDepth = 1.0 - d;\n"
523 "}\n"},
524 {"uniform_loop_write", "Uniform loop write", evalConstDepth,
525 "${VERSION_DECL}\n"
526 "uniform highp vec4 u_color;\n"
527 "uniform int ui_two;\n"
528 "uniform highp float uf_fourth;\n"
529 "in highp vec2 v_coord;\n"
530 "layout(location = 0) out mediump vec4 o_color;\n"
531 "void main (void)\n"
532 "{\n"
533 " o_color = u_color;\n"
534 " gl_FragDepth = 0.0;\n"
535 " for (int i = 0; i < ui_two; i++)\n"
536 " gl_FragDepth += uf_fourth;\n"
537 "}\n"},
538 {"write_in_function", "Uniform loop write", evalDynamicDepth,
539 "${VERSION_DECL}\n"
540 "uniform highp vec4 u_color;\n"
541 "uniform highp float uf_half;\n"
542 "in highp vec2 v_coord;\n"
543 "layout(location = 0) out mediump vec4 o_color;\n"
544 "void myfunc (highp vec2 coord)\n"
545 "{\n"
546 " gl_FragDepth = (coord.x+coord.y)*0.5;\n"
547 "}\n"
548 "void main (void)\n"
549 "{\n"
550 " o_color = u_color;\n"
551 " myfunc(v_coord);\n"
552 "}\n"}};
553
554 // .write
555 tcu::TestCaseGroup *writeGroup = new tcu::TestCaseGroup(m_testCtx, "write", "gl_FragDepth write tests");
556 addChild(writeGroup);
557 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
558 writeGroup->addChild(new FragDepthWriteCase(m_context, cases[ndx].name, cases[ndx].desc, m_glslVersion,
559 cases[ndx].fragSrc, cases[ndx].evalFunc));
560
561 // .compare
562 tcu::TestCaseGroup *compareGroup =
563 new tcu::TestCaseGroup(m_testCtx, "compare", "gl_FragDepth used with depth comparison");
564 addChild(compareGroup);
565 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
566 compareGroup->addChild(new FragDepthCompareCase(m_context, cases[ndx].name, cases[ndx].desc, m_glslVersion,
567 cases[ndx].fragSrc, cases[ndx].evalFunc, GL_LESS));
568 }
569
570 } // namespace deqp
571