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 Polygon offset tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es3fPolygonOffsetTests.hpp" 25e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 26e5c31af7Sopenharmony_ci#include "deRandom.hpp" 27e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 28e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 29e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 30e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 31e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 32e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 33e5c31af7Sopenharmony_ci#include "glwDefs.hpp" 34e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 35e5c31af7Sopenharmony_ci#include "tcuTestContext.hpp" 36e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 37e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 38e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 39e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp" 40e5c31af7Sopenharmony_ci#include "rrRenderer.hpp" 41e5c31af7Sopenharmony_ci#include "rrFragmentOperations.hpp" 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_ci#include "sglrReferenceContext.hpp" 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ci#include <string> 46e5c31af7Sopenharmony_ci#include <limits> 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ciusing namespace glw; // GLint and other GL types 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_cinamespace deqp 51e5c31af7Sopenharmony_ci{ 52e5c31af7Sopenharmony_cinamespace gles3 53e5c31af7Sopenharmony_ci{ 54e5c31af7Sopenharmony_cinamespace Functional 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_cinamespace 57e5c31af7Sopenharmony_ci{ 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ciconst char* s_shaderSourceVertex = "#version 300 es\n" 60e5c31af7Sopenharmony_ci "in highp vec4 a_position;\n" 61e5c31af7Sopenharmony_ci "in highp vec4 a_color;\n" 62e5c31af7Sopenharmony_ci "out highp vec4 v_color;\n" 63e5c31af7Sopenharmony_ci "void main (void)\n" 64e5c31af7Sopenharmony_ci "{\n" 65e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 66e5c31af7Sopenharmony_ci " v_color = a_color;\n" 67e5c31af7Sopenharmony_ci "}\n"; 68e5c31af7Sopenharmony_ciconst char* s_shaderSourceFragment = "#version 300 es\n" 69e5c31af7Sopenharmony_ci "in highp vec4 v_color;\n" 70e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 fragColor;" 71e5c31af7Sopenharmony_ci "void main (void)\n" 72e5c31af7Sopenharmony_ci "{\n" 73e5c31af7Sopenharmony_ci " fragColor = v_color;\n" 74e5c31af7Sopenharmony_ci "}\n"; 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_cistatic const tcu::Vec4 MASK_COLOR_OK = tcu::Vec4(0.0f, 0.1f, 0.0f, 1.0f); 77e5c31af7Sopenharmony_cistatic const tcu::Vec4 MASK_COLOR_DEV = tcu::Vec4(0.8f, 0.5f, 0.0f, 1.0f); 78e5c31af7Sopenharmony_cistatic const tcu::Vec4 MASK_COLOR_FAIL = tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f); 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_ciinline bool compareThreshold (const tcu::IVec4& a, const tcu::IVec4& b, const tcu::IVec4& threshold) 81e5c31af7Sopenharmony_ci{ 82e5c31af7Sopenharmony_ci return tcu::boolAll(tcu::lessThanEqual(tcu::abs(a - b), threshold)); 83e5c31af7Sopenharmony_ci} 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 86e5c31af7Sopenharmony_ci* \brief Pixelwise comparison of two images. 87e5c31af7Sopenharmony_ci* \note copied & modified from glsRasterizationTests 88e5c31af7Sopenharmony_ci* 89e5c31af7Sopenharmony_ci* Kernel radius defines maximum allowed distance. If radius is 0, only 90e5c31af7Sopenharmony_ci* perfect match is allowed. Radius of 1 gives a 3x3 kernel. 91e5c31af7Sopenharmony_ci* 92e5c31af7Sopenharmony_ci* Return values: -1 = Perfect match 93e5c31af7Sopenharmony_ci* 0 = Deviation within kernel 94e5c31af7Sopenharmony_ci* >0 = Number of faulty pixels 95e5c31af7Sopenharmony_ci*//*--------------------------------------------------------------------*/ 96e5c31af7Sopenharmony_ciint compareImages (tcu::TestLog& log, glu::RenderContext& renderCtx, const tcu::ConstPixelBufferAccess& test, const tcu::ConstPixelBufferAccess& ref, const tcu::PixelBufferAccess& diffMask, int radius) 97e5c31af7Sopenharmony_ci{ 98e5c31af7Sopenharmony_ci const int height = test.getHeight(); 99e5c31af7Sopenharmony_ci const int width = test.getWidth(); 100e5c31af7Sopenharmony_ci const int colorThreshold = 128; 101e5c31af7Sopenharmony_ci const tcu::RGBA formatThreshold = renderCtx.getRenderTarget().getPixelFormat().getColorThreshold(); 102e5c31af7Sopenharmony_ci const tcu::IVec4 threshold = tcu::IVec4(colorThreshold, colorThreshold, colorThreshold, formatThreshold.getAlpha() > 0 ? colorThreshold : 0) 103e5c31af7Sopenharmony_ci + tcu::IVec4(formatThreshold.getRed(), formatThreshold.getGreen(), formatThreshold.getBlue(), formatThreshold.getAlpha()); 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_ci int faultyPixels = 0; 106e5c31af7Sopenharmony_ci int compareFailed = -1; 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_ci tcu::clear(diffMask, MASK_COLOR_OK); 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci for (int y = 0; y < height; y++) 111e5c31af7Sopenharmony_ci { 112e5c31af7Sopenharmony_ci for (int x = 0; x < width; x++) 113e5c31af7Sopenharmony_ci { 114e5c31af7Sopenharmony_ci const tcu::IVec4 cRef = ref.getPixelInt(x, y); 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci // Pixelwise match, no deviation or fault 117e5c31af7Sopenharmony_ci { 118e5c31af7Sopenharmony_ci const tcu::IVec4 cTest = test.getPixelInt(x, y); 119e5c31af7Sopenharmony_ci if (compareThreshold(cRef, cTest, threshold)) 120e5c31af7Sopenharmony_ci continue; 121e5c31af7Sopenharmony_ci } 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci // If not, search within kernel radius 124e5c31af7Sopenharmony_ci { 125e5c31af7Sopenharmony_ci const int kYmin = deMax32(y - radius, 0); 126e5c31af7Sopenharmony_ci const int kYmax = deMin32(y + radius, height-1); 127e5c31af7Sopenharmony_ci const int kXmin = deMax32(x - radius, 0); 128e5c31af7Sopenharmony_ci const int kXmax = deMin32(x + radius, width-1); 129e5c31af7Sopenharmony_ci bool found = false; 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci for (int kY = kYmin; kY <= kYmax; kY++) 132e5c31af7Sopenharmony_ci for (int kX = kXmin; kX <= kXmax; kX++) 133e5c31af7Sopenharmony_ci { 134e5c31af7Sopenharmony_ci const tcu::IVec4 cTest = test.getPixelInt(kX, kY); 135e5c31af7Sopenharmony_ci if (compareThreshold(cRef, cTest, threshold)) 136e5c31af7Sopenharmony_ci found = true; 137e5c31af7Sopenharmony_ci } 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ci if (found) // The pixel is deviating if the color is found inside the kernel 140e5c31af7Sopenharmony_ci { 141e5c31af7Sopenharmony_ci diffMask.setPixel(MASK_COLOR_DEV, x, y); 142e5c31af7Sopenharmony_ci if (compareFailed == -1) 143e5c31af7Sopenharmony_ci compareFailed = 0; 144e5c31af7Sopenharmony_ci continue; 145e5c31af7Sopenharmony_ci } 146e5c31af7Sopenharmony_ci } 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci diffMask.setPixel(MASK_COLOR_FAIL, x, y); 149e5c31af7Sopenharmony_ci faultyPixels++; // The pixel is faulty if the color is not found 150e5c31af7Sopenharmony_ci compareFailed = 1; 151e5c31af7Sopenharmony_ci } 152e5c31af7Sopenharmony_ci } 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << faultyPixels << " faulty pixel(s) found." << tcu::TestLog::EndMessage; 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci return (compareFailed == 1 ? faultyPixels : compareFailed); 157e5c31af7Sopenharmony_ci} 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_civoid verifyImages (tcu::TestLog& log, tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const tcu::ConstPixelBufferAccess& testImage, const tcu::ConstPixelBufferAccess& referenceImage) 160e5c31af7Sopenharmony_ci{ 161e5c31af7Sopenharmony_ci using tcu::TestLog; 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci const int kernelRadius = 1; 164e5c31af7Sopenharmony_ci const int faultyPixelLimit = 20; 165e5c31af7Sopenharmony_ci int faultyPixels; 166e5c31af7Sopenharmony_ci tcu::Surface diffMask (testImage.getWidth(), testImage.getHeight()); 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_ci faultyPixels = compareImages(log, renderCtx, referenceImage, testImage, diffMask.getAccess(), kernelRadius); 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci if (faultyPixels > faultyPixelLimit) 171e5c31af7Sopenharmony_ci { 172e5c31af7Sopenharmony_ci log << TestLog::ImageSet("Images", "Image comparison"); 173e5c31af7Sopenharmony_ci log << TestLog::Image("Test image", "Test image", testImage); 174e5c31af7Sopenharmony_ci log << TestLog::Image("Reference image", "Reference image", referenceImage); 175e5c31af7Sopenharmony_ci log << TestLog::Image("Difference mask", "Difference mask", diffMask.getAccess()); 176e5c31af7Sopenharmony_ci log << TestLog::EndImageSet; 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage; 179e5c31af7Sopenharmony_ci testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels"); 180e5c31af7Sopenharmony_ci } 181e5c31af7Sopenharmony_ci} 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_civoid verifyError (tcu::TestContext& testCtx, const glw::Functions& gl, GLenum expected) 184e5c31af7Sopenharmony_ci{ 185e5c31af7Sopenharmony_ci deUint32 got = gl.getError(); 186e5c31af7Sopenharmony_ci if (got != expected) 187e5c31af7Sopenharmony_ci { 188e5c31af7Sopenharmony_ci testCtx.getLog() << tcu::TestLog::Message << "// ERROR: expected " << glu::getErrorStr(expected) << "; got " << glu::getErrorStr(got) << tcu::TestLog::EndMessage; 189e5c31af7Sopenharmony_ci if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 190e5c31af7Sopenharmony_ci testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid error"); 191e5c31af7Sopenharmony_ci } 192e5c31af7Sopenharmony_ci} 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_civoid checkCanvasSize (int width, int height, int minWidth, int minHeight) 195e5c31af7Sopenharmony_ci{ 196e5c31af7Sopenharmony_ci if (width < minWidth || height < minHeight) 197e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(std::string("Render context size must be at least ") + de::toString(minWidth) + "x" + de::toString(minWidth)); 198e5c31af7Sopenharmony_ci} 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ciclass PositionColorShader : public sglr::ShaderProgram 201e5c31af7Sopenharmony_ci{ 202e5c31af7Sopenharmony_cipublic: 203e5c31af7Sopenharmony_ci enum 204e5c31af7Sopenharmony_ci { 205e5c31af7Sopenharmony_ci VARYINGLOC_COLOR = 0 206e5c31af7Sopenharmony_ci }; 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_ci PositionColorShader (void); 209e5c31af7Sopenharmony_ci void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const; 210e5c31af7Sopenharmony_ci void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const; 211e5c31af7Sopenharmony_ci}; 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ciPositionColorShader::PositionColorShader (void) 214e5c31af7Sopenharmony_ci : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration() 215e5c31af7Sopenharmony_ci << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT) 216e5c31af7Sopenharmony_ci << sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT) 217e5c31af7Sopenharmony_ci << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT) 218e5c31af7Sopenharmony_ci << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT) 219e5c31af7Sopenharmony_ci << sglr::pdec::VertexSource(s_shaderSourceVertex) 220e5c31af7Sopenharmony_ci << sglr::pdec::FragmentSource(s_shaderSourceFragment)) 221e5c31af7Sopenharmony_ci{ 222e5c31af7Sopenharmony_ci} 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_civoid PositionColorShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 225e5c31af7Sopenharmony_ci{ 226e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 227e5c31af7Sopenharmony_ci { 228e5c31af7Sopenharmony_ci const int positionAttrLoc = 0; 229e5c31af7Sopenharmony_ci const int colorAttrLoc = 1; 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci rr::VertexPacket& packet = *packets[packetNdx]; 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci // Transform to position 234e5c31af7Sopenharmony_ci packet.position = rr::readVertexAttribFloat(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx); 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci // Pass color to FS 237e5c31af7Sopenharmony_ci packet.outputs[VARYINGLOC_COLOR] = rr::readVertexAttribFloat(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx); 238e5c31af7Sopenharmony_ci } 239e5c31af7Sopenharmony_ci} 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_civoid PositionColorShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 242e5c31af7Sopenharmony_ci{ 243e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 244e5c31af7Sopenharmony_ci { 245e5c31af7Sopenharmony_ci rr::FragmentPacket& packet = packets[packetNdx]; 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 248e5c31af7Sopenharmony_ci rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readTriangleVarying<float>(packet, context, VARYINGLOC_COLOR, fragNdx)); 249e5c31af7Sopenharmony_ci } 250e5c31af7Sopenharmony_ci} 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci// PolygonOffsetTestCase 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_ciclass PolygonOffsetTestCase : public TestCase 255e5c31af7Sopenharmony_ci{ 256e5c31af7Sopenharmony_cipublic: 257e5c31af7Sopenharmony_ci PolygonOffsetTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName, int canvasSize); 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci virtual void testPolygonOffset (void) = DE_NULL; 260e5c31af7Sopenharmony_ci IterateResult iterate (void); 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_ciprotected: 263e5c31af7Sopenharmony_ci const GLenum m_internalFormat; 264e5c31af7Sopenharmony_ci const char* m_internalFormatName; 265e5c31af7Sopenharmony_ci const int m_targetSize; 266e5c31af7Sopenharmony_ci}; 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ciPolygonOffsetTestCase::PolygonOffsetTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName, int canvasSize) 269e5c31af7Sopenharmony_ci : TestCase (context, name, description) 270e5c31af7Sopenharmony_ci , m_internalFormat (internalFormat) 271e5c31af7Sopenharmony_ci , m_internalFormatName (internalFormatName) 272e5c31af7Sopenharmony_ci , m_targetSize (canvasSize) 273e5c31af7Sopenharmony_ci{ 274e5c31af7Sopenharmony_ci} 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ciPolygonOffsetTestCase::IterateResult PolygonOffsetTestCase::iterate (void) 277e5c31af7Sopenharmony_ci{ 278e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 279e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Testing PolygonOffset with " << m_internalFormatName << " depth buffer." << tcu::TestLog::EndMessage; 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_ci if (m_internalFormat == 0) 282e5c31af7Sopenharmony_ci { 283e5c31af7Sopenharmony_ci // default framebuffer 284e5c31af7Sopenharmony_ci const int width = m_context.getRenderTarget().getWidth(); 285e5c31af7Sopenharmony_ci const int height = m_context.getRenderTarget().getHeight(); 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_ci checkCanvasSize(width, height, m_targetSize, m_targetSize); 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci if (m_context.getRenderTarget().getDepthBits() == 0) 290e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("polygon offset tests require depth buffer"); 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_ci testPolygonOffset(); 293e5c31af7Sopenharmony_ci } 294e5c31af7Sopenharmony_ci else 295e5c31af7Sopenharmony_ci { 296e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci // framebuffer object 299e5c31af7Sopenharmony_ci GLuint colorRboId = 0; 300e5c31af7Sopenharmony_ci GLuint depthRboId = 0; 301e5c31af7Sopenharmony_ci GLuint fboId = 0; 302e5c31af7Sopenharmony_ci bool fboComplete; 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_ci gl.genRenderbuffers(1, &colorRboId); 305e5c31af7Sopenharmony_ci gl.bindRenderbuffer(GL_RENDERBUFFER, colorRboId); 306e5c31af7Sopenharmony_ci gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, m_targetSize, m_targetSize); 307e5c31af7Sopenharmony_ci verifyError(m_testCtx, gl, GL_NO_ERROR); 308e5c31af7Sopenharmony_ci 309e5c31af7Sopenharmony_ci gl.genRenderbuffers(1, &depthRboId); 310e5c31af7Sopenharmony_ci gl.bindRenderbuffer(GL_RENDERBUFFER, depthRboId); 311e5c31af7Sopenharmony_ci gl.renderbufferStorage(GL_RENDERBUFFER, m_internalFormat, m_targetSize, m_targetSize); 312e5c31af7Sopenharmony_ci verifyError(m_testCtx, gl, GL_NO_ERROR); 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &fboId); 315e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, fboId); 316e5c31af7Sopenharmony_ci gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRboId); 317e5c31af7Sopenharmony_ci gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRboId); 318e5c31af7Sopenharmony_ci verifyError(m_testCtx, gl, GL_NO_ERROR); 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_ci fboComplete = gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_ci if (fboComplete) 323e5c31af7Sopenharmony_ci testPolygonOffset(); 324e5c31af7Sopenharmony_ci 325e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &fboId); 326e5c31af7Sopenharmony_ci gl.deleteRenderbuffers(1, &depthRboId); 327e5c31af7Sopenharmony_ci gl.deleteRenderbuffers(1, &colorRboId); 328e5c31af7Sopenharmony_ci 329e5c31af7Sopenharmony_ci if (!fboComplete) 330e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("could not create fbo for testing."); 331e5c31af7Sopenharmony_ci } 332e5c31af7Sopenharmony_ci 333e5c31af7Sopenharmony_ci return STOP; 334e5c31af7Sopenharmony_ci} 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci// UsageTestCase 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ciclass UsageTestCase : public PolygonOffsetTestCase 339e5c31af7Sopenharmony_ci{ 340e5c31af7Sopenharmony_cipublic: 341e5c31af7Sopenharmony_ci UsageTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName); 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci void testPolygonOffset (void); 344e5c31af7Sopenharmony_ci}; 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ciUsageTestCase::UsageTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName) 347e5c31af7Sopenharmony_ci : PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200) 348e5c31af7Sopenharmony_ci{ 349e5c31af7Sopenharmony_ci} 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_civoid UsageTestCase::testPolygonOffset (void) 352e5c31af7Sopenharmony_ci{ 353e5c31af7Sopenharmony_ci using tcu::TestLog; 354e5c31af7Sopenharmony_ci 355e5c31af7Sopenharmony_ci const tcu::Vec4 triangle[] = 356e5c31af7Sopenharmony_ci { 357e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, 0, 1), 358e5c31af7Sopenharmony_ci tcu::Vec4( 1, 1, 0, 1), 359e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, 0, 1), 360e5c31af7Sopenharmony_ci }; 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci tcu::TestLog& log = m_testCtx.getLog(); 363e5c31af7Sopenharmony_ci tcu::Surface testImage (m_targetSize, m_targetSize); 364e5c31af7Sopenharmony_ci tcu::Surface referenceImage (m_targetSize, m_targetSize); 365e5c31af7Sopenharmony_ci int subpixelBits = 0; 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci // render test image 368e5c31af7Sopenharmony_ci { 369e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 370e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment)); 371e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(program.getProgram(), "a_position"); 372e5c31af7Sopenharmony_ci const GLint colorLoc = gl.getAttribLocation(program.getProgram(), "a_color"); 373e5c31af7Sopenharmony_ci 374e5c31af7Sopenharmony_ci if (!program.isOk()) 375e5c31af7Sopenharmony_ci { 376e5c31af7Sopenharmony_ci log << program; 377e5c31af7Sopenharmony_ci TCU_FAIL("Shader compile failed."); 378e5c31af7Sopenharmony_ci } 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_ci gl.clearColor (0, 0, 0, 1); 381e5c31af7Sopenharmony_ci gl.clearDepthf (1.0f); 382e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 383e5c31af7Sopenharmony_ci gl.viewport (0, 0, m_targetSize, m_targetSize); 384e5c31af7Sopenharmony_ci gl.useProgram (program.getProgram()); 385e5c31af7Sopenharmony_ci gl.enable (GL_DEPTH_TEST); 386e5c31af7Sopenharmony_ci gl.depthFunc (GL_LEQUAL); // make test pass if polygon offset doesn't do anything. It has its own test case. This test is only for to detect always-on cases. 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci log << TestLog::Message << "DepthFunc = GL_LEQUAL" << TestLog::EndMessage; 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (positionLoc); 391e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle); 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_ci //draw back (offset disabled) 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw bottom-right. Color = White.\tState: PolygonOffset(0, -2), POLYGON_OFFSET_FILL disabled." << TestLog::EndMessage; 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci gl.polygonOffset (0, -2); 398e5c31af7Sopenharmony_ci gl.disable (GL_POLYGON_OFFSET_FILL); 399e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); 400e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 401e5c31af7Sopenharmony_ci 402e5c31af7Sopenharmony_ci //draw front 403e5c31af7Sopenharmony_ci 404e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw bottom-right. Color = Red.\tState: PolygonOffset(0, -1), POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage; 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci gl.polygonOffset (0, -1); 407e5c31af7Sopenharmony_ci gl.enable (GL_POLYGON_OFFSET_FILL); 408e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 0.0f, 0.0f, 1.0f); 409e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 410e5c31af7Sopenharmony_ci 411e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (positionLoc); 412e5c31af7Sopenharmony_ci gl.useProgram (0); 413e5c31af7Sopenharmony_ci gl.finish (); 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess()); 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ci gl.getIntegerv(GL_SUBPIXEL_BITS, &subpixelBits); 418e5c31af7Sopenharmony_ci } 419e5c31af7Sopenharmony_ci 420e5c31af7Sopenharmony_ci // render reference image 421e5c31af7Sopenharmony_ci { 422e5c31af7Sopenharmony_ci rr::Renderer referenceRenderer; 423e5c31af7Sopenharmony_ci rr::VertexAttrib attribs[2]; 424e5c31af7Sopenharmony_ci rr::RenderState state((rr::ViewportState)(rr::WindowRectangle(0, 0, m_targetSize, m_targetSize)), subpixelBits); 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ci PositionColorShader program; 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ci attribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT; 429e5c31af7Sopenharmony_ci attribs[0].size = 4; 430e5c31af7Sopenharmony_ci attribs[0].stride = 0; 431e5c31af7Sopenharmony_ci attribs[0].instanceDivisor = 0; 432e5c31af7Sopenharmony_ci attribs[0].pointer = triangle; 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_ci attribs[1].type = rr::VERTEXATTRIBTYPE_DONT_CARE; 435e5c31af7Sopenharmony_ci attribs[1].generic = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); 436e5c31af7Sopenharmony_ci 437e5c31af7Sopenharmony_ci tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 438e5c31af7Sopenharmony_ci 439e5c31af7Sopenharmony_ci log << TestLog::Message << "Expecting: Bottom-right = Red." << TestLog::EndMessage; 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ci referenceRenderer.draw( 442e5c31af7Sopenharmony_ci rr::DrawCommand( 443e5c31af7Sopenharmony_ci state, 444e5c31af7Sopenharmony_ci rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())), 445e5c31af7Sopenharmony_ci rr::Program(program.getVertexShader(), program.getFragmentShader()), 446e5c31af7Sopenharmony_ci 2, 447e5c31af7Sopenharmony_ci attribs, 448e5c31af7Sopenharmony_ci rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0))); 449e5c31af7Sopenharmony_ci } 450e5c31af7Sopenharmony_ci 451e5c31af7Sopenharmony_ci // compare 452e5c31af7Sopenharmony_ci verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess()); 453e5c31af7Sopenharmony_ci} 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci// UsageDisplacementTestCase 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ciclass UsageDisplacementTestCase : public PolygonOffsetTestCase 458e5c31af7Sopenharmony_ci{ 459e5c31af7Sopenharmony_cipublic: 460e5c31af7Sopenharmony_ci UsageDisplacementTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName); 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_ciprivate: 463e5c31af7Sopenharmony_ci tcu::Vec4 genRandomVec4 (de::Random& rnd) const; 464e5c31af7Sopenharmony_ci void testPolygonOffset (void); 465e5c31af7Sopenharmony_ci}; 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ciUsageDisplacementTestCase::UsageDisplacementTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName) 468e5c31af7Sopenharmony_ci : PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200) 469e5c31af7Sopenharmony_ci{ 470e5c31af7Sopenharmony_ci} 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_citcu::Vec4 UsageDisplacementTestCase::genRandomVec4 (de::Random& rnd) const 473e5c31af7Sopenharmony_ci{ 474e5c31af7Sopenharmony_ci // generater triangle endpoint with following properties 475e5c31af7Sopenharmony_ci // 1) it will not be clipped 476e5c31af7Sopenharmony_ci // 2) it is not near either far or near plane to prevent possible problems related to depth clamping 477e5c31af7Sopenharmony_ci // => w >= 1.0 and z in (-0.9, 0.9) range 478e5c31af7Sopenharmony_ci tcu::Vec4 retVal; 479e5c31af7Sopenharmony_ci 480e5c31af7Sopenharmony_ci retVal.x() = rnd.getFloat(-1, 1); 481e5c31af7Sopenharmony_ci retVal.y() = rnd.getFloat(-1, 1); 482e5c31af7Sopenharmony_ci retVal.z() = 0.5f; 483e5c31af7Sopenharmony_ci retVal.w() = 1.0f + rnd.getFloat(); 484e5c31af7Sopenharmony_ci 485e5c31af7Sopenharmony_ci return retVal; 486e5c31af7Sopenharmony_ci} 487e5c31af7Sopenharmony_ci 488e5c31af7Sopenharmony_civoid UsageDisplacementTestCase::testPolygonOffset (void) 489e5c31af7Sopenharmony_ci{ 490e5c31af7Sopenharmony_ci using tcu::TestLog; 491e5c31af7Sopenharmony_ci 492e5c31af7Sopenharmony_ci de::Random rnd (0xdec0de); 493e5c31af7Sopenharmony_ci tcu::TestLog& log = m_testCtx.getLog(); 494e5c31af7Sopenharmony_ci tcu::Surface testImage (m_targetSize, m_targetSize); 495e5c31af7Sopenharmony_ci tcu::Surface referenceImage (m_targetSize, m_targetSize); 496e5c31af7Sopenharmony_ci 497e5c31af7Sopenharmony_ci // render test image 498e5c31af7Sopenharmony_ci { 499e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 500e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment)); 501e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(program.getProgram(), "a_position"); 502e5c31af7Sopenharmony_ci const GLint colorLoc = gl.getAttribLocation(program.getProgram(), "a_color"); 503e5c31af7Sopenharmony_ci const int numIterations = 40; 504e5c31af7Sopenharmony_ci 505e5c31af7Sopenharmony_ci if (!program.isOk()) 506e5c31af7Sopenharmony_ci { 507e5c31af7Sopenharmony_ci log << program; 508e5c31af7Sopenharmony_ci TCU_FAIL("Shader compile failed."); 509e5c31af7Sopenharmony_ci } 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci gl.clearColor (0, 0, 0, 1); 512e5c31af7Sopenharmony_ci gl.clearDepthf (1.0f); 513e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 514e5c31af7Sopenharmony_ci gl.viewport (0, 0, m_targetSize, m_targetSize); 515e5c31af7Sopenharmony_ci gl.useProgram (program.getProgram()); 516e5c31af7Sopenharmony_ci gl.enable (GL_DEPTH_TEST); 517e5c31af7Sopenharmony_ci gl.enable (GL_POLYGON_OFFSET_FILL); 518e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (positionLoc); 519e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 0.0f, 1.0f, 0.0f, 1.0f); 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_ci log << TestLog::Message << "Framebuffer cleared, clear color = Black." << TestLog::EndMessage; 522e5c31af7Sopenharmony_ci log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage; 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci // draw colorless (mask = 0,0,0) triangle at random* location, set offset and render green triangle with depthfunc = equal 525e5c31af7Sopenharmony_ci // *) w >= 1.0 and z in (-1, 1) range 526e5c31af7Sopenharmony_ci for (int iterationNdx = 0; iterationNdx < numIterations; ++iterationNdx) 527e5c31af7Sopenharmony_ci { 528e5c31af7Sopenharmony_ci const bool offsetDirection = rnd.getBool(); 529e5c31af7Sopenharmony_ci const float offset = offsetDirection ? -1.0f : 1.0f; 530e5c31af7Sopenharmony_ci tcu::Vec4 triangle[3]; 531e5c31af7Sopenharmony_ci 532e5c31af7Sopenharmony_ci for (int vertexNdx = 0; vertexNdx < DE_LENGTH_OF_ARRAY(triangle); ++vertexNdx) 533e5c31af7Sopenharmony_ci triangle[vertexNdx] = genRandomVec4(rnd); 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle); 536e5c31af7Sopenharmony_ci 537e5c31af7Sopenharmony_ci log << TestLog::Message << "Setup triangle with random coordinates:" << TestLog::EndMessage; 538e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangle); ++ndx) 539e5c31af7Sopenharmony_ci log << TestLog::Message 540e5c31af7Sopenharmony_ci << "\tx=" << triangle[ndx].x() 541e5c31af7Sopenharmony_ci << "\ty=" << triangle[ndx].y() 542e5c31af7Sopenharmony_ci << "\tz=" << triangle[ndx].z() 543e5c31af7Sopenharmony_ci << "\tw=" << triangle[ndx].w() 544e5c31af7Sopenharmony_ci << TestLog::EndMessage; 545e5c31af7Sopenharmony_ci 546e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw colorless triangle.\tState: DepthFunc = GL_ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage; 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci gl.depthFunc (GL_ALWAYS); 549e5c31af7Sopenharmony_ci gl.polygonOffset (0, 0); 550e5c31af7Sopenharmony_ci gl.colorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 551e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_ci // all fragments should have different Z => DepthFunc == GL_EQUAL fails with every fragment 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw green triangle.\tState: DepthFunc = GL_EQUAL, PolygonOffset(0, " << offset << ")." << TestLog::EndMessage; 556e5c31af7Sopenharmony_ci 557e5c31af7Sopenharmony_ci gl.depthFunc (GL_EQUAL); 558e5c31af7Sopenharmony_ci gl.polygonOffset (0, offset); 559e5c31af7Sopenharmony_ci gl.colorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 560e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 561e5c31af7Sopenharmony_ci 562e5c31af7Sopenharmony_ci log << TestLog::Message << TestLog::EndMessage; // empty line for clarity 563e5c31af7Sopenharmony_ci } 564e5c31af7Sopenharmony_ci 565e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (positionLoc); 566e5c31af7Sopenharmony_ci gl.useProgram (0); 567e5c31af7Sopenharmony_ci gl.finish (); 568e5c31af7Sopenharmony_ci 569e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess()); 570e5c31af7Sopenharmony_ci } 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_ci // render reference image 573e5c31af7Sopenharmony_ci log << TestLog::Message << "Expecting black framebuffer." << TestLog::EndMessage; 574e5c31af7Sopenharmony_ci tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ci // compare 577e5c31af7Sopenharmony_ci verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess()); 578e5c31af7Sopenharmony_ci} 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci// UsagePositiveNegativeTestCase 581e5c31af7Sopenharmony_ci 582e5c31af7Sopenharmony_ciclass UsagePositiveNegativeTestCase : public PolygonOffsetTestCase 583e5c31af7Sopenharmony_ci{ 584e5c31af7Sopenharmony_cipublic: 585e5c31af7Sopenharmony_ci UsagePositiveNegativeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName); 586e5c31af7Sopenharmony_ci 587e5c31af7Sopenharmony_ci void testPolygonOffset (void); 588e5c31af7Sopenharmony_ci}; 589e5c31af7Sopenharmony_ci 590e5c31af7Sopenharmony_ciUsagePositiveNegativeTestCase::UsagePositiveNegativeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName) 591e5c31af7Sopenharmony_ci : PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200) 592e5c31af7Sopenharmony_ci{ 593e5c31af7Sopenharmony_ci} 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_civoid UsagePositiveNegativeTestCase::testPolygonOffset (void) 596e5c31af7Sopenharmony_ci{ 597e5c31af7Sopenharmony_ci using tcu::TestLog; 598e5c31af7Sopenharmony_ci 599e5c31af7Sopenharmony_ci const tcu::Vec4 triangleBottomRight[] = 600e5c31af7Sopenharmony_ci { 601e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, 0, 1), 602e5c31af7Sopenharmony_ci tcu::Vec4( 1, 1, 0, 1), 603e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, 0, 1), 604e5c31af7Sopenharmony_ci }; 605e5c31af7Sopenharmony_ci const tcu::Vec4 triangleTopLeft[] = 606e5c31af7Sopenharmony_ci { 607e5c31af7Sopenharmony_ci tcu::Vec4(-1, -1, 0, 1), 608e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, 0, 1), 609e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, 0, 1), 610e5c31af7Sopenharmony_ci }; 611e5c31af7Sopenharmony_ci 612e5c31af7Sopenharmony_ci tcu::TestLog& log = m_testCtx.getLog(); 613e5c31af7Sopenharmony_ci tcu::Surface testImage (m_targetSize, m_targetSize); 614e5c31af7Sopenharmony_ci tcu::Surface referenceImage (m_targetSize, m_targetSize); 615e5c31af7Sopenharmony_ci int subpixelBits = 0; 616e5c31af7Sopenharmony_ci // render test image 617e5c31af7Sopenharmony_ci { 618e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 619e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment)); 620e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(program.getProgram(), "a_position"); 621e5c31af7Sopenharmony_ci const GLint colorLoc = gl.getAttribLocation(program.getProgram(), "a_color"); 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci if (!program.isOk()) 624e5c31af7Sopenharmony_ci { 625e5c31af7Sopenharmony_ci log << program; 626e5c31af7Sopenharmony_ci TCU_FAIL("Shader compile failed."); 627e5c31af7Sopenharmony_ci } 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_ci gl.clearColor (0, 0, 0, 1); 630e5c31af7Sopenharmony_ci gl.clearDepthf (1.0f); 631e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 632e5c31af7Sopenharmony_ci gl.viewport (0, 0, m_targetSize, m_targetSize); 633e5c31af7Sopenharmony_ci gl.depthFunc (GL_LESS); 634e5c31af7Sopenharmony_ci gl.useProgram (program.getProgram()); 635e5c31af7Sopenharmony_ci gl.enable (GL_DEPTH_TEST); 636e5c31af7Sopenharmony_ci gl.enable (GL_POLYGON_OFFSET_FILL); 637e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (positionLoc); 638e5c31af7Sopenharmony_ci 639e5c31af7Sopenharmony_ci log << TestLog::Message << "DepthFunc = GL_LESS." << TestLog::EndMessage; 640e5c31af7Sopenharmony_ci log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage; 641e5c31af7Sopenharmony_ci 642e5c31af7Sopenharmony_ci //draw top left (negative offset test) 643e5c31af7Sopenharmony_ci { 644e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft); 645e5c31af7Sopenharmony_ci 646e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw top-left. Color = White.\tState: PolygonOffset(0, 0)." << TestLog::EndMessage; 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ci gl.polygonOffset (0, 0); 649e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); 650e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 651e5c31af7Sopenharmony_ci 652e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw top-left. Color = Green.\tState: PolygonOffset(0, -1)." << TestLog::EndMessage; 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci gl.polygonOffset (0, -1); 655e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 0.0f, 1.0f, 0.0f, 1.0f); 656e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 657e5c31af7Sopenharmony_ci } 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci //draw bottom right (positive offset test) 660e5c31af7Sopenharmony_ci { 661e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight); 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw bottom-right. Color = White.\tState: PolygonOffset(0, 1)." << TestLog::EndMessage; 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ci gl.polygonOffset (0, 1); 666e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); 667e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw bottom-right. Color = Yellow.\tState: PolygonOffset(0, 0)." << TestLog::EndMessage; 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ci gl.polygonOffset (0, 0); 672e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 0.0f, 1.0f); 673e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 674e5c31af7Sopenharmony_ci } 675e5c31af7Sopenharmony_ci 676e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (positionLoc); 677e5c31af7Sopenharmony_ci gl.useProgram (0); 678e5c31af7Sopenharmony_ci gl.finish (); 679e5c31af7Sopenharmony_ci 680e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess()); 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci gl.getIntegerv(GL_SUBPIXEL_BITS, &subpixelBits); 683e5c31af7Sopenharmony_ci } 684e5c31af7Sopenharmony_ci 685e5c31af7Sopenharmony_ci // render reference image 686e5c31af7Sopenharmony_ci { 687e5c31af7Sopenharmony_ci rr::Renderer referenceRenderer; 688e5c31af7Sopenharmony_ci rr::VertexAttrib attribs[2]; 689e5c31af7Sopenharmony_ci rr::RenderState state((rr::ViewportState)(rr::WindowRectangle(0, 0, m_targetSize, m_targetSize)), subpixelBits); 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci PositionColorShader program; 692e5c31af7Sopenharmony_ci 693e5c31af7Sopenharmony_ci attribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT; 694e5c31af7Sopenharmony_ci attribs[0].size = 4; 695e5c31af7Sopenharmony_ci attribs[0].stride = 0; 696e5c31af7Sopenharmony_ci attribs[0].instanceDivisor = 0; 697e5c31af7Sopenharmony_ci attribs[0].pointer = triangleTopLeft; 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci attribs[1].type = rr::VERTEXATTRIBTYPE_DONT_CARE; 700e5c31af7Sopenharmony_ci attribs[1].generic = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 703e5c31af7Sopenharmony_ci 704e5c31af7Sopenharmony_ci log << TestLog::Message << "Expecting: Top-left = Green, Bottom-right = Yellow." << TestLog::EndMessage; 705e5c31af7Sopenharmony_ci 706e5c31af7Sopenharmony_ci referenceRenderer.draw( 707e5c31af7Sopenharmony_ci rr::DrawCommand( 708e5c31af7Sopenharmony_ci state, 709e5c31af7Sopenharmony_ci rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())), 710e5c31af7Sopenharmony_ci rr::Program(program.getVertexShader(), program.getFragmentShader()), 711e5c31af7Sopenharmony_ci 2, 712e5c31af7Sopenharmony_ci attribs, 713e5c31af7Sopenharmony_ci rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0))); 714e5c31af7Sopenharmony_ci 715e5c31af7Sopenharmony_ci attribs[0].pointer = triangleBottomRight; 716e5c31af7Sopenharmony_ci attribs[1].generic = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f); 717e5c31af7Sopenharmony_ci 718e5c31af7Sopenharmony_ci referenceRenderer.draw( 719e5c31af7Sopenharmony_ci rr::DrawCommand( 720e5c31af7Sopenharmony_ci state, 721e5c31af7Sopenharmony_ci rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())), 722e5c31af7Sopenharmony_ci rr::Program(program.getVertexShader(), program.getFragmentShader()), 723e5c31af7Sopenharmony_ci 2, 724e5c31af7Sopenharmony_ci attribs, 725e5c31af7Sopenharmony_ci rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0))); 726e5c31af7Sopenharmony_ci } 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci // compare 729e5c31af7Sopenharmony_ci verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess()); 730e5c31af7Sopenharmony_ci} 731e5c31af7Sopenharmony_ci 732e5c31af7Sopenharmony_ci// ResultClampingTestCase 733e5c31af7Sopenharmony_ci 734e5c31af7Sopenharmony_ciclass ResultClampingTestCase : public PolygonOffsetTestCase 735e5c31af7Sopenharmony_ci{ 736e5c31af7Sopenharmony_cipublic: 737e5c31af7Sopenharmony_ci ResultClampingTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName); 738e5c31af7Sopenharmony_ci 739e5c31af7Sopenharmony_ci void testPolygonOffset (void); 740e5c31af7Sopenharmony_ci}; 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ciResultClampingTestCase::ResultClampingTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName) 743e5c31af7Sopenharmony_ci : PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200) 744e5c31af7Sopenharmony_ci{ 745e5c31af7Sopenharmony_ci} 746e5c31af7Sopenharmony_ci 747e5c31af7Sopenharmony_civoid ResultClampingTestCase::testPolygonOffset (void) 748e5c31af7Sopenharmony_ci{ 749e5c31af7Sopenharmony_ci using tcu::TestLog; 750e5c31af7Sopenharmony_ci 751e5c31af7Sopenharmony_ci const tcu::Vec4 triangleBottomRight[] = 752e5c31af7Sopenharmony_ci { 753e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, 1, 1), 754e5c31af7Sopenharmony_ci tcu::Vec4( 1, 1, 1, 1), 755e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, 1, 1), 756e5c31af7Sopenharmony_ci }; 757e5c31af7Sopenharmony_ci const tcu::Vec4 triangleTopLeft[] = 758e5c31af7Sopenharmony_ci { 759e5c31af7Sopenharmony_ci tcu::Vec4(-1, -1, -1, 1), 760e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, -1, 1), 761e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, -1, 1), 762e5c31af7Sopenharmony_ci }; 763e5c31af7Sopenharmony_ci 764e5c31af7Sopenharmony_ci tcu::TestLog& log = m_testCtx.getLog(); 765e5c31af7Sopenharmony_ci tcu::Surface testImage (m_targetSize, m_targetSize); 766e5c31af7Sopenharmony_ci tcu::Surface referenceImage (m_targetSize, m_targetSize); 767e5c31af7Sopenharmony_ci 768e5c31af7Sopenharmony_ci // render test image 769e5c31af7Sopenharmony_ci { 770e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 771e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment)); 772e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(program.getProgram(), "a_position"); 773e5c31af7Sopenharmony_ci const GLint colorLoc = gl.getAttribLocation(program.getProgram(), "a_color"); 774e5c31af7Sopenharmony_ci 775e5c31af7Sopenharmony_ci if (!program.isOk()) 776e5c31af7Sopenharmony_ci { 777e5c31af7Sopenharmony_ci log << program; 778e5c31af7Sopenharmony_ci TCU_FAIL("Shader compile failed."); 779e5c31af7Sopenharmony_ci } 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci gl.clearColor (0, 0, 0, 1); 782e5c31af7Sopenharmony_ci gl.clearDepthf (1.0f); 783e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 784e5c31af7Sopenharmony_ci gl.viewport (0, 0, m_targetSize, m_targetSize); 785e5c31af7Sopenharmony_ci gl.useProgram (program.getProgram()); 786e5c31af7Sopenharmony_ci gl.enable (GL_DEPTH_TEST); 787e5c31af7Sopenharmony_ci gl.enable (GL_POLYGON_OFFSET_FILL); 788e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (positionLoc); 789e5c31af7Sopenharmony_ci 790e5c31af7Sopenharmony_ci log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage; 791e5c31af7Sopenharmony_ci 792e5c31af7Sopenharmony_ci //draw bottom right (far) 793e5c31af7Sopenharmony_ci { 794e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight); 795e5c31af7Sopenharmony_ci 796e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw bottom-right. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 8), Polygon Z = 1.0. (Result depth should clamp to 1.0)." << TestLog::EndMessage; 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ci gl.depthFunc (GL_ALWAYS); 799e5c31af7Sopenharmony_ci gl.polygonOffset (0, 8); 800e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); 801e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 802e5c31af7Sopenharmony_ci 803e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw bottom-right. Color = Red.\tState: DepthFunc = GREATER, PolygonOffset(0, 9), Polygon Z = 1.0. (Result depth should clamp to 1.0 too)" << TestLog::EndMessage; 804e5c31af7Sopenharmony_ci 805e5c31af7Sopenharmony_ci gl.depthFunc (GL_GREATER); 806e5c31af7Sopenharmony_ci gl.polygonOffset (0, 9); 807e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 0.0f, 0.0f, 1.0f); 808e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 809e5c31af7Sopenharmony_ci } 810e5c31af7Sopenharmony_ci 811e5c31af7Sopenharmony_ci //draw top left (near) 812e5c31af7Sopenharmony_ci { 813e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft); 814e5c31af7Sopenharmony_ci 815e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw top-left. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, -8), Polygon Z = -1.0. (Result depth should clamp to -1.0)" << TestLog::EndMessage; 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci gl.depthFunc (GL_ALWAYS); 818e5c31af7Sopenharmony_ci gl.polygonOffset (0, -8); 819e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); 820e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 821e5c31af7Sopenharmony_ci 822e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw top-left. Color = Yellow.\tState: DepthFunc = LESS, PolygonOffset(0, -9), Polygon Z = -1.0. (Result depth should clamp to -1.0 too)." << TestLog::EndMessage; 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ci gl.depthFunc (GL_LESS); 825e5c31af7Sopenharmony_ci gl.polygonOffset (0, -9); 826e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 0.0f, 1.0f); 827e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 828e5c31af7Sopenharmony_ci } 829e5c31af7Sopenharmony_ci 830e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (positionLoc); 831e5c31af7Sopenharmony_ci gl.useProgram (0); 832e5c31af7Sopenharmony_ci gl.finish (); 833e5c31af7Sopenharmony_ci 834e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess()); 835e5c31af7Sopenharmony_ci } 836e5c31af7Sopenharmony_ci 837e5c31af7Sopenharmony_ci // render reference image 838e5c31af7Sopenharmony_ci log << TestLog::Message << "Expecting: Top-left = White, Bottom-right = White." << TestLog::EndMessage; 839e5c31af7Sopenharmony_ci tcu::clear(referenceImage.getAccess(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 840e5c31af7Sopenharmony_ci 841e5c31af7Sopenharmony_ci // compare 842e5c31af7Sopenharmony_ci verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess()); 843e5c31af7Sopenharmony_ci} 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_ci// UsageSlopeTestCase 846e5c31af7Sopenharmony_ci 847e5c31af7Sopenharmony_ciclass UsageSlopeTestCase : public PolygonOffsetTestCase 848e5c31af7Sopenharmony_ci{ 849e5c31af7Sopenharmony_cipublic: 850e5c31af7Sopenharmony_ci UsageSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName); 851e5c31af7Sopenharmony_ci 852e5c31af7Sopenharmony_ci void testPolygonOffset (void); 853e5c31af7Sopenharmony_ci}; 854e5c31af7Sopenharmony_ci 855e5c31af7Sopenharmony_ciUsageSlopeTestCase::UsageSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName) 856e5c31af7Sopenharmony_ci : PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200) 857e5c31af7Sopenharmony_ci{ 858e5c31af7Sopenharmony_ci} 859e5c31af7Sopenharmony_ci 860e5c31af7Sopenharmony_civoid UsageSlopeTestCase::testPolygonOffset (void) 861e5c31af7Sopenharmony_ci{ 862e5c31af7Sopenharmony_ci using tcu::TestLog; 863e5c31af7Sopenharmony_ci 864e5c31af7Sopenharmony_ci const tcu::Vec4 triangleBottomRight[] = 865e5c31af7Sopenharmony_ci { 866e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, 0.0f, 1), 867e5c31af7Sopenharmony_ci tcu::Vec4( 1, 1, 0.9f, 1), 868e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, 0.9f, 1), 869e5c31af7Sopenharmony_ci }; 870e5c31af7Sopenharmony_ci const tcu::Vec4 triangleTopLeft[] = 871e5c31af7Sopenharmony_ci { 872e5c31af7Sopenharmony_ci tcu::Vec4(-1, -1, -0.9f, 1), 873e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, 0.9f, 1), 874e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, 0.0f, 1), 875e5c31af7Sopenharmony_ci }; 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci tcu::TestLog& log = m_testCtx.getLog(); 878e5c31af7Sopenharmony_ci tcu::Surface testImage (m_targetSize, m_targetSize); 879e5c31af7Sopenharmony_ci tcu::Surface referenceImage (m_targetSize, m_targetSize); 880e5c31af7Sopenharmony_ci 881e5c31af7Sopenharmony_ci // render test image 882e5c31af7Sopenharmony_ci { 883e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 884e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment)); 885e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(program.getProgram(), "a_position"); 886e5c31af7Sopenharmony_ci const GLint colorLoc = gl.getAttribLocation(program.getProgram(), "a_color"); 887e5c31af7Sopenharmony_ci 888e5c31af7Sopenharmony_ci if (!program.isOk()) 889e5c31af7Sopenharmony_ci { 890e5c31af7Sopenharmony_ci log << program; 891e5c31af7Sopenharmony_ci TCU_FAIL("Shader compile failed."); 892e5c31af7Sopenharmony_ci } 893e5c31af7Sopenharmony_ci 894e5c31af7Sopenharmony_ci gl.clearColor (0, 0, 0, 1); 895e5c31af7Sopenharmony_ci gl.clearDepthf (1.0f); 896e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 897e5c31af7Sopenharmony_ci gl.viewport (0, 0, m_targetSize, m_targetSize); 898e5c31af7Sopenharmony_ci gl.useProgram (program.getProgram()); 899e5c31af7Sopenharmony_ci gl.enable (GL_DEPTH_TEST); 900e5c31af7Sopenharmony_ci gl.enable (GL_POLYGON_OFFSET_FILL); 901e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (positionLoc); 902e5c31af7Sopenharmony_ci 903e5c31af7Sopenharmony_ci log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage; 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_ci //draw top left (negative offset test) 906e5c31af7Sopenharmony_ci { 907e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft); 908e5c31af7Sopenharmony_ci 909e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw top-left. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage; 910e5c31af7Sopenharmony_ci 911e5c31af7Sopenharmony_ci gl.depthFunc (GL_ALWAYS); 912e5c31af7Sopenharmony_ci gl.polygonOffset (0, 0); 913e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); 914e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 915e5c31af7Sopenharmony_ci 916e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw top-left. Color = Green.\tState: DepthFunc = LESS, PolygonOffset(-1, 0)." << TestLog::EndMessage; 917e5c31af7Sopenharmony_ci 918e5c31af7Sopenharmony_ci gl.depthFunc (GL_LESS); 919e5c31af7Sopenharmony_ci gl.polygonOffset (-1, 0); 920e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 0.0f, 1.0f, 0.0f, 1.0f); 921e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 922e5c31af7Sopenharmony_ci } 923e5c31af7Sopenharmony_ci 924e5c31af7Sopenharmony_ci //draw bottom right (positive offset test) 925e5c31af7Sopenharmony_ci { 926e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight); 927e5c31af7Sopenharmony_ci 928e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw bottom-right. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage; 929e5c31af7Sopenharmony_ci 930e5c31af7Sopenharmony_ci gl.depthFunc (GL_ALWAYS); 931e5c31af7Sopenharmony_ci gl.polygonOffset (0, 0); 932e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); 933e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 934e5c31af7Sopenharmony_ci 935e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw bottom-right. Color = Green.\tState: DepthFunc = GREATER, PolygonOffset(1, 0)." << TestLog::EndMessage; 936e5c31af7Sopenharmony_ci 937e5c31af7Sopenharmony_ci gl.depthFunc (GL_GREATER); 938e5c31af7Sopenharmony_ci gl.polygonOffset (1, 0); 939e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 0.0f, 1.0f, 0.0f, 1.0f); 940e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 941e5c31af7Sopenharmony_ci } 942e5c31af7Sopenharmony_ci 943e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (positionLoc); 944e5c31af7Sopenharmony_ci gl.useProgram (0); 945e5c31af7Sopenharmony_ci gl.finish (); 946e5c31af7Sopenharmony_ci 947e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess()); 948e5c31af7Sopenharmony_ci } 949e5c31af7Sopenharmony_ci 950e5c31af7Sopenharmony_ci // render reference image 951e5c31af7Sopenharmony_ci log << TestLog::Message << "Expecting: Top-left = Green, Bottom-right = Green." << TestLog::EndMessage; 952e5c31af7Sopenharmony_ci tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 953e5c31af7Sopenharmony_ci 954e5c31af7Sopenharmony_ci // compare 955e5c31af7Sopenharmony_ci verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess()); 956e5c31af7Sopenharmony_ci} 957e5c31af7Sopenharmony_ci 958e5c31af7Sopenharmony_ci// ZeroSlopeTestCase 959e5c31af7Sopenharmony_ci 960e5c31af7Sopenharmony_ciclass ZeroSlopeTestCase : public PolygonOffsetTestCase 961e5c31af7Sopenharmony_ci{ 962e5c31af7Sopenharmony_cipublic: 963e5c31af7Sopenharmony_ci ZeroSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName); 964e5c31af7Sopenharmony_ci 965e5c31af7Sopenharmony_ci void testPolygonOffset (void); 966e5c31af7Sopenharmony_ci}; 967e5c31af7Sopenharmony_ci 968e5c31af7Sopenharmony_ciZeroSlopeTestCase::ZeroSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName) 969e5c31af7Sopenharmony_ci : PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200) 970e5c31af7Sopenharmony_ci{ 971e5c31af7Sopenharmony_ci} 972e5c31af7Sopenharmony_ci 973e5c31af7Sopenharmony_civoid ZeroSlopeTestCase::testPolygonOffset (void) 974e5c31af7Sopenharmony_ci{ 975e5c31af7Sopenharmony_ci using tcu::TestLog; 976e5c31af7Sopenharmony_ci 977e5c31af7Sopenharmony_ci const tcu::Vec4 triangle[] = 978e5c31af7Sopenharmony_ci { 979e5c31af7Sopenharmony_ci tcu::Vec4(-0.4f, 0.4f, 0.0f, 1.0f), 980e5c31af7Sopenharmony_ci tcu::Vec4(-0.8f, -0.5f, 0.0f, 1.0f), 981e5c31af7Sopenharmony_ci tcu::Vec4( 0.7f, 0.2f, 0.0f, 1.0f), 982e5c31af7Sopenharmony_ci }; 983e5c31af7Sopenharmony_ci 984e5c31af7Sopenharmony_ci tcu::TestLog& log = m_testCtx.getLog(); 985e5c31af7Sopenharmony_ci tcu::Surface testImage (m_targetSize, m_targetSize); 986e5c31af7Sopenharmony_ci tcu::Surface referenceImage (m_targetSize, m_targetSize); 987e5c31af7Sopenharmony_ci 988e5c31af7Sopenharmony_ci // log the triangle 989e5c31af7Sopenharmony_ci log << TestLog::Message << "Setup triangle with coordinates:" << TestLog::EndMessage; 990e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangle); ++ndx) 991e5c31af7Sopenharmony_ci log << TestLog::Message 992e5c31af7Sopenharmony_ci << "\tx=" << triangle[ndx].x() 993e5c31af7Sopenharmony_ci << "\ty=" << triangle[ndx].y() 994e5c31af7Sopenharmony_ci << "\tz=" << triangle[ndx].z() 995e5c31af7Sopenharmony_ci << "\tw=" << triangle[ndx].w() 996e5c31af7Sopenharmony_ci << TestLog::EndMessage; 997e5c31af7Sopenharmony_ci 998e5c31af7Sopenharmony_ci // render test image 999e5c31af7Sopenharmony_ci { 1000e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1001e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment)); 1002e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(program.getProgram(), "a_position"); 1003e5c31af7Sopenharmony_ci const GLint colorLoc = gl.getAttribLocation(program.getProgram(), "a_color"); 1004e5c31af7Sopenharmony_ci 1005e5c31af7Sopenharmony_ci if (!program.isOk()) 1006e5c31af7Sopenharmony_ci { 1007e5c31af7Sopenharmony_ci log << program; 1008e5c31af7Sopenharmony_ci TCU_FAIL("Shader compile failed."); 1009e5c31af7Sopenharmony_ci } 1010e5c31af7Sopenharmony_ci 1011e5c31af7Sopenharmony_ci gl.clearColor (0, 0, 0, 1); 1012e5c31af7Sopenharmony_ci gl.clearDepthf (1.0f); 1013e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1014e5c31af7Sopenharmony_ci gl.viewport (0, 0, m_targetSize, m_targetSize); 1015e5c31af7Sopenharmony_ci gl.useProgram (program.getProgram()); 1016e5c31af7Sopenharmony_ci gl.enable (GL_DEPTH_TEST); 1017e5c31af7Sopenharmony_ci gl.enable (GL_POLYGON_OFFSET_FILL); 1018e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (positionLoc); 1019e5c31af7Sopenharmony_ci 1020e5c31af7Sopenharmony_ci log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage; 1021e5c31af7Sopenharmony_ci 1022e5c31af7Sopenharmony_ci { 1023e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle); 1024e5c31af7Sopenharmony_ci 1025e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw triangle. Color = Red.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage; 1026e5c31af7Sopenharmony_ci 1027e5c31af7Sopenharmony_ci gl.depthFunc (GL_ALWAYS); 1028e5c31af7Sopenharmony_ci gl.polygonOffset (0, 0); 1029e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 0.0f, 0.0f, 1.0f); 1030e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 1031e5c31af7Sopenharmony_ci 1032e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw triangle. Color = Black.\tState: DepthFunc = EQUAL, PolygonOffset(4, 0)." << TestLog::EndMessage; 1033e5c31af7Sopenharmony_ci 1034e5c31af7Sopenharmony_ci gl.depthFunc (GL_EQUAL); 1035e5c31af7Sopenharmony_ci gl.polygonOffset (4, 0); // triangle slope == 0 1036e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 0.0f, 0.0f, 0.0f, 1.0f); 1037e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 1038e5c31af7Sopenharmony_ci } 1039e5c31af7Sopenharmony_ci 1040e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (positionLoc); 1041e5c31af7Sopenharmony_ci gl.useProgram (0); 1042e5c31af7Sopenharmony_ci gl.finish (); 1043e5c31af7Sopenharmony_ci 1044e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess()); 1045e5c31af7Sopenharmony_ci } 1046e5c31af7Sopenharmony_ci 1047e5c31af7Sopenharmony_ci // render reference image 1048e5c31af7Sopenharmony_ci log << TestLog::Message << "Expecting black triangle." << TestLog::EndMessage; 1049e5c31af7Sopenharmony_ci tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 1050e5c31af7Sopenharmony_ci 1051e5c31af7Sopenharmony_ci // compare 1052e5c31af7Sopenharmony_ci verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess()); 1053e5c31af7Sopenharmony_ci} 1054e5c31af7Sopenharmony_ci 1055e5c31af7Sopenharmony_ci// OneSlopeTestCase 1056e5c31af7Sopenharmony_ci 1057e5c31af7Sopenharmony_ciclass OneSlopeTestCase : public PolygonOffsetTestCase 1058e5c31af7Sopenharmony_ci{ 1059e5c31af7Sopenharmony_cipublic: 1060e5c31af7Sopenharmony_ci OneSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName); 1061e5c31af7Sopenharmony_ci 1062e5c31af7Sopenharmony_ci void testPolygonOffset (void); 1063e5c31af7Sopenharmony_ci}; 1064e5c31af7Sopenharmony_ci 1065e5c31af7Sopenharmony_ciOneSlopeTestCase::OneSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName) 1066e5c31af7Sopenharmony_ci : PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200) 1067e5c31af7Sopenharmony_ci{ 1068e5c31af7Sopenharmony_ci} 1069e5c31af7Sopenharmony_ci 1070e5c31af7Sopenharmony_civoid OneSlopeTestCase::testPolygonOffset (void) 1071e5c31af7Sopenharmony_ci{ 1072e5c31af7Sopenharmony_ci using tcu::TestLog; 1073e5c31af7Sopenharmony_ci 1074e5c31af7Sopenharmony_ci /* 1075e5c31af7Sopenharmony_ci * setup vertices subject to following properties 1076e5c31af7Sopenharmony_ci * dz_w / dx_w == 1 1077e5c31af7Sopenharmony_ci * dz_w / dy_w == 0 1078e5c31af7Sopenharmony_ci * or 1079e5c31af7Sopenharmony_ci * dz_w / dx_w == 0 1080e5c31af7Sopenharmony_ci * dz_w / dy_w == 1 1081e5c31af7Sopenharmony_ci * ==> m == 1 1082e5c31af7Sopenharmony_ci */ 1083e5c31af7Sopenharmony_ci const float cornerDepth = float(m_targetSize); 1084e5c31af7Sopenharmony_ci const tcu::Vec4 triangles[2][3] = 1085e5c31af7Sopenharmony_ci { 1086e5c31af7Sopenharmony_ci { 1087e5c31af7Sopenharmony_ci tcu::Vec4(-1, -1, -cornerDepth, 1), 1088e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, -cornerDepth, 1), 1089e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, cornerDepth, 1), 1090e5c31af7Sopenharmony_ci }, 1091e5c31af7Sopenharmony_ci { 1092e5c31af7Sopenharmony_ci tcu::Vec4(-1, 1, cornerDepth, 1), 1093e5c31af7Sopenharmony_ci tcu::Vec4( 1, 1, cornerDepth, 1), 1094e5c31af7Sopenharmony_ci tcu::Vec4( 1, -1, -cornerDepth, 1), 1095e5c31af7Sopenharmony_ci }, 1096e5c31af7Sopenharmony_ci }; 1097e5c31af7Sopenharmony_ci 1098e5c31af7Sopenharmony_ci tcu::TestLog& log = m_testCtx.getLog(); 1099e5c31af7Sopenharmony_ci tcu::Surface testImage (m_targetSize, m_targetSize); 1100e5c31af7Sopenharmony_ci tcu::Surface referenceImage (m_targetSize, m_targetSize); 1101e5c31af7Sopenharmony_ci 1102e5c31af7Sopenharmony_ci // log triangle info 1103e5c31af7Sopenharmony_ci log << TestLog::Message << "Setup triangle0 coordinates: (slope in window coordinates = 1.0)" << TestLog::EndMessage; 1104e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangles[0]); ++ndx) 1105e5c31af7Sopenharmony_ci log << TestLog::Message 1106e5c31af7Sopenharmony_ci << "\tx=" << triangles[0][ndx].x() 1107e5c31af7Sopenharmony_ci << "\ty=" << triangles[0][ndx].y() 1108e5c31af7Sopenharmony_ci << "\tz=" << triangles[0][ndx].z() 1109e5c31af7Sopenharmony_ci << "\tw=" << triangles[0][ndx].w() 1110e5c31af7Sopenharmony_ci << TestLog::EndMessage; 1111e5c31af7Sopenharmony_ci log << TestLog::Message << "Setup triangle1 coordinates: (slope in window coordinates = 1.0)" << TestLog::EndMessage; 1112e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangles[1]); ++ndx) 1113e5c31af7Sopenharmony_ci log << TestLog::Message 1114e5c31af7Sopenharmony_ci << "\tx=" << triangles[1][ndx].x() 1115e5c31af7Sopenharmony_ci << "\ty=" << triangles[1][ndx].y() 1116e5c31af7Sopenharmony_ci << "\tz=" << triangles[1][ndx].z() 1117e5c31af7Sopenharmony_ci << "\tw=" << triangles[1][ndx].w() 1118e5c31af7Sopenharmony_ci << TestLog::EndMessage; 1119e5c31af7Sopenharmony_ci 1120e5c31af7Sopenharmony_ci // render test image 1121e5c31af7Sopenharmony_ci { 1122e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1123e5c31af7Sopenharmony_ci const glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment)); 1124e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(program.getProgram(), "a_position"); 1125e5c31af7Sopenharmony_ci const GLint colorLoc = gl.getAttribLocation(program.getProgram(), "a_color"); 1126e5c31af7Sopenharmony_ci 1127e5c31af7Sopenharmony_ci if (!program.isOk()) 1128e5c31af7Sopenharmony_ci { 1129e5c31af7Sopenharmony_ci log << program; 1130e5c31af7Sopenharmony_ci TCU_FAIL("Shader compile failed."); 1131e5c31af7Sopenharmony_ci } 1132e5c31af7Sopenharmony_ci 1133e5c31af7Sopenharmony_ci gl.clearColor (0, 0, 0, 1); 1134e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT); 1135e5c31af7Sopenharmony_ci gl.viewport (0, 0, m_targetSize, m_targetSize); 1136e5c31af7Sopenharmony_ci gl.useProgram (program.getProgram()); 1137e5c31af7Sopenharmony_ci gl.enable (GL_DEPTH_TEST); 1138e5c31af7Sopenharmony_ci gl.enable (GL_POLYGON_OFFSET_FILL); 1139e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (positionLoc); 1140e5c31af7Sopenharmony_ci 1141e5c31af7Sopenharmony_ci log << TestLog::Message << "Framebuffer cleared, clear color = Black." << TestLog::EndMessage; 1142e5c31af7Sopenharmony_ci log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage; 1143e5c31af7Sopenharmony_ci 1144e5c31af7Sopenharmony_ci // top left (positive offset) 1145e5c31af7Sopenharmony_ci { 1146e5c31af7Sopenharmony_ci log << TestLog::Message << "Clear depth to 1.0." << TestLog::EndMessage; 1147e5c31af7Sopenharmony_ci 1148e5c31af7Sopenharmony_ci gl.clearDepthf (1.0f); // far 1149e5c31af7Sopenharmony_ci gl.clear (GL_DEPTH_BUFFER_BIT); 1150e5c31af7Sopenharmony_ci 1151e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangles[0]); 1152e5c31af7Sopenharmony_ci 1153e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw triangle0. Color = Red.\tState: DepthFunc = NOTEQUAL, PolygonOffset(10, 0). (Result depth should clamp to 1.0)." << TestLog::EndMessage; 1154e5c31af7Sopenharmony_ci 1155e5c31af7Sopenharmony_ci gl.polygonOffset (10, 0); // clamps any depth on the triangle to 1 1156e5c31af7Sopenharmony_ci gl.depthFunc (GL_NOTEQUAL); 1157e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 1.0f, 0.0f, 0.0f, 1.0f); 1158e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 1159e5c31af7Sopenharmony_ci } 1160e5c31af7Sopenharmony_ci // bottom right (negative offset) 1161e5c31af7Sopenharmony_ci { 1162e5c31af7Sopenharmony_ci log << TestLog::Message << "Clear depth to 0.0." << TestLog::EndMessage; 1163e5c31af7Sopenharmony_ci 1164e5c31af7Sopenharmony_ci gl.clearDepthf (0.0f); // far 1165e5c31af7Sopenharmony_ci gl.clear (GL_DEPTH_BUFFER_BIT); 1166e5c31af7Sopenharmony_ci 1167e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangles[1]); 1168e5c31af7Sopenharmony_ci 1169e5c31af7Sopenharmony_ci log << TestLog::Message << "Draw triangle1. Color = Green.\tState: DepthFunc = NOTEQUAL, PolygonOffset(-10, 0). (Result depth should clamp to 0.0)." << TestLog::EndMessage; 1170e5c31af7Sopenharmony_ci 1171e5c31af7Sopenharmony_ci gl.polygonOffset (-10, 0); // clamps depth to 0 1172e5c31af7Sopenharmony_ci gl.depthFunc (GL_NOTEQUAL); 1173e5c31af7Sopenharmony_ci gl.vertexAttrib4f (colorLoc, 0.0f, 1.0f, 0.0f, 1.0f); 1174e5c31af7Sopenharmony_ci gl.drawArrays (GL_TRIANGLES, 0, 3); 1175e5c31af7Sopenharmony_ci } 1176e5c31af7Sopenharmony_ci 1177e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (positionLoc); 1178e5c31af7Sopenharmony_ci gl.useProgram (0); 1179e5c31af7Sopenharmony_ci gl.finish (); 1180e5c31af7Sopenharmony_ci 1181e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess()); 1182e5c31af7Sopenharmony_ci } 1183e5c31af7Sopenharmony_ci 1184e5c31af7Sopenharmony_ci // render reference image 1185e5c31af7Sopenharmony_ci log << TestLog::Message << "Expecting black framebuffer." << TestLog::EndMessage; 1186e5c31af7Sopenharmony_ci tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 1187e5c31af7Sopenharmony_ci 1188e5c31af7Sopenharmony_ci // compare 1189e5c31af7Sopenharmony_ci verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess()); 1190e5c31af7Sopenharmony_ci} 1191e5c31af7Sopenharmony_ci 1192e5c31af7Sopenharmony_ci} // anonymous 1193e5c31af7Sopenharmony_ci 1194e5c31af7Sopenharmony_ciPolygonOffsetTests::PolygonOffsetTests (Context& context) 1195e5c31af7Sopenharmony_ci : TestCaseGroup(context, "polygon_offset", "Polygon offset tests") 1196e5c31af7Sopenharmony_ci{ 1197e5c31af7Sopenharmony_ci} 1198e5c31af7Sopenharmony_ci 1199e5c31af7Sopenharmony_ciPolygonOffsetTests::~PolygonOffsetTests (void) 1200e5c31af7Sopenharmony_ci{ 1201e5c31af7Sopenharmony_ci} 1202e5c31af7Sopenharmony_ci 1203e5c31af7Sopenharmony_civoid PolygonOffsetTests::init (void) 1204e5c31af7Sopenharmony_ci{ 1205e5c31af7Sopenharmony_ci const struct DepthBufferFormat 1206e5c31af7Sopenharmony_ci { 1207e5c31af7Sopenharmony_ci enum BufferType 1208e5c31af7Sopenharmony_ci { 1209e5c31af7Sopenharmony_ci TYPE_FIXED_POINT, 1210e5c31af7Sopenharmony_ci TYPE_FLOATING_POINT, 1211e5c31af7Sopenharmony_ci TYPE_UNKNOWN 1212e5c31af7Sopenharmony_ci }; 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci GLenum internalFormat; 1215e5c31af7Sopenharmony_ci int bits; 1216e5c31af7Sopenharmony_ci BufferType floatingPoint; 1217e5c31af7Sopenharmony_ci const char* name; 1218e5c31af7Sopenharmony_ci } depthFormats[]= 1219e5c31af7Sopenharmony_ci { 1220e5c31af7Sopenharmony_ci { 0, 0, DepthBufferFormat::TYPE_UNKNOWN, "default" }, 1221e5c31af7Sopenharmony_ci { GL_DEPTH_COMPONENT16, 16, DepthBufferFormat::TYPE_FIXED_POINT, "fixed16" }, 1222e5c31af7Sopenharmony_ci { GL_DEPTH_COMPONENT24, 24, DepthBufferFormat::TYPE_FIXED_POINT, "fixed24" }, 1223e5c31af7Sopenharmony_ci { GL_DEPTH_COMPONENT32F, 32, DepthBufferFormat::TYPE_FLOATING_POINT, "float32" }, 1224e5c31af7Sopenharmony_ci }; 1225e5c31af7Sopenharmony_ci 1226e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthFormats); ++ndx) 1227e5c31af7Sopenharmony_ci { 1228e5c31af7Sopenharmony_ci const DepthBufferFormat& format = depthFormats[ndx]; 1229e5c31af7Sopenharmony_ci 1230e5c31af7Sopenharmony_ci // enable works? 1231e5c31af7Sopenharmony_ci addChild(new UsageTestCase(m_context, (std::string(format.name) + "_enable").c_str(), "test enable GL_POLYGON_OFFSET_FILL", format.internalFormat, format.name)); 1232e5c31af7Sopenharmony_ci 1233e5c31af7Sopenharmony_ci // Really moves the polygons ? 1234e5c31af7Sopenharmony_ci addChild(new UsageDisplacementTestCase(m_context, (std::string(format.name) + "_displacement_with_units").c_str(), "test polygon offset", format.internalFormat, format.name)); 1235e5c31af7Sopenharmony_ci 1236e5c31af7Sopenharmony_ci // Really moves the polygons to right direction ? 1237e5c31af7Sopenharmony_ci addChild(new UsagePositiveNegativeTestCase(m_context, (std::string(format.name) + "_render_with_units").c_str(), "test polygon offset", format.internalFormat, format.name)); 1238e5c31af7Sopenharmony_ci 1239e5c31af7Sopenharmony_ci // Is total result clamped to [0,1] like promised? 1240e5c31af7Sopenharmony_ci addChild(new ResultClampingTestCase(m_context, (std::string(format.name) + "_result_depth_clamp").c_str(), "test polygon offset clamping", format.internalFormat, format.name)); 1241e5c31af7Sopenharmony_ci 1242e5c31af7Sopenharmony_ci // Slope really moves the polygon? 1243e5c31af7Sopenharmony_ci addChild(new UsageSlopeTestCase(m_context, (std::string(format.name) + "_render_with_factor").c_str(), "test polygon offset factor", format.internalFormat, format.name)); 1244e5c31af7Sopenharmony_ci 1245e5c31af7Sopenharmony_ci // Factor with zero slope 1246e5c31af7Sopenharmony_ci addChild(new ZeroSlopeTestCase(m_context, (std::string(format.name) + "_factor_0_slope").c_str(), "test polygon offset factor", format.internalFormat, format.name)); 1247e5c31af7Sopenharmony_ci 1248e5c31af7Sopenharmony_ci // Factor with 1.0 slope 1249e5c31af7Sopenharmony_ci addChild(new OneSlopeTestCase(m_context, (std::string(format.name) + "_factor_1_slope").c_str(), "test polygon offset factor", format.internalFormat, format.name)); 1250e5c31af7Sopenharmony_ci } 1251e5c31af7Sopenharmony_ci} 1252e5c31af7Sopenharmony_ci 1253e5c31af7Sopenharmony_ci} // Functional 1254e5c31af7Sopenharmony_ci} // gles3 1255e5c31af7Sopenharmony_ci} // deqp 1256