1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 2.0 Module 3e5c31af7Sopenharmony_ci * ------------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief glDepthRangef() tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es2fDepthRangeTests.hpp" 25e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 26e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 27e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 28e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 29e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 30e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 31e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 32e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 33e5c31af7Sopenharmony_ci#include "deRandom.hpp" 34e5c31af7Sopenharmony_ci#include "deMath.h" 35e5c31af7Sopenharmony_ci#include "deString.h" 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ci#include "glw.h" 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_cinamespace deqp 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_cinamespace gles2 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_cinamespace Functional 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_cienum 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_ci VISUALIZE_DEPTH_STEPS = 32 //!< Number of depth steps in visualization 49e5c31af7Sopenharmony_ci}; 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_ciusing tcu::Vec2; 52e5c31af7Sopenharmony_ciusing tcu::Vec3; 53e5c31af7Sopenharmony_ciusing tcu::Vec4; 54e5c31af7Sopenharmony_ciusing tcu::TestLog; 55e5c31af7Sopenharmony_ciusing std::string; 56e5c31af7Sopenharmony_ciusing std::vector; 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_cistatic const char* s_vertexShaderSrc = 59e5c31af7Sopenharmony_ci "attribute highp vec4 a_position;\n" 60e5c31af7Sopenharmony_ci "attribute highp vec2 a_coord;\n" 61e5c31af7Sopenharmony_ci "void main (void)\n" 62e5c31af7Sopenharmony_ci "{\n" 63e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 64e5c31af7Sopenharmony_ci "}\n"; 65e5c31af7Sopenharmony_cistatic const char* s_fragmentShaderSrc = 66e5c31af7Sopenharmony_ci "uniform mediump vec4 u_color;\n" 67e5c31af7Sopenharmony_ci "void main (void)\n" 68e5c31af7Sopenharmony_ci "{\n" 69e5c31af7Sopenharmony_ci " gl_FragColor = u_color;\n" 70e5c31af7Sopenharmony_ci "}\n"; 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_citemplate <typename T> 73e5c31af7Sopenharmony_cistatic inline bool compare (deUint32 func, T a, T b) 74e5c31af7Sopenharmony_ci{ 75e5c31af7Sopenharmony_ci switch (func) 76e5c31af7Sopenharmony_ci { 77e5c31af7Sopenharmony_ci case GL_NEVER: return false; 78e5c31af7Sopenharmony_ci case GL_ALWAYS: return true; 79e5c31af7Sopenharmony_ci case GL_LESS: return a < b; 80e5c31af7Sopenharmony_ci case GL_LEQUAL: return a <= b; 81e5c31af7Sopenharmony_ci case GL_EQUAL: return a == b; 82e5c31af7Sopenharmony_ci case GL_NOTEQUAL: return a != b; 83e5c31af7Sopenharmony_ci case GL_GEQUAL: return a >= b; 84e5c31af7Sopenharmony_ci case GL_GREATER: return a > b; 85e5c31af7Sopenharmony_ci default: 86e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 87e5c31af7Sopenharmony_ci return false; 88e5c31af7Sopenharmony_ci } 89e5c31af7Sopenharmony_ci} 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ciinline float triangleInterpolate (const float v0, const float v1, const float v2, const float x, const float y) 92e5c31af7Sopenharmony_ci{ 93e5c31af7Sopenharmony_ci return v0 + (v2-v0)*x + (v1-v0)*y; 94e5c31af7Sopenharmony_ci} 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ciinline float triQuadInterpolate (const float x, const float y, const tcu::Vec4& quad) 97e5c31af7Sopenharmony_ci{ 98e5c31af7Sopenharmony_ci // \note Top left fill rule. 99e5c31af7Sopenharmony_ci if (x + y < 1.0f) 100e5c31af7Sopenharmony_ci return triangleInterpolate(quad.x(), quad.y(), quad.z(), x, y); 101e5c31af7Sopenharmony_ci else 102e5c31af7Sopenharmony_ci return triangleInterpolate(quad.w(), quad.z(), quad.y(), 1.0f-x, 1.0f-y); 103e5c31af7Sopenharmony_ci} 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_ciinline float depthRangeTransform (const float zd, const float zNear, const float zFar) 106e5c31af7Sopenharmony_ci{ 107e5c31af7Sopenharmony_ci const float cNear = de::clamp(zNear, 0.0f, 1.0f); 108e5c31af7Sopenharmony_ci const float cFar = de::clamp(zFar, 0.0f, 1.0f); 109e5c31af7Sopenharmony_ci return ((cFar - cNear)/2.0f) * zd + (cNear + cFar)/2.0f; 110e5c31af7Sopenharmony_ci} 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ciclass DepthRangeCompareCase : public TestCase 113e5c31af7Sopenharmony_ci{ 114e5c31af7Sopenharmony_cipublic: 115e5c31af7Sopenharmony_ci DepthRangeCompareCase (Context& context, const char* name, const char* desc, const tcu::Vec4& depthCoord, const float zNear, const float zFar, const deUint32 compareFunc); 116e5c31af7Sopenharmony_ci ~DepthRangeCompareCase (void); 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci IterateResult iterate (void); 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ciprivate: 121e5c31af7Sopenharmony_ci const tcu::Vec4 m_depthCoord; 122e5c31af7Sopenharmony_ci const float m_zNear; 123e5c31af7Sopenharmony_ci const float m_zFar; 124e5c31af7Sopenharmony_ci const deUint32 m_compareFunc; 125e5c31af7Sopenharmony_ci}; 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ciDepthRangeCompareCase::DepthRangeCompareCase (Context& context, const char* name, const char* desc, const tcu::Vec4& depthCoord, const float zNear, const float zFar, const deUint32 compareFunc) 128e5c31af7Sopenharmony_ci : TestCase (context, name, desc) 129e5c31af7Sopenharmony_ci , m_depthCoord (depthCoord) 130e5c31af7Sopenharmony_ci , m_zNear (zNear) 131e5c31af7Sopenharmony_ci , m_zFar (zFar) 132e5c31af7Sopenharmony_ci , m_compareFunc (compareFunc) 133e5c31af7Sopenharmony_ci{ 134e5c31af7Sopenharmony_ci} 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ciDepthRangeCompareCase::~DepthRangeCompareCase (void) 137e5c31af7Sopenharmony_ci{ 138e5c31af7Sopenharmony_ci} 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ciDepthRangeCompareCase::IterateResult DepthRangeCompareCase::iterate (void) 141e5c31af7Sopenharmony_ci{ 142e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 143e5c31af7Sopenharmony_ci de::Random rnd (deStringHash(getName())); 144e5c31af7Sopenharmony_ci const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 145e5c31af7Sopenharmony_ci const int viewportW = de::min(128, renderTarget.getWidth()); 146e5c31af7Sopenharmony_ci const int viewportH = de::min(128, renderTarget.getHeight()); 147e5c31af7Sopenharmony_ci const int viewportX = rnd.getInt(0, renderTarget.getWidth()-viewportW); 148e5c31af7Sopenharmony_ci const int viewportY = rnd.getInt(0, renderTarget.getHeight()-viewportH); 149e5c31af7Sopenharmony_ci tcu::Surface renderedFrame (viewportW, viewportH); 150e5c31af7Sopenharmony_ci tcu::Surface referenceFrame (viewportW, viewportH); 151e5c31af7Sopenharmony_ci const float constDepth = 0.1f; 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_ci if (renderTarget.getDepthBits() == 0) 154e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__); 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, s_fragmentShaderSrc)); 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_ci if (!program.isOk()) 159e5c31af7Sopenharmony_ci { 160e5c31af7Sopenharmony_ci log << program; 161e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 162e5c31af7Sopenharmony_ci } 163e5c31af7Sopenharmony_ci 164e5c31af7Sopenharmony_ci const int colorLoc = glGetUniformLocation(program.getProgram(), "u_color"); 165e5c31af7Sopenharmony_ci const int posLoc = glGetAttribLocation(program.getProgram(), "a_position"); 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << "glDepthRangef(" << m_zNear << ", " << m_zFar << ")" << TestLog::EndMessage; 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci glViewport(viewportX, viewportY, viewportW, viewportH); 170e5c31af7Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 171e5c31af7Sopenharmony_ci glEnable(GL_DEPTH_TEST); 172e5c31af7Sopenharmony_ci glUseProgram(program.getProgram()); 173e5c31af7Sopenharmony_ci glEnableVertexAttribArray(posLoc); 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ci static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 }; 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_ci // Fill viewport with 2 quads - one with constant depth and another with d = [-1..1] 178e5c31af7Sopenharmony_ci { 179e5c31af7Sopenharmony_ci static const float constDepthCoord[] = 180e5c31af7Sopenharmony_ci { 181e5c31af7Sopenharmony_ci -1.0f, -1.0f, constDepth, 1.0f, 182e5c31af7Sopenharmony_ci -1.0f, +1.0f, constDepth, 1.0f, 183e5c31af7Sopenharmony_ci 0.0f, -1.0f, constDepth, 1.0f, 184e5c31af7Sopenharmony_ci 0.0f, +1.0f, constDepth, 1.0f 185e5c31af7Sopenharmony_ci }; 186e5c31af7Sopenharmony_ci static const float varyingDepthCoord[] = 187e5c31af7Sopenharmony_ci { 188e5c31af7Sopenharmony_ci 0.0f, -1.0f, +1.0f, 1.0f, 189e5c31af7Sopenharmony_ci 0.0f, +1.0f, 0.0f, 1.0f, 190e5c31af7Sopenharmony_ci +1.0f, -1.0f, 0.0f, 1.0f, 191e5c31af7Sopenharmony_ci +1.0f, +1.0f, -1.0f, 1.0f 192e5c31af7Sopenharmony_ci }; 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci glUniform4f(colorLoc, 0.0f, 0.0f, 1.0f, 1.0f); 195e5c31af7Sopenharmony_ci glDepthFunc(GL_ALWAYS); 196e5c31af7Sopenharmony_ci 197e5c31af7Sopenharmony_ci glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &constDepthCoord); 198e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]); 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &varyingDepthCoord); 201e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]); 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci GLU_CHECK(); 204e5c31af7Sopenharmony_ci } 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ci // Render with depth test. 207e5c31af7Sopenharmony_ci { 208e5c31af7Sopenharmony_ci const float position[] = 209e5c31af7Sopenharmony_ci { 210e5c31af7Sopenharmony_ci -1.0f, -1.0f, m_depthCoord[0], 1.0f, 211e5c31af7Sopenharmony_ci -1.0f, +1.0f, m_depthCoord[1], 1.0f, 212e5c31af7Sopenharmony_ci +1.0f, -1.0f, m_depthCoord[2], 1.0f, 213e5c31af7Sopenharmony_ci +1.0f, +1.0f, m_depthCoord[3], 1.0f 214e5c31af7Sopenharmony_ci }; 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci glDepthRangef(m_zNear, m_zFar); 217e5c31af7Sopenharmony_ci glDepthFunc(m_compareFunc); 218e5c31af7Sopenharmony_ci glUniform4f(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f); 219e5c31af7Sopenharmony_ci 220e5c31af7Sopenharmony_ci glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]); 221e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]); 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci GLU_CHECK(); 224e5c31af7Sopenharmony_ci } 225e5c31af7Sopenharmony_ci 226e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess()); 227e5c31af7Sopenharmony_ci 228e5c31af7Sopenharmony_ci // Render reference. 229e5c31af7Sopenharmony_ci for (int y = 0; y < referenceFrame.getHeight(); y++) 230e5c31af7Sopenharmony_ci { 231e5c31af7Sopenharmony_ci float yf = ((float)y + 0.5f) / (float)referenceFrame.getHeight(); 232e5c31af7Sopenharmony_ci int half = de::clamp((int)((float)referenceFrame.getWidth()*0.5f + 0.5f), 0, referenceFrame.getWidth()); 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci // Fill left half - comparison to constant 0.5 235e5c31af7Sopenharmony_ci for (int x = 0; x < half; x++) 236e5c31af7Sopenharmony_ci { 237e5c31af7Sopenharmony_ci float xf = ((float)x + 0.5f) / (float)referenceFrame.getWidth(); 238e5c31af7Sopenharmony_ci float d = depthRangeTransform(triQuadInterpolate(xf, yf, m_depthCoord), m_zNear, m_zFar); 239e5c31af7Sopenharmony_ci bool dpass = compare(m_compareFunc, d, constDepth*0.5f + 0.5f); 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green() : tcu::RGBA::blue()); 242e5c31af7Sopenharmony_ci } 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci // Fill right half - comparison to interpolated depth 245e5c31af7Sopenharmony_ci for (int x = half; x < referenceFrame.getWidth(); x++) 246e5c31af7Sopenharmony_ci { 247e5c31af7Sopenharmony_ci float xf = ((float)x + 0.5f) / (float)referenceFrame.getWidth(); 248e5c31af7Sopenharmony_ci float xh = ((float)(x - half) + 0.5f) / (float)(referenceFrame.getWidth()-half); 249e5c31af7Sopenharmony_ci float rd = 1.0f - (xh + yf) * 0.5f; 250e5c31af7Sopenharmony_ci float d = depthRangeTransform(triQuadInterpolate(xf, yf, m_depthCoord), m_zNear, m_zFar); 251e5c31af7Sopenharmony_ci bool dpass = compare(m_compareFunc, d, rd); 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green() : tcu::RGBA::blue()); 254e5c31af7Sopenharmony_ci } 255e5c31af7Sopenharmony_ci } 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f, tcu::COMPARE_LOG_RESULT); 258e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 259e5c31af7Sopenharmony_ci isOk ? "Pass" : "Fail"); 260e5c31af7Sopenharmony_ci return STOP; 261e5c31af7Sopenharmony_ci} 262e5c31af7Sopenharmony_ci 263e5c31af7Sopenharmony_ciclass DepthRangeWriteCase : public TestCase 264e5c31af7Sopenharmony_ci{ 265e5c31af7Sopenharmony_cipublic: 266e5c31af7Sopenharmony_ci DepthRangeWriteCase (Context& context, const char* name, const char* desc, const tcu::Vec4& depthCoord, const float zNear, const float zFar); 267e5c31af7Sopenharmony_ci ~DepthRangeWriteCase (void); 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_ci IterateResult iterate (void); 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ciprivate: 272e5c31af7Sopenharmony_ci const tcu::Vec4& m_depthCoord; 273e5c31af7Sopenharmony_ci const float m_zNear; 274e5c31af7Sopenharmony_ci const float m_zFar; 275e5c31af7Sopenharmony_ci}; 276e5c31af7Sopenharmony_ci 277e5c31af7Sopenharmony_ciDepthRangeWriteCase::DepthRangeWriteCase (Context& context, const char* name, const char* desc, const tcu::Vec4& depthCoord, const float zNear, const float zFar) 278e5c31af7Sopenharmony_ci : TestCase (context, name, desc) 279e5c31af7Sopenharmony_ci , m_depthCoord (depthCoord) 280e5c31af7Sopenharmony_ci , m_zNear (zNear) 281e5c31af7Sopenharmony_ci , m_zFar (zFar) 282e5c31af7Sopenharmony_ci{ 283e5c31af7Sopenharmony_ci} 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ciDepthRangeWriteCase::~DepthRangeWriteCase (void) 286e5c31af7Sopenharmony_ci{ 287e5c31af7Sopenharmony_ci} 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ciDepthRangeWriteCase::IterateResult DepthRangeWriteCase::iterate (void) 290e5c31af7Sopenharmony_ci{ 291e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 292e5c31af7Sopenharmony_ci de::Random rnd (deStringHash(getName())); 293e5c31af7Sopenharmony_ci const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 294e5c31af7Sopenharmony_ci const int viewportW = de::min(128, renderTarget.getWidth()); 295e5c31af7Sopenharmony_ci const int viewportH = de::min(128, renderTarget.getHeight()); 296e5c31af7Sopenharmony_ci const int viewportX = rnd.getInt(0, renderTarget.getWidth()-viewportW); 297e5c31af7Sopenharmony_ci const int viewportY = rnd.getInt(0, renderTarget.getHeight()-viewportH); 298e5c31af7Sopenharmony_ci tcu::Surface renderedFrame (viewportW, viewportH); 299e5c31af7Sopenharmony_ci tcu::Surface referenceFrame (viewportW, viewportH); 300e5c31af7Sopenharmony_ci const int numDepthSteps = VISUALIZE_DEPTH_STEPS; 301e5c31af7Sopenharmony_ci const float depthStep = 1.0f/(float)(numDepthSteps-1); 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci if (renderTarget.getDepthBits() == 0) 304e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__); 305e5c31af7Sopenharmony_ci 306e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, s_fragmentShaderSrc)); 307e5c31af7Sopenharmony_ci 308e5c31af7Sopenharmony_ci if (!program.isOk()) 309e5c31af7Sopenharmony_ci { 310e5c31af7Sopenharmony_ci log << program; 311e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 312e5c31af7Sopenharmony_ci } 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci const int colorLoc = glGetUniformLocation(program.getProgram(), "u_color"); 315e5c31af7Sopenharmony_ci const int posLoc = glGetAttribLocation(program.getProgram(), "a_position"); 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << "glDepthRangef(" << m_zNear << ", " << m_zFar << ")" << TestLog::EndMessage; 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci glViewport(viewportX, viewportY, viewportW, viewportH); 320e5c31af7Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 321e5c31af7Sopenharmony_ci glEnable(GL_DEPTH_TEST); 322e5c31af7Sopenharmony_ci glUseProgram(program.getProgram()); 323e5c31af7Sopenharmony_ci glEnableVertexAttribArray(posLoc); 324e5c31af7Sopenharmony_ci 325e5c31af7Sopenharmony_ci static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 }; 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci // Render with depth range. 328e5c31af7Sopenharmony_ci { 329e5c31af7Sopenharmony_ci const float position[] = 330e5c31af7Sopenharmony_ci { 331e5c31af7Sopenharmony_ci -1.0f, -1.0f, m_depthCoord[0], 1.0f, 332e5c31af7Sopenharmony_ci -1.0f, +1.0f, m_depthCoord[1], 1.0f, 333e5c31af7Sopenharmony_ci +1.0f, -1.0f, m_depthCoord[2], 1.0f, 334e5c31af7Sopenharmony_ci +1.0f, +1.0f, m_depthCoord[3], 1.0f 335e5c31af7Sopenharmony_ci }; 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_ci glDepthFunc(GL_ALWAYS); 338e5c31af7Sopenharmony_ci glDepthRangef(m_zNear, m_zFar); 339e5c31af7Sopenharmony_ci glUniform4f(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f); 340e5c31af7Sopenharmony_ci glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]); 341e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]); 342e5c31af7Sopenharmony_ci GLU_CHECK(); 343e5c31af7Sopenharmony_ci } 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ci // Visualize by rendering full-screen quads with increasing depth and color. 346e5c31af7Sopenharmony_ci { 347e5c31af7Sopenharmony_ci glDepthFunc(GL_LEQUAL); 348e5c31af7Sopenharmony_ci glDepthMask(GL_FALSE); 349e5c31af7Sopenharmony_ci glDepthRangef(0.0f, 1.0f); 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci for (int stepNdx = 0; stepNdx < numDepthSteps; stepNdx++) 352e5c31af7Sopenharmony_ci { 353e5c31af7Sopenharmony_ci float f = (float)stepNdx*depthStep; 354e5c31af7Sopenharmony_ci float depth = f*2.0f - 1.0f; 355e5c31af7Sopenharmony_ci Vec4 color = Vec4(f, f, f, 1.0f); 356e5c31af7Sopenharmony_ci 357e5c31af7Sopenharmony_ci float position[] = 358e5c31af7Sopenharmony_ci { 359e5c31af7Sopenharmony_ci -1.0f, -1.0f, depth, 1.0f, 360e5c31af7Sopenharmony_ci -1.0f, +1.0f, depth, 1.0f, 361e5c31af7Sopenharmony_ci +1.0f, -1.0f, depth, 1.0f, 362e5c31af7Sopenharmony_ci +1.0f, +1.0f, depth, 1.0f 363e5c31af7Sopenharmony_ci }; 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci glUniform4fv(colorLoc, 1, color.getPtr()); 366e5c31af7Sopenharmony_ci glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]); 367e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]); 368e5c31af7Sopenharmony_ci } 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci GLU_CHECK(); 371e5c31af7Sopenharmony_ci } 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess()); 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci // Render reference. 376e5c31af7Sopenharmony_ci for (int y = 0; y < referenceFrame.getHeight(); y++) 377e5c31af7Sopenharmony_ci { 378e5c31af7Sopenharmony_ci for (int x = 0; x < referenceFrame.getWidth(); x++) 379e5c31af7Sopenharmony_ci { 380e5c31af7Sopenharmony_ci float xf = ((float)x + 0.5f) / (float)referenceFrame.getWidth(); 381e5c31af7Sopenharmony_ci float yf = ((float)y + 0.5f) / (float)referenceFrame.getHeight(); 382e5c31af7Sopenharmony_ci float d = depthRangeTransform(triQuadInterpolate(xf, yf, m_depthCoord), m_zNear, m_zFar); 383e5c31af7Sopenharmony_ci int step = (int)deFloatFloor(d / depthStep); 384e5c31af7Sopenharmony_ci int col = de::clamp(deRoundFloatToInt32((float)step*depthStep*255.0f), 0, 255); 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci referenceFrame.setPixel(x, y, tcu::RGBA(col, col, col, 0xff)); 387e5c31af7Sopenharmony_ci } 388e5c31af7Sopenharmony_ci } 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f, tcu::COMPARE_LOG_RESULT); 391e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 392e5c31af7Sopenharmony_ci isOk ? "Pass" : "Fail"); 393e5c31af7Sopenharmony_ci return STOP; 394e5c31af7Sopenharmony_ci} 395e5c31af7Sopenharmony_ci 396e5c31af7Sopenharmony_ciDepthRangeTests::DepthRangeTests (Context& context) 397e5c31af7Sopenharmony_ci : TestCaseGroup(context, "depth_range", "glDepthRangef() tests") 398e5c31af7Sopenharmony_ci{ 399e5c31af7Sopenharmony_ci} 400e5c31af7Sopenharmony_ci 401e5c31af7Sopenharmony_ciDepthRangeTests::~DepthRangeTests (void) 402e5c31af7Sopenharmony_ci{ 403e5c31af7Sopenharmony_ci} 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_civoid DepthRangeTests::init (void) 406e5c31af7Sopenharmony_ci{ 407e5c31af7Sopenharmony_ci static const struct 408e5c31af7Sopenharmony_ci { 409e5c31af7Sopenharmony_ci const char* name; 410e5c31af7Sopenharmony_ci const char* desc; 411e5c31af7Sopenharmony_ci const tcu::Vec4 depthCoord; 412e5c31af7Sopenharmony_ci const float zNear; 413e5c31af7Sopenharmony_ci const float zFar; 414e5c31af7Sopenharmony_ci } cases[] = 415e5c31af7Sopenharmony_ci { 416e5c31af7Sopenharmony_ci { "default", "Default depth range", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.0f, 1.0f }, 417e5c31af7Sopenharmony_ci { "reverse", "Reversed default range", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 1.0f, 0.0f }, 418e5c31af7Sopenharmony_ci { "zero_to_half", "From 0 to 0.5", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.0f, 0.5f }, 419e5c31af7Sopenharmony_ci { "half_to_one", "From 0.5 to 1", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.5f, 1.0f }, 420e5c31af7Sopenharmony_ci { "half_to_zero", "From 0.5 to 0", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.5f, 0.0f }, 421e5c31af7Sopenharmony_ci { "one_to_half", "From 1 to 0.5", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 1.0f, 0.5f }, 422e5c31af7Sopenharmony_ci { "third_to_0_8", "From 1/3 to 0.8", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 1.0f/3.0f, 0.8f }, 423e5c31af7Sopenharmony_ci { "0_8_to_third", "From 0.8 to 1/3", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.8f, 1.0f/3.0f }, 424e5c31af7Sopenharmony_ci { "zero_to_zero", "From 0 to 0", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.0f, 0.0f }, 425e5c31af7Sopenharmony_ci { "half_to_half", "From 0.5 to 0.5", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.5f, 0.5f }, 426e5c31af7Sopenharmony_ci { "one_to_one", "From 1 to 1", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 1.0f, 1.0f }, 427e5c31af7Sopenharmony_ci { "clamp_near", "From -1 to 1", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), -1.0f, 1.0f }, 428e5c31af7Sopenharmony_ci { "clamp_far", "From 0 to 2", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.0f, 2.0 }, 429e5c31af7Sopenharmony_ci { "clamp_both", "From -1 to 2", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), -1.0, 2.0 } 430e5c31af7Sopenharmony_ci }; 431e5c31af7Sopenharmony_ci 432e5c31af7Sopenharmony_ci // .write 433e5c31af7Sopenharmony_ci tcu::TestCaseGroup* writeGroup = new tcu::TestCaseGroup(m_testCtx, "write", "gl_FragDepth write tests"); 434e5c31af7Sopenharmony_ci addChild(writeGroup); 435e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++) 436e5c31af7Sopenharmony_ci writeGroup->addChild(new DepthRangeWriteCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].depthCoord, cases[ndx].zNear, cases[ndx].zFar)); 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_ci // .compare 439e5c31af7Sopenharmony_ci tcu::TestCaseGroup* compareGroup = new tcu::TestCaseGroup(m_testCtx, "compare", "gl_FragDepth used with depth comparison"); 440e5c31af7Sopenharmony_ci addChild(compareGroup); 441e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++) 442e5c31af7Sopenharmony_ci compareGroup->addChild(new DepthRangeCompareCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].depthCoord, cases[ndx].zNear, cases[ndx].zFar, GL_LESS)); 443e5c31af7Sopenharmony_ci} 444e5c31af7Sopenharmony_ci 445e5c31af7Sopenharmony_ci} // Functional 446e5c31af7Sopenharmony_ci} // gles3 447e5c31af7Sopenharmony_ci} // deqp 448