/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 3.0 Module * ------------------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Rasterizer discard tests. *//*--------------------------------------------------------------------*/ #include "es3fRasterizerDiscardTests.hpp" #include "tcuTestLog.hpp" #include "tcuVector.hpp" #include "tcuSurface.hpp" #include "tcuRenderTarget.hpp" #include "gluShaderProgram.hpp" #include "gluPixelTransfer.hpp" #include "deRandom.hpp" #include "deStringUtil.hpp" #include "deString.h" #include "glw.h" using tcu::Vec4; using tcu::TestLog; namespace deqp { namespace gles3 { namespace Functional { static const int NUM_CASE_ITERATIONS = 1; static const Vec4 FAIL_COLOR_RED = Vec4(1.0f, 0.0f, 0.0f, 1.0f); static const Vec4 PASS_COLOR_BLUE = Vec4(0.0f, 0.0f, 0.5f, 1.0f); static const Vec4 BLACK_COLOR = Vec4(0.0f, 0.0f, 0.0f, 1.0f); static const float FAIL_DEPTH = 0.0f; static const int FAIL_STENCIL = 1; static const float UNIT_SQUARE[16] = { 1.0f, 1.0f, 0.05f, 1.0f, 1.0f, -1.0f, 0.05f, 1.0f, -1.0f, 1.0f, 0.05f, 1.0f, -1.0f, -1.0f, 0.05f, 1.0f }; enum CaseType { CASE_WRITE_DEPTH, CASE_WRITE_STENCIL, CASE_CLEAR_COLOR, CASE_CLEAR_DEPTH, CASE_CLEAR_STENCIL }; enum CaseOptions { CASEOPTION_FBO = (1 << 0), CASEOPTION_SCISSOR = (1 << 1) }; class RasterizerDiscardCase : public TestCase { public: RasterizerDiscardCase (Context& context, const char* name, const char* description, int numPrimitives, CaseType caseType, deUint32 caseOptions, deUint32 drawMode = GL_TRIANGLES); ~RasterizerDiscardCase (void); void init (void); void deinit (void); IterateResult iterate (void); private: RasterizerDiscardCase (const RasterizerDiscardCase& other); RasterizerDiscardCase& operator= (const RasterizerDiscardCase& other); void setupFramebufferObject (void); void deleteFramebufferObject (void); int m_numPrimitives; CaseType m_caseType; deUint32 m_caseOptions; deUint32 m_drawMode; glu::ShaderProgram* m_program; deUint32 m_fbo; deUint32 m_colorBuf; deUint32 m_depthStencilBuf; int m_iterNdx; de::Random m_rnd; }; RasterizerDiscardCase::RasterizerDiscardCase (Context& context, const char* name, const char* description, int numPrimitives, CaseType caseType, deUint32 caseOptions, deUint32 drawMode) : TestCase (context, name, description) , m_numPrimitives (numPrimitives) , m_caseType (caseType) , m_caseOptions (caseOptions) , m_drawMode (drawMode) , m_program (DE_NULL) , m_fbo (0) , m_colorBuf (0) , m_depthStencilBuf (0) , m_iterNdx (0) , m_rnd (deStringHash(name)) { } RasterizerDiscardCase::~RasterizerDiscardCase (void) { RasterizerDiscardCase::deinit(); } static void generateVertices (std::vector& dst, int numPrimitives, de::Random& rnd, deUint32 drawMode) { int numVertices; switch (drawMode) { case GL_POINTS: numVertices = numPrimitives; break; case GL_LINES: numVertices = 2*numPrimitives; break; case GL_LINE_STRIP: numVertices = numPrimitives+1; break; case GL_LINE_LOOP: numVertices = numPrimitives+2; break; case GL_TRIANGLES: numVertices = 3*numPrimitives; break; case GL_TRIANGLE_STRIP: numVertices = numPrimitives+2; break; case GL_TRIANGLE_FAN: numVertices = numPrimitives+2; break; default: DE_ASSERT(false); numVertices = 0; } dst.resize(numVertices * 4); for (int i = 0; i < numVertices; i++) { dst[i*4 ] = rnd.getFloat(-1.0f, 1.0f); // x dst[i*4 + 1] = rnd.getFloat(-1.0f, 1.0f); // y dst[i*4 + 2] = rnd.getFloat( 0.1f, 0.9f); // z dst[i*4 + 3] = 1.0f; // w } } void RasterizerDiscardCase::setupFramebufferObject (void) { int width = m_context.getRenderTarget().getWidth(); int height = m_context.getRenderTarget().getHeight(); // Create framebuffer object glGenFramebuffers (1, &m_fbo); // FBO glGenTextures (1, &m_colorBuf); // Color attachment glGenRenderbuffers (1, &m_depthStencilBuf); // Depth and stencil attachments // Create color texture glBindTexture (GL_TEXTURE_2D, m_colorBuf); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); // Create depth and stencil buffers glBindRenderbuffer (GL_RENDERBUFFER, m_depthStencilBuf); glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); // Attach texture and buffers to FBO glBindFramebuffer (GL_FRAMEBUFFER, m_fbo); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuf, 0); glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuf); glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuf); deUint32 fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (fboStatus == GL_FRAMEBUFFER_UNSUPPORTED) throw tcu::NotSupportedError("Framebuffer unsupported", "", __FILE__, __LINE__); else if (fboStatus != GL_FRAMEBUFFER_COMPLETE) throw tcu::TestError("Failed to create framebuffer object", "", __FILE__, __LINE__); } void RasterizerDiscardCase::deleteFramebufferObject (void) { glDeleteTextures (1, &m_colorBuf); // Color attachment glDeleteRenderbuffers (1, &m_depthStencilBuf); // Depth and stencil attachments glDeleteFramebuffers (1, &m_fbo); // FBO } void RasterizerDiscardCase::init (void) { const char* vertShaderSource = "#version 300 es\n" "layout(location = 0) in mediump vec4 a_position;\n" "\n" "void main (void)\n" "{\n" " gl_Position = a_position;\n" "}\n"; const char* fragShaderSource = "#version 300 es\n" "layout(location = 0) out mediump vec4 dEQP_FragColor;\n" "uniform mediump vec4 u_color;\n" "\n" "void main (void)\n" "{\n" " mediump float depth_gradient = gl_FragCoord.z;\n" " mediump float bias = 0.1;\n" " dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1.0);\n" "}\n"; DE_ASSERT(!m_program); m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource)); if (!m_program->isOk()) { m_testCtx.getLog() << *m_program; TCU_FAIL("Failed to compile shader program"); } m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Initialize test result to pass. GLU_CHECK_MSG ("Case initialization finished"); } void RasterizerDiscardCase::deinit (void) { deleteFramebufferObject(); delete m_program; m_program = DE_NULL; } RasterizerDiscardCase::IterateResult RasterizerDiscardCase::iterate (void) { TestLog& log = m_testCtx.getLog(); const tcu::RenderTarget& renderTarget = m_context.getRenderTarget(); deUint32 colorUnif = glGetUniformLocation(m_program->getProgram(), "u_color"); bool failColorFound = false; bool passColorFound = false; std::vector vertices; std::string header = "Case iteration " + de::toString(m_iterNdx+1) + " / " + de::toString(NUM_CASE_ITERATIONS); log << TestLog::Section(header, header); DE_ASSERT (m_program); // Create and bind FBO if needed if (m_caseOptions & CASEOPTION_FBO) { try { setupFramebufferObject(); } catch (tcu::NotSupportedError& e) { log << TestLog::Message << "ERROR: " << e.what() << "." << TestLog::EndMessage << TestLog::EndSection; m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported"); return STOP; } catch (tcu::InternalError& e) { log << TestLog::Message << "ERROR: " << e.what() << "." << TestLog::EndMessage << TestLog::EndSection; m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); return STOP; } } if (m_caseOptions & CASEOPTION_SCISSOR) { glEnable (GL_SCISSOR_TEST); glScissor(0, 0, renderTarget.getWidth(), renderTarget.getHeight()); log << TestLog::Message << "Scissor test enabled: glScissor(0, 0, " << renderTarget.getWidth() << ", " << renderTarget.getHeight() << ")" << TestLog::EndMessage; } glUseProgram (m_program->getProgram()); glEnable (GL_DEPTH_TEST); glDepthRangef (0.0f, 1.0f); glDepthFunc (GL_LEQUAL); glEnable (GL_STENCIL_TEST); glStencilFunc (GL_NOTEQUAL, 1, 0xFF); glStencilOp (GL_REPLACE, GL_KEEP, GL_KEEP); glClearColor (PASS_COLOR_BLUE.x(), PASS_COLOR_BLUE.y(), PASS_COLOR_BLUE.z(), PASS_COLOR_BLUE.w()); glClearDepthf (1.0f); glClearStencil (0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Generate vertices glEnableVertexAttribArray (0); generateVertices (vertices, m_numPrimitives, m_rnd, m_drawMode); glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, &vertices[0]); // Clear color to black for depth and stencil clear cases if (m_caseType == CASE_CLEAR_DEPTH || m_caseType == CASE_CLEAR_STENCIL) { glClearColor (BLACK_COLOR.x(), BLACK_COLOR.y(), BLACK_COLOR.z(), BLACK_COLOR.w()); glClear (GL_COLOR_BUFFER_BIT); } // Set fail values for color, depth and stencil glUniform4f (colorUnif, FAIL_COLOR_RED.x(), FAIL_COLOR_RED.y(), FAIL_COLOR_RED.z(), FAIL_COLOR_RED.w()); glClearColor (FAIL_COLOR_RED.x(), FAIL_COLOR_RED.y(), FAIL_COLOR_RED.z(), FAIL_COLOR_RED.w()); glClearDepthf (FAIL_DEPTH); glClearStencil (FAIL_STENCIL); // Enable rasterizer discard glEnable (GL_RASTERIZER_DISCARD); GLU_CHECK_MSG ("Rasterizer discard enabled"); // Do to-be-discarded primitive draws and buffer clears switch (m_caseType) { case CASE_WRITE_DEPTH: glDrawArrays(m_drawMode, 0, (int)vertices.size() / 4); break; case CASE_WRITE_STENCIL: glDrawArrays(m_drawMode, 0, (int)vertices.size() / 4); break; case CASE_CLEAR_COLOR: (m_caseOptions & CASEOPTION_FBO) ? glClearBufferfv(GL_COLOR, 0, &FAIL_COLOR_RED[0]) : glClear(GL_COLOR_BUFFER_BIT); break; case CASE_CLEAR_DEPTH: (m_caseOptions & CASEOPTION_FBO) ? glClearBufferfv(GL_DEPTH, 0, &FAIL_DEPTH) : glClear(GL_DEPTH_BUFFER_BIT); break; case CASE_CLEAR_STENCIL: (m_caseOptions & CASEOPTION_FBO) ? glClearBufferiv(GL_STENCIL, 0, &FAIL_STENCIL) : glClear(GL_STENCIL_BUFFER_BIT); break; default: DE_ASSERT(false); } // Disable rasterizer discard glDisable (GL_RASTERIZER_DISCARD); GLU_CHECK_MSG ("Rasterizer discard disabled"); if (m_caseType == CASE_WRITE_STENCIL) { if ((m_caseOptions & CASEOPTION_FBO) || m_context.getRenderTarget().getStencilBits() > 0) { // Draw a full-screen square that colors all pixels red if they have stencil value 1. glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, &UNIT_SQUARE[0]); glStencilFunc (GL_EQUAL, 1, 0xFF); glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); } // \note If no stencil buffers are present and test is rendering to default framebuffer, test will always pass. } else if (m_caseType == CASE_CLEAR_DEPTH || m_caseType == CASE_CLEAR_STENCIL) { // Draw pass-indicating primitives for depth and stencil clear cases glUniform4f (colorUnif, PASS_COLOR_BLUE.x(), PASS_COLOR_BLUE.y(), PASS_COLOR_BLUE.z(), PASS_COLOR_BLUE.w()); glDrawArrays (m_drawMode, 0, (int)vertices.size() / 4); } glFinish (); glDisable (GL_STENCIL_TEST); glDisable (GL_DEPTH_TEST); glDisable (GL_SCISSOR_TEST); // Read and check pixel data tcu::Surface pixels(renderTarget.getWidth(), renderTarget.getHeight()); glu::readPixels(m_context.getRenderContext(), 0, 0, pixels.getAccess()); { int width = pixels.getWidth(); int height = pixels.getHeight(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (pixels.getPixel(x,y).getBlue() != 0) passColorFound = true; if (pixels.getPixel(x,y).getRed() != 0) { failColorFound = true; break; } } if (failColorFound) break; } } // Delete FBO if created if (m_caseOptions & CASEOPTION_FBO) deleteFramebufferObject(); // Evaluate test result bool testOk = passColorFound && !failColorFound; if (!testOk) log << TestLog::Image ("Result image", "Result image", pixels); log << TestLog::Message << "Test result: " << (testOk ? "Passed!" : "Failed!") << TestLog::EndMessage; if (!testOk) { log << TestLog::Message << "Primitive or buffer clear was not discarded." << TestLog::EndMessage << TestLog::EndSection; m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); return STOP; } log << TestLog::Message << "Primitive or buffer clear was discarded correctly." << TestLog::EndMessage << TestLog::EndSection; return (++m_iterNdx < NUM_CASE_ITERATIONS) ? CONTINUE : STOP; } RasterizerDiscardTests::RasterizerDiscardTests (Context& context) : TestCaseGroup(context, "rasterizer_discard", "Rasterizer Discard Tests") { } RasterizerDiscardTests::~RasterizerDiscardTests (void) { } void RasterizerDiscardTests::init (void) { tcu::TestCaseGroup* basic = new tcu::TestCaseGroup(m_testCtx, "basic", "Rasterizer discard test for default framebuffer"); tcu::TestCaseGroup* scissor = new tcu::TestCaseGroup(m_testCtx, "scissor", "Rasterizer discard test for default framebuffer with scissor test enabled"); tcu::TestCaseGroup* fbo = new tcu::TestCaseGroup(m_testCtx, "fbo", "Rasterizer discard test for framebuffer object"); addChild(basic); addChild(scissor); addChild(fbo); // Default framebuffer cases basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_points", "points", 4, CASE_WRITE_DEPTH, 0, GL_POINTS)); basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines", "lines", 4, CASE_WRITE_DEPTH, 0, GL_LINES)); basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip", "line_strip", 4, CASE_WRITE_DEPTH, 0, GL_LINE_STRIP)); basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop", "line_loop", 4, CASE_WRITE_DEPTH, 0, GL_LINE_LOOP)); basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles", "triangles", 4, CASE_WRITE_DEPTH, 0, GL_TRIANGLES)); basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip", "triangle_strip", 4, CASE_WRITE_DEPTH, 0, GL_TRIANGLE_STRIP)); basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan", "triangle_fan", 4, CASE_WRITE_DEPTH, 0, GL_TRIANGLE_FAN)); basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points", "points", 4, CASE_WRITE_STENCIL, 0, GL_POINTS)); basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines", "lines", 4, CASE_WRITE_STENCIL, 0, GL_LINES)); basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip", "line_strip", 4, CASE_WRITE_STENCIL, 0, GL_LINE_STRIP)); basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop", "line_loop", 4, CASE_WRITE_STENCIL, 0, GL_LINE_LOOP)); basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles", "triangles", 4, CASE_WRITE_STENCIL, 0, GL_TRIANGLES)); basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip", "triangle_strip", 4, CASE_WRITE_STENCIL, 0, GL_TRIANGLE_STRIP)); basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan", "triangle_fan", 4, CASE_WRITE_STENCIL, 0, GL_TRIANGLE_FAN)); basic->addChild(new RasterizerDiscardCase(m_context, "clear_color", "clear_color", 4, CASE_CLEAR_COLOR, 0)); basic->addChild(new RasterizerDiscardCase(m_context, "clear_depth", "clear_depth", 4, CASE_CLEAR_DEPTH, 0)); basic->addChild(new RasterizerDiscardCase(m_context, "clear_stencil", "clear_stencil", 4, CASE_CLEAR_STENCIL, 0)); // Default framebuffer cases with scissor test enabled scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_points", "points", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_POINTS)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines", "lines", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_LINES)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip", "line_strip", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_LINE_STRIP)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop", "line_loop", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_LINE_LOOP)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles", "triangles", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_TRIANGLES)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip", "triangle_strip", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_TRIANGLE_STRIP)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan", "triangle_fan", 4, CASE_WRITE_DEPTH, CASEOPTION_SCISSOR, GL_TRIANGLE_FAN)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points", "points", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_POINTS)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines", "lines", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_LINES)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip", "line_strip", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_LINE_STRIP)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop", "line_loop", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_LINE_LOOP)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles", "triangles", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_TRIANGLES)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip", "triangle_strip", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_TRIANGLE_STRIP)); scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan", "triangle_fan", 4, CASE_WRITE_STENCIL, CASEOPTION_SCISSOR, GL_TRIANGLE_FAN)); scissor->addChild(new RasterizerDiscardCase(m_context, "clear_color", "clear_color", 4, CASE_CLEAR_COLOR, CASEOPTION_SCISSOR)); scissor->addChild(new RasterizerDiscardCase(m_context, "clear_depth", "clear_depth", 4, CASE_CLEAR_DEPTH, CASEOPTION_SCISSOR)); scissor->addChild(new RasterizerDiscardCase(m_context, "clear_stencil", "clear_stencil", 4, CASE_CLEAR_STENCIL, CASEOPTION_SCISSOR)); // FBO cases fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_points", "points", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_POINTS)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines", "lines", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_LINES)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip", "line_strip", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_LINE_STRIP)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop", "line_loop", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_LINE_LOOP)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles", "triangles", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_TRIANGLES)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip", "triangle_strip", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_TRIANGLE_STRIP)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan", "triangle_fan", 4, CASE_WRITE_DEPTH, CASEOPTION_FBO, GL_TRIANGLE_FAN)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points", "points", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_POINTS)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines", "lines", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_LINES)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip", "line_strip", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_LINE_STRIP)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop", "line_loop", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_LINE_LOOP)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles", "triangles", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_TRIANGLES)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip", "triangle_strip", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_TRIANGLE_STRIP)); fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan", "triangle_fan", 4, CASE_WRITE_STENCIL, CASEOPTION_FBO, GL_TRIANGLE_FAN)); fbo->addChild(new RasterizerDiscardCase(m_context, "clear_color", "clear_color", 4, CASE_CLEAR_COLOR, CASEOPTION_FBO)); fbo->addChild(new RasterizerDiscardCase(m_context, "clear_depth", "clear_depth", 4, CASE_CLEAR_DEPTH, CASEOPTION_FBO)); fbo->addChild(new RasterizerDiscardCase(m_context, "clear_stencil", "clear_stencil", 4, CASE_CLEAR_STENCIL, CASEOPTION_FBO)); } } // Functional } // gles3 } // deqp