1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.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 Rasterizer discard tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es3fRasterizerDiscardTests.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 27e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 28e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 29e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 30e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 31e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 32e5c31af7Sopenharmony_ci#include "deRandom.hpp" 33e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 34e5c31af7Sopenharmony_ci#include "deString.h" 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_ci#include "glw.h" 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ciusing tcu::Vec4; 39e5c31af7Sopenharmony_ciusing tcu::TestLog; 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_cinamespace deqp 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_cinamespace gles3 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_cinamespace Functional 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_cistatic const int NUM_CASE_ITERATIONS = 1; 49e5c31af7Sopenharmony_cistatic const Vec4 FAIL_COLOR_RED = Vec4(1.0f, 0.0f, 0.0f, 1.0f); 50e5c31af7Sopenharmony_cistatic const Vec4 PASS_COLOR_BLUE = Vec4(0.0f, 0.0f, 0.5f, 1.0f); 51e5c31af7Sopenharmony_cistatic const Vec4 BLACK_COLOR = Vec4(0.0f, 0.0f, 0.0f, 1.0f); 52e5c31af7Sopenharmony_cistatic const float FAIL_DEPTH = 0.0f; 53e5c31af7Sopenharmony_cistatic const int FAIL_STENCIL = 1; 54e5c31af7Sopenharmony_cistatic const float UNIT_SQUARE[16] = 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_ci 1.0f, 1.0f, 0.05f, 1.0f, 57e5c31af7Sopenharmony_ci 1.0f, -1.0f, 0.05f, 1.0f, 58e5c31af7Sopenharmony_ci -1.0f, 1.0f, 0.05f, 1.0f, 59e5c31af7Sopenharmony_ci -1.0f, -1.0f, 0.05f, 1.0f 60e5c31af7Sopenharmony_ci}; 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_cienum CaseType 63e5c31af7Sopenharmony_ci{ 64e5c31af7Sopenharmony_ci CASE_WRITE_DEPTH, 65e5c31af7Sopenharmony_ci CASE_WRITE_STENCIL, 66e5c31af7Sopenharmony_ci CASE_CLEAR_COLOR, 67e5c31af7Sopenharmony_ci CASE_CLEAR_DEPTH, 68e5c31af7Sopenharmony_ci CASE_CLEAR_STENCIL 69e5c31af7Sopenharmony_ci}; 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_cienum CaseOptions 72e5c31af7Sopenharmony_ci{ 73e5c31af7Sopenharmony_ci CASEOPTION_FBO = (1 << 0), 74e5c31af7Sopenharmony_ci CASEOPTION_SCISSOR = (1 << 1) 75e5c31af7Sopenharmony_ci}; 76e5c31af7Sopenharmony_ci 77e5c31af7Sopenharmony_ciclass RasterizerDiscardCase : public TestCase 78e5c31af7Sopenharmony_ci{ 79e5c31af7Sopenharmony_cipublic: 80e5c31af7Sopenharmony_ci RasterizerDiscardCase (Context& context, const char* name, const char* description, int numPrimitives, CaseType caseType, deUint32 caseOptions, deUint32 drawMode = GL_TRIANGLES); 81e5c31af7Sopenharmony_ci ~RasterizerDiscardCase (void); 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ci void init (void); 84e5c31af7Sopenharmony_ci void deinit (void); 85e5c31af7Sopenharmony_ci IterateResult iterate (void); 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ciprivate: 88e5c31af7Sopenharmony_ci RasterizerDiscardCase (const RasterizerDiscardCase& other); 89e5c31af7Sopenharmony_ci RasterizerDiscardCase& operator= (const RasterizerDiscardCase& other); 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci void setupFramebufferObject (void); 92e5c31af7Sopenharmony_ci void deleteFramebufferObject (void); 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ci int m_numPrimitives; 95e5c31af7Sopenharmony_ci CaseType m_caseType; 96e5c31af7Sopenharmony_ci deUint32 m_caseOptions; 97e5c31af7Sopenharmony_ci deUint32 m_drawMode; 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci glu::ShaderProgram* m_program; 100e5c31af7Sopenharmony_ci deUint32 m_fbo; 101e5c31af7Sopenharmony_ci deUint32 m_colorBuf; 102e5c31af7Sopenharmony_ci deUint32 m_depthStencilBuf; 103e5c31af7Sopenharmony_ci int m_iterNdx; 104e5c31af7Sopenharmony_ci de::Random m_rnd; 105e5c31af7Sopenharmony_ci}; 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ciRasterizerDiscardCase::RasterizerDiscardCase (Context& context, const char* name, const char* description, int numPrimitives, CaseType caseType, deUint32 caseOptions, deUint32 drawMode) 108e5c31af7Sopenharmony_ci : TestCase (context, name, description) 109e5c31af7Sopenharmony_ci , m_numPrimitives (numPrimitives) 110e5c31af7Sopenharmony_ci , m_caseType (caseType) 111e5c31af7Sopenharmony_ci , m_caseOptions (caseOptions) 112e5c31af7Sopenharmony_ci , m_drawMode (drawMode) 113e5c31af7Sopenharmony_ci , m_program (DE_NULL) 114e5c31af7Sopenharmony_ci , m_fbo (0) 115e5c31af7Sopenharmony_ci , m_colorBuf (0) 116e5c31af7Sopenharmony_ci , m_depthStencilBuf (0) 117e5c31af7Sopenharmony_ci , m_iterNdx (0) 118e5c31af7Sopenharmony_ci , m_rnd (deStringHash(name)) 119e5c31af7Sopenharmony_ci{ 120e5c31af7Sopenharmony_ci} 121e5c31af7Sopenharmony_ci 122e5c31af7Sopenharmony_ciRasterizerDiscardCase::~RasterizerDiscardCase (void) 123e5c31af7Sopenharmony_ci{ 124e5c31af7Sopenharmony_ci RasterizerDiscardCase::deinit(); 125e5c31af7Sopenharmony_ci} 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_cistatic void generateVertices (std::vector<float>& dst, int numPrimitives, de::Random& rnd, deUint32 drawMode) 128e5c31af7Sopenharmony_ci{ 129e5c31af7Sopenharmony_ci int numVertices; 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci switch (drawMode) 132e5c31af7Sopenharmony_ci { 133e5c31af7Sopenharmony_ci case GL_POINTS: numVertices = numPrimitives; break; 134e5c31af7Sopenharmony_ci case GL_LINES: numVertices = 2*numPrimitives; break; 135e5c31af7Sopenharmony_ci case GL_LINE_STRIP: numVertices = numPrimitives+1; break; 136e5c31af7Sopenharmony_ci case GL_LINE_LOOP: numVertices = numPrimitives+2; break; 137e5c31af7Sopenharmony_ci case GL_TRIANGLES: numVertices = 3*numPrimitives; break; 138e5c31af7Sopenharmony_ci case GL_TRIANGLE_STRIP: numVertices = numPrimitives+2; break; 139e5c31af7Sopenharmony_ci case GL_TRIANGLE_FAN: numVertices = numPrimitives+2; break; 140e5c31af7Sopenharmony_ci default: 141e5c31af7Sopenharmony_ci DE_ASSERT(false); 142e5c31af7Sopenharmony_ci numVertices = 0; 143e5c31af7Sopenharmony_ci } 144e5c31af7Sopenharmony_ci 145e5c31af7Sopenharmony_ci dst.resize(numVertices * 4); 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_ci for (int i = 0; i < numVertices; i++) 148e5c31af7Sopenharmony_ci { 149e5c31af7Sopenharmony_ci dst[i*4 ] = rnd.getFloat(-1.0f, 1.0f); // x 150e5c31af7Sopenharmony_ci dst[i*4 + 1] = rnd.getFloat(-1.0f, 1.0f); // y 151e5c31af7Sopenharmony_ci dst[i*4 + 2] = rnd.getFloat( 0.1f, 0.9f); // z 152e5c31af7Sopenharmony_ci dst[i*4 + 3] = 1.0f; // w 153e5c31af7Sopenharmony_ci } 154e5c31af7Sopenharmony_ci} 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_civoid RasterizerDiscardCase::setupFramebufferObject (void) 157e5c31af7Sopenharmony_ci{ 158e5c31af7Sopenharmony_ci int width = m_context.getRenderTarget().getWidth(); 159e5c31af7Sopenharmony_ci int height = m_context.getRenderTarget().getHeight(); 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_ci // Create framebuffer object 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci glGenFramebuffers (1, &m_fbo); // FBO 164e5c31af7Sopenharmony_ci glGenTextures (1, &m_colorBuf); // Color attachment 165e5c31af7Sopenharmony_ci glGenRenderbuffers (1, &m_depthStencilBuf); // Depth and stencil attachments 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ci // Create color texture 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci glBindTexture (GL_TEXTURE_2D, m_colorBuf); 170e5c31af7Sopenharmony_ci glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 171e5c31af7Sopenharmony_ci glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 172e5c31af7Sopenharmony_ci glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 173e5c31af7Sopenharmony_ci glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 174e5c31af7Sopenharmony_ci glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci // Create depth and stencil buffers 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci glBindRenderbuffer (GL_RENDERBUFFER, m_depthStencilBuf); 179e5c31af7Sopenharmony_ci glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci // Attach texture and buffers to FBO 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_ci glBindFramebuffer (GL_FRAMEBUFFER, m_fbo); 184e5c31af7Sopenharmony_ci glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuf, 0); 185e5c31af7Sopenharmony_ci glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuf); 186e5c31af7Sopenharmony_ci glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuf); 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci deUint32 fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_ci if (fboStatus == GL_FRAMEBUFFER_UNSUPPORTED) 191e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Framebuffer unsupported", "", __FILE__, __LINE__); 192e5c31af7Sopenharmony_ci else if (fboStatus != GL_FRAMEBUFFER_COMPLETE) 193e5c31af7Sopenharmony_ci throw tcu::TestError("Failed to create framebuffer object", "", __FILE__, __LINE__); 194e5c31af7Sopenharmony_ci} 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_civoid RasterizerDiscardCase::deleteFramebufferObject (void) 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci glDeleteTextures (1, &m_colorBuf); // Color attachment 199e5c31af7Sopenharmony_ci glDeleteRenderbuffers (1, &m_depthStencilBuf); // Depth and stencil attachments 200e5c31af7Sopenharmony_ci glDeleteFramebuffers (1, &m_fbo); // FBO 201e5c31af7Sopenharmony_ci} 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_civoid RasterizerDiscardCase::init (void) 204e5c31af7Sopenharmony_ci{ 205e5c31af7Sopenharmony_ci const char* vertShaderSource = 206e5c31af7Sopenharmony_ci "#version 300 es\n" 207e5c31af7Sopenharmony_ci "layout(location = 0) in mediump vec4 a_position;\n" 208e5c31af7Sopenharmony_ci "\n" 209e5c31af7Sopenharmony_ci "void main (void)\n" 210e5c31af7Sopenharmony_ci "{\n" 211e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 212e5c31af7Sopenharmony_ci "}\n"; 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_ci const char* fragShaderSource = 215e5c31af7Sopenharmony_ci "#version 300 es\n" 216e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 dEQP_FragColor;\n" 217e5c31af7Sopenharmony_ci "uniform mediump vec4 u_color;\n" 218e5c31af7Sopenharmony_ci "\n" 219e5c31af7Sopenharmony_ci "void main (void)\n" 220e5c31af7Sopenharmony_ci "{\n" 221e5c31af7Sopenharmony_ci " mediump float depth_gradient = gl_FragCoord.z;\n" 222e5c31af7Sopenharmony_ci " mediump float bias = 0.1;\n" 223e5c31af7Sopenharmony_ci " dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1.0);\n" 224e5c31af7Sopenharmony_ci "}\n"; 225e5c31af7Sopenharmony_ci 226e5c31af7Sopenharmony_ci DE_ASSERT(!m_program); 227e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource)); 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci if (!m_program->isOk()) 230e5c31af7Sopenharmony_ci { 231e5c31af7Sopenharmony_ci m_testCtx.getLog() << *m_program; 232e5c31af7Sopenharmony_ci TCU_FAIL("Failed to compile shader program"); 233e5c31af7Sopenharmony_ci } 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Initialize test result to pass. 236e5c31af7Sopenharmony_ci GLU_CHECK_MSG ("Case initialization finished"); 237e5c31af7Sopenharmony_ci} 238e5c31af7Sopenharmony_ci 239e5c31af7Sopenharmony_civoid RasterizerDiscardCase::deinit (void) 240e5c31af7Sopenharmony_ci{ 241e5c31af7Sopenharmony_ci deleteFramebufferObject(); 242e5c31af7Sopenharmony_ci delete m_program; 243e5c31af7Sopenharmony_ci m_program = DE_NULL; 244e5c31af7Sopenharmony_ci} 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ciRasterizerDiscardCase::IterateResult RasterizerDiscardCase::iterate (void) 247e5c31af7Sopenharmony_ci{ 248e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 249e5c31af7Sopenharmony_ci const tcu::RenderTarget& renderTarget = m_context.getRenderTarget(); 250e5c31af7Sopenharmony_ci deUint32 colorUnif = glGetUniformLocation(m_program->getProgram(), "u_color"); 251e5c31af7Sopenharmony_ci bool failColorFound = false; 252e5c31af7Sopenharmony_ci bool passColorFound = false; 253e5c31af7Sopenharmony_ci std::vector<float> vertices; 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_ci std::string header = "Case iteration " + de::toString(m_iterNdx+1) + " / " + de::toString(NUM_CASE_ITERATIONS); 256e5c31af7Sopenharmony_ci log << TestLog::Section(header, header); 257e5c31af7Sopenharmony_ci 258e5c31af7Sopenharmony_ci DE_ASSERT (m_program); 259e5c31af7Sopenharmony_ci 260e5c31af7Sopenharmony_ci // Create and bind FBO if needed 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_ci if (m_caseOptions & CASEOPTION_FBO) 263e5c31af7Sopenharmony_ci { 264e5c31af7Sopenharmony_ci try 265e5c31af7Sopenharmony_ci { 266e5c31af7Sopenharmony_ci setupFramebufferObject(); 267e5c31af7Sopenharmony_ci } 268e5c31af7Sopenharmony_ci catch (tcu::NotSupportedError& e) 269e5c31af7Sopenharmony_ci { 270e5c31af7Sopenharmony_ci log << TestLog::Message << "ERROR: " << e.what() << "." << TestLog::EndMessage << TestLog::EndSection; 271e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported"); 272e5c31af7Sopenharmony_ci return STOP; 273e5c31af7Sopenharmony_ci } 274e5c31af7Sopenharmony_ci catch (tcu::InternalError& e) 275e5c31af7Sopenharmony_ci { 276e5c31af7Sopenharmony_ci log << TestLog::Message << "ERROR: " << e.what() << "." << TestLog::EndMessage << TestLog::EndSection; 277e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); 278e5c31af7Sopenharmony_ci return STOP; 279e5c31af7Sopenharmony_ci } 280e5c31af7Sopenharmony_ci } 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci if (m_caseOptions & CASEOPTION_SCISSOR) 283e5c31af7Sopenharmony_ci { 284e5c31af7Sopenharmony_ci glEnable (GL_SCISSOR_TEST); 285e5c31af7Sopenharmony_ci glScissor(0, 0, renderTarget.getWidth(), renderTarget.getHeight()); 286e5c31af7Sopenharmony_ci log << TestLog::Message << "Scissor test enabled: glScissor(0, 0, " << renderTarget.getWidth() << ", " << renderTarget.getHeight() << ")" << TestLog::EndMessage; 287e5c31af7Sopenharmony_ci } 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci glUseProgram (m_program->getProgram()); 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci glEnable (GL_DEPTH_TEST); 292e5c31af7Sopenharmony_ci glDepthRangef (0.0f, 1.0f); 293e5c31af7Sopenharmony_ci glDepthFunc (GL_LEQUAL); 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_ci glEnable (GL_STENCIL_TEST); 296e5c31af7Sopenharmony_ci glStencilFunc (GL_NOTEQUAL, 1, 0xFF); 297e5c31af7Sopenharmony_ci glStencilOp (GL_REPLACE, GL_KEEP, GL_KEEP); 298e5c31af7Sopenharmony_ci 299e5c31af7Sopenharmony_ci glClearColor (PASS_COLOR_BLUE.x(), PASS_COLOR_BLUE.y(), PASS_COLOR_BLUE.z(), PASS_COLOR_BLUE.w()); 300e5c31af7Sopenharmony_ci glClearDepthf (1.0f); 301e5c31af7Sopenharmony_ci glClearStencil (0); 302e5c31af7Sopenharmony_ci glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_ci // Generate vertices 305e5c31af7Sopenharmony_ci 306e5c31af7Sopenharmony_ci glEnableVertexAttribArray (0); 307e5c31af7Sopenharmony_ci generateVertices (vertices, m_numPrimitives, m_rnd, m_drawMode); 308e5c31af7Sopenharmony_ci glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, &vertices[0]); 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_ci // Clear color to black for depth and stencil clear cases 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci if (m_caseType == CASE_CLEAR_DEPTH || m_caseType == CASE_CLEAR_STENCIL) 313e5c31af7Sopenharmony_ci { 314e5c31af7Sopenharmony_ci glClearColor (BLACK_COLOR.x(), BLACK_COLOR.y(), BLACK_COLOR.z(), BLACK_COLOR.w()); 315e5c31af7Sopenharmony_ci glClear (GL_COLOR_BUFFER_BIT); 316e5c31af7Sopenharmony_ci } 317e5c31af7Sopenharmony_ci 318e5c31af7Sopenharmony_ci // Set fail values for color, depth and stencil 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_ci glUniform4f (colorUnif, FAIL_COLOR_RED.x(), FAIL_COLOR_RED.y(), FAIL_COLOR_RED.z(), FAIL_COLOR_RED.w()); 321e5c31af7Sopenharmony_ci glClearColor (FAIL_COLOR_RED.x(), FAIL_COLOR_RED.y(), FAIL_COLOR_RED.z(), FAIL_COLOR_RED.w()); 322e5c31af7Sopenharmony_ci glClearDepthf (FAIL_DEPTH); 323e5c31af7Sopenharmony_ci glClearStencil (FAIL_STENCIL); 324e5c31af7Sopenharmony_ci 325e5c31af7Sopenharmony_ci // Enable rasterizer discard 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci glEnable (GL_RASTERIZER_DISCARD); 328e5c31af7Sopenharmony_ci GLU_CHECK_MSG ("Rasterizer discard enabled"); 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ci // Do to-be-discarded primitive draws and buffer clears 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci switch (m_caseType) 333e5c31af7Sopenharmony_ci { 334e5c31af7Sopenharmony_ci case CASE_WRITE_DEPTH: glDrawArrays(m_drawMode, 0, (int)vertices.size() / 4); break; 335e5c31af7Sopenharmony_ci case CASE_WRITE_STENCIL: glDrawArrays(m_drawMode, 0, (int)vertices.size() / 4); break; 336e5c31af7Sopenharmony_ci case CASE_CLEAR_COLOR: (m_caseOptions & CASEOPTION_FBO) ? glClearBufferfv(GL_COLOR, 0, &FAIL_COLOR_RED[0]) : glClear(GL_COLOR_BUFFER_BIT); break; 337e5c31af7Sopenharmony_ci case CASE_CLEAR_DEPTH: (m_caseOptions & CASEOPTION_FBO) ? glClearBufferfv(GL_DEPTH, 0, &FAIL_DEPTH) : glClear(GL_DEPTH_BUFFER_BIT); break; 338e5c31af7Sopenharmony_ci case CASE_CLEAR_STENCIL: (m_caseOptions & CASEOPTION_FBO) ? glClearBufferiv(GL_STENCIL, 0, &FAIL_STENCIL) : glClear(GL_STENCIL_BUFFER_BIT); break; 339e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 340e5c31af7Sopenharmony_ci } 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_ci // Disable rasterizer discard 343e5c31af7Sopenharmony_ci 344e5c31af7Sopenharmony_ci glDisable (GL_RASTERIZER_DISCARD); 345e5c31af7Sopenharmony_ci GLU_CHECK_MSG ("Rasterizer discard disabled"); 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci if (m_caseType == CASE_WRITE_STENCIL) 348e5c31af7Sopenharmony_ci { 349e5c31af7Sopenharmony_ci if ((m_caseOptions & CASEOPTION_FBO) || m_context.getRenderTarget().getStencilBits() > 0) 350e5c31af7Sopenharmony_ci { 351e5c31af7Sopenharmony_ci // Draw a full-screen square that colors all pixels red if they have stencil value 1. 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, &UNIT_SQUARE[0]); 354e5c31af7Sopenharmony_ci glStencilFunc (GL_EQUAL, 1, 0xFF); 355e5c31af7Sopenharmony_ci glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); 356e5c31af7Sopenharmony_ci } 357e5c31af7Sopenharmony_ci // \note If no stencil buffers are present and test is rendering to default framebuffer, test will always pass. 358e5c31af7Sopenharmony_ci } 359e5c31af7Sopenharmony_ci else if (m_caseType == CASE_CLEAR_DEPTH || m_caseType == CASE_CLEAR_STENCIL) 360e5c31af7Sopenharmony_ci { 361e5c31af7Sopenharmony_ci // Draw pass-indicating primitives for depth and stencil clear cases 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci glUniform4f (colorUnif, PASS_COLOR_BLUE.x(), PASS_COLOR_BLUE.y(), PASS_COLOR_BLUE.z(), PASS_COLOR_BLUE.w()); 364e5c31af7Sopenharmony_ci glDrawArrays (m_drawMode, 0, (int)vertices.size() / 4); 365e5c31af7Sopenharmony_ci } 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci glFinish (); 368e5c31af7Sopenharmony_ci glDisable (GL_STENCIL_TEST); 369e5c31af7Sopenharmony_ci glDisable (GL_DEPTH_TEST); 370e5c31af7Sopenharmony_ci glDisable (GL_SCISSOR_TEST); 371e5c31af7Sopenharmony_ci 372e5c31af7Sopenharmony_ci // Read and check pixel data 373e5c31af7Sopenharmony_ci 374e5c31af7Sopenharmony_ci tcu::Surface pixels(renderTarget.getWidth(), renderTarget.getHeight()); 375e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, pixels.getAccess()); 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci { 378e5c31af7Sopenharmony_ci int width = pixels.getWidth(); 379e5c31af7Sopenharmony_ci int height = pixels.getHeight(); 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci for (int y = 0; y < height; y++) 382e5c31af7Sopenharmony_ci { 383e5c31af7Sopenharmony_ci for (int x = 0; x < width; x++) 384e5c31af7Sopenharmony_ci { 385e5c31af7Sopenharmony_ci if (pixels.getPixel(x,y).getBlue() != 0) 386e5c31af7Sopenharmony_ci passColorFound = true; 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci if (pixels.getPixel(x,y).getRed() != 0) 389e5c31af7Sopenharmony_ci { 390e5c31af7Sopenharmony_ci failColorFound = true; 391e5c31af7Sopenharmony_ci break; 392e5c31af7Sopenharmony_ci } 393e5c31af7Sopenharmony_ci } 394e5c31af7Sopenharmony_ci if (failColorFound) break; 395e5c31af7Sopenharmony_ci } 396e5c31af7Sopenharmony_ci } 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ci // Delete FBO if created 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci if (m_caseOptions & CASEOPTION_FBO) 401e5c31af7Sopenharmony_ci deleteFramebufferObject(); 402e5c31af7Sopenharmony_ci 403e5c31af7Sopenharmony_ci // Evaluate test result 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_ci bool testOk = passColorFound && !failColorFound; 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_ci if (!testOk) 408e5c31af7Sopenharmony_ci log << TestLog::Image ("Result image", "Result image", pixels); 409e5c31af7Sopenharmony_ci log << TestLog::Message << "Test result: " << (testOk ? "Passed!" : "Failed!") << TestLog::EndMessage; 410e5c31af7Sopenharmony_ci 411e5c31af7Sopenharmony_ci if (!testOk) 412e5c31af7Sopenharmony_ci { 413e5c31af7Sopenharmony_ci log << TestLog::Message << "Primitive or buffer clear was not discarded." << TestLog::EndMessage << TestLog::EndSection; 414e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 415e5c31af7Sopenharmony_ci return STOP; 416e5c31af7Sopenharmony_ci } 417e5c31af7Sopenharmony_ci 418e5c31af7Sopenharmony_ci log << TestLog::Message << "Primitive or buffer clear was discarded correctly." << TestLog::EndMessage << TestLog::EndSection; 419e5c31af7Sopenharmony_ci 420e5c31af7Sopenharmony_ci return (++m_iterNdx < NUM_CASE_ITERATIONS) ? CONTINUE : STOP; 421e5c31af7Sopenharmony_ci} 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ciRasterizerDiscardTests::RasterizerDiscardTests (Context& context) 424e5c31af7Sopenharmony_ci : TestCaseGroup(context, "rasterizer_discard", "Rasterizer Discard Tests") 425e5c31af7Sopenharmony_ci{ 426e5c31af7Sopenharmony_ci} 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ciRasterizerDiscardTests::~RasterizerDiscardTests (void) 429e5c31af7Sopenharmony_ci{ 430e5c31af7Sopenharmony_ci} 431e5c31af7Sopenharmony_ci 432e5c31af7Sopenharmony_civoid RasterizerDiscardTests::init (void) 433e5c31af7Sopenharmony_ci{ 434e5c31af7Sopenharmony_ci tcu::TestCaseGroup* basic = new tcu::TestCaseGroup(m_testCtx, "basic", "Rasterizer discard test for default framebuffer"); 435e5c31af7Sopenharmony_ci tcu::TestCaseGroup* scissor = new tcu::TestCaseGroup(m_testCtx, "scissor", "Rasterizer discard test for default framebuffer with scissor test enabled"); 436e5c31af7Sopenharmony_ci tcu::TestCaseGroup* fbo = new tcu::TestCaseGroup(m_testCtx, "fbo", "Rasterizer discard test for framebuffer object"); 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_ci addChild(basic); 439e5c31af7Sopenharmony_ci addChild(scissor); 440e5c31af7Sopenharmony_ci addChild(fbo); 441e5c31af7Sopenharmony_ci 442e5c31af7Sopenharmony_ci // Default framebuffer cases 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_points", "points", 4, CASE_WRITE_DEPTH, 0, GL_POINTS)); 445e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines", "lines", 4, CASE_WRITE_DEPTH, 0, GL_LINES)); 446e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip", "line_strip", 4, CASE_WRITE_DEPTH, 0, GL_LINE_STRIP)); 447e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop", "line_loop", 4, CASE_WRITE_DEPTH, 0, GL_LINE_LOOP)); 448e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles", "triangles", 4, CASE_WRITE_DEPTH, 0, GL_TRIANGLES)); 449e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip", "triangle_strip", 4, CASE_WRITE_DEPTH, 0, GL_TRIANGLE_STRIP)); 450e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan", "triangle_fan", 4, CASE_WRITE_DEPTH, 0, GL_TRIANGLE_FAN)); 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points", "points", 4, CASE_WRITE_STENCIL, 0, GL_POINTS)); 453e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines", "lines", 4, CASE_WRITE_STENCIL, 0, GL_LINES)); 454e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip", "line_strip", 4, CASE_WRITE_STENCIL, 0, GL_LINE_STRIP)); 455e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop", "line_loop", 4, CASE_WRITE_STENCIL, 0, GL_LINE_LOOP)); 456e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles", "triangles", 4, CASE_WRITE_STENCIL, 0, GL_TRIANGLES)); 457e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip", "triangle_strip", 4, CASE_WRITE_STENCIL, 0, GL_TRIANGLE_STRIP)); 458e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan", "triangle_fan", 4, CASE_WRITE_STENCIL, 0, GL_TRIANGLE_FAN)); 459e5c31af7Sopenharmony_ci 460e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "clear_color", "clear_color", 4, CASE_CLEAR_COLOR, 0)); 461e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "clear_depth", "clear_depth", 4, CASE_CLEAR_DEPTH, 0)); 462e5c31af7Sopenharmony_ci basic->addChild(new RasterizerDiscardCase(m_context, "clear_stencil", "clear_stencil", 4, CASE_CLEAR_STENCIL, 0)); 463e5c31af7Sopenharmony_ci 464e5c31af7Sopenharmony_ci // Default framebuffer cases with scissor test enabled 465e5c31af7Sopenharmony_ci 466e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_points", "points", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_POINTS)); 467e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines", "lines", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_LINES)); 468e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip", "line_strip", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_LINE_STRIP)); 469e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop", "line_loop", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_LINE_LOOP)); 470e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles", "triangles", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_TRIANGLES)); 471e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip", "triangle_strip", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_TRIANGLE_STRIP)); 472e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan", "triangle_fan", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_TRIANGLE_FAN)); 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points", "points", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_POINTS)); 475e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines", "lines", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_LINES)); 476e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip", "line_strip", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_LINE_STRIP)); 477e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop", "line_loop", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_LINE_LOOP)); 478e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles", "triangles", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_TRIANGLES)); 479e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip", "triangle_strip", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_TRIANGLE_STRIP)); 480e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan", "triangle_fan", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_TRIANGLE_FAN)); 481e5c31af7Sopenharmony_ci 482e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "clear_color", "clear_color", 4, CASE_CLEAR_COLOR, CASEOPTION_SCISSOR)); 483e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "clear_depth", "clear_depth", 4, CASE_CLEAR_DEPTH, CASEOPTION_SCISSOR)); 484e5c31af7Sopenharmony_ci scissor->addChild(new RasterizerDiscardCase(m_context, "clear_stencil", "clear_stencil", 4, CASE_CLEAR_STENCIL, CASEOPTION_SCISSOR)); 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci // FBO cases 487e5c31af7Sopenharmony_ci 488e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_points", "points", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_POINTS)); 489e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines", "lines", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_LINES)); 490e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip", "line_strip", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_LINE_STRIP)); 491e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop", "line_loop", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_LINE_LOOP)); 492e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles", "triangles", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_TRIANGLES)); 493e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip", "triangle_strip", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_TRIANGLE_STRIP)); 494e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan", "triangle_fan", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_TRIANGLE_FAN)); 495e5c31af7Sopenharmony_ci 496e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points", "points", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_POINTS)); 497e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines", "lines", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_LINES)); 498e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip", "line_strip", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_LINE_STRIP)); 499e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop", "line_loop", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_LINE_LOOP)); 500e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles", "triangles", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_TRIANGLES)); 501e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip", "triangle_strip", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_TRIANGLE_STRIP)); 502e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan", "triangle_fan", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_TRIANGLE_FAN)); 503e5c31af7Sopenharmony_ci 504e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "clear_color", "clear_color", 4, CASE_CLEAR_COLOR, CASEOPTION_FBO)); 505e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "clear_depth", "clear_depth", 4, CASE_CLEAR_DEPTH, CASEOPTION_FBO)); 506e5c31af7Sopenharmony_ci fbo->addChild(new RasterizerDiscardCase(m_context, "clear_stencil", "clear_stencil", 4, CASE_CLEAR_STENCIL, CASEOPTION_FBO)); 507e5c31af7Sopenharmony_ci} 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci} // Functional 510e5c31af7Sopenharmony_ci} // gles3 511e5c31af7Sopenharmony_ci} // deqp 512