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