1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 2.0 Module 3e5c31af7Sopenharmony_ci * ------------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Functional rasterization tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es2fRasterizationTests.hpp" 25e5c31af7Sopenharmony_ci#include "tcuRasterizationVerifier.hpp" 26e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 27e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 28e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp" 29e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 30e5c31af7Sopenharmony_ci#include "tcuResultCollector.hpp" 31e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 32e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 33e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 34e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 35e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 36e5c31af7Sopenharmony_ci#include "deRandom.hpp" 37e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 38e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci#include <vector> 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_cinamespace deqp 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_cinamespace gles2 45e5c31af7Sopenharmony_ci{ 46e5c31af7Sopenharmony_cinamespace Functional 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_cinamespace 49e5c31af7Sopenharmony_ci{ 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_ciusing tcu::RasterizationArguments; 52e5c31af7Sopenharmony_ciusing tcu::TriangleSceneSpec; 53e5c31af7Sopenharmony_ciusing tcu::PointSceneSpec; 54e5c31af7Sopenharmony_ciusing tcu::LineSceneSpec; 55e5c31af7Sopenharmony_ciusing tcu::LineInterpolationMethod; 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_cistatic const char* const s_shaderVertexTemplate = "attribute highp vec4 a_position;\n" 58e5c31af7Sopenharmony_ci "attribute highp vec4 a_color;\n" 59e5c31af7Sopenharmony_ci "varying highp vec4 v_color;\n" 60e5c31af7Sopenharmony_ci "uniform highp float u_pointSize;\n" 61e5c31af7Sopenharmony_ci "void main ()\n" 62e5c31af7Sopenharmony_ci "{\n" 63e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 64e5c31af7Sopenharmony_ci " gl_PointSize = u_pointSize;\n" 65e5c31af7Sopenharmony_ci " v_color = a_color;\n" 66e5c31af7Sopenharmony_ci "}\n"; 67e5c31af7Sopenharmony_cistatic const char* const s_shaderFragmentTemplate = "varying mediump vec4 v_color;\n" 68e5c31af7Sopenharmony_ci "void main ()\n" 69e5c31af7Sopenharmony_ci "{\n" 70e5c31af7Sopenharmony_ci " gl_FragColor = v_color;\n" 71e5c31af7Sopenharmony_ci "}\n"; 72e5c31af7Sopenharmony_cienum InterpolationCaseFlags 73e5c31af7Sopenharmony_ci{ 74e5c31af7Sopenharmony_ci INTERPOLATIONFLAGS_NONE = 0, 75e5c31af7Sopenharmony_ci INTERPOLATIONFLAGS_PROJECTED = (1 << 1), 76e5c31af7Sopenharmony_ci}; 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_cienum PrimitiveWideness 79e5c31af7Sopenharmony_ci{ 80e5c31af7Sopenharmony_ci PRIMITIVEWIDENESS_NARROW = 0, 81e5c31af7Sopenharmony_ci PRIMITIVEWIDENESS_WIDE, 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ci PRIMITIVEWIDENESS_LAST 84e5c31af7Sopenharmony_ci}; 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ciclass BaseRenderingCase : public TestCase 87e5c31af7Sopenharmony_ci{ 88e5c31af7Sopenharmony_cipublic: 89e5c31af7Sopenharmony_ci BaseRenderingCase (Context& context, const char* name, const char* desc, int renderSize = 256); 90e5c31af7Sopenharmony_ci ~BaseRenderingCase (void); 91e5c31af7Sopenharmony_ci virtual void init (void); 92e5c31af7Sopenharmony_ci void deinit (void); 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ciprotected: 95e5c31af7Sopenharmony_ci void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, glw::GLenum primitiveType); 96e5c31af7Sopenharmony_ci void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, glw::GLenum primitiveType); 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ci const int m_renderSize; 99e5c31af7Sopenharmony_ci int m_numSamples; 100e5c31af7Sopenharmony_ci int m_subpixelBits; 101e5c31af7Sopenharmony_ci float m_pointSize; 102e5c31af7Sopenharmony_ci float m_lineWidth; 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci glu::ShaderProgram* m_shader; 105e5c31af7Sopenharmony_ci}; 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ciBaseRenderingCase::BaseRenderingCase (Context& context, const char* name, const char* desc, int renderSize) 108e5c31af7Sopenharmony_ci : TestCase (context, name, desc) 109e5c31af7Sopenharmony_ci , m_renderSize (renderSize) 110e5c31af7Sopenharmony_ci , m_numSamples (-1) 111e5c31af7Sopenharmony_ci , m_subpixelBits (-1) 112e5c31af7Sopenharmony_ci , m_pointSize (1.0f) 113e5c31af7Sopenharmony_ci , m_lineWidth (1.0f) 114e5c31af7Sopenharmony_ci , m_shader (DE_NULL) 115e5c31af7Sopenharmony_ci{ 116e5c31af7Sopenharmony_ci} 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ciBaseRenderingCase::~BaseRenderingCase (void) 119e5c31af7Sopenharmony_ci{ 120e5c31af7Sopenharmony_ci deinit(); 121e5c31af7Sopenharmony_ci} 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_civoid BaseRenderingCase::init (void) 124e5c31af7Sopenharmony_ci{ 125e5c31af7Sopenharmony_ci const int width = m_context.getRenderTarget().getWidth(); 126e5c31af7Sopenharmony_ci const int height = m_context.getRenderTarget().getHeight(); 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci // Requirements 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci if (width < m_renderSize || height < m_renderSize) 131e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(std::string("Render target size must be at least ") + de::toString(m_renderSize) + "x" + de::toString(m_renderSize)); 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ci if (m_lineWidth != 1.0f) 134e5c31af7Sopenharmony_ci { 135e5c31af7Sopenharmony_ci float range[2] = { 0.0f, 0.0f }; 136e5c31af7Sopenharmony_ci m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range); 137e5c31af7Sopenharmony_ci 138e5c31af7Sopenharmony_ci if (m_lineWidth < range[0] || m_lineWidth > range[1]) 139e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(std::string("Support for line width ") + de::toString(m_lineWidth) + " is required."); 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage; 142e5c31af7Sopenharmony_ci } 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci if (m_pointSize != 1.0f) 145e5c31af7Sopenharmony_ci { 146e5c31af7Sopenharmony_ci float range[2] = { 0.0f, 0.0f }; 147e5c31af7Sopenharmony_ci m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_POINT_SIZE_RANGE, range); 148e5c31af7Sopenharmony_ci 149e5c31af7Sopenharmony_ci if (m_pointSize < range[0] || m_pointSize > range[1]) 150e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(std::string("Support for point size ") + de::toString(m_pointSize) + " is required."); 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage; 153e5c31af7Sopenharmony_ci } 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci // Query info 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci m_numSamples = m_context.getRenderTarget().getNumSamples(); 158e5c31af7Sopenharmony_ci m_context.getRenderContext().getFunctions().getIntegerv(GL_SUBPIXEL_BITS, &m_subpixelBits); 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Sample count = " << m_numSamples << tcu::TestLog::EndMessage; 161e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage; 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci // Gen shader 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci { 166e5c31af7Sopenharmony_ci tcu::StringTemplate vertexSource (s_shaderVertexTemplate); 167e5c31af7Sopenharmony_ci tcu::StringTemplate fragmentSource (s_shaderFragmentTemplate); 168e5c31af7Sopenharmony_ci std::map<std::string, std::string> params; 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci m_shader = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vertexSource.specialize(params)) << glu::FragmentSource(fragmentSource.specialize(params))); 171e5c31af7Sopenharmony_ci if (!m_shader->isOk()) 172e5c31af7Sopenharmony_ci throw tcu::TestError("could not create shader"); 173e5c31af7Sopenharmony_ci } 174e5c31af7Sopenharmony_ci} 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_civoid BaseRenderingCase::deinit (void) 177e5c31af7Sopenharmony_ci{ 178e5c31af7Sopenharmony_ci if (m_shader) 179e5c31af7Sopenharmony_ci { 180e5c31af7Sopenharmony_ci delete m_shader; 181e5c31af7Sopenharmony_ci m_shader = DE_NULL; 182e5c31af7Sopenharmony_ci } 183e5c31af7Sopenharmony_ci} 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_civoid BaseRenderingCase::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, glw::GLenum primitiveType) 186e5c31af7Sopenharmony_ci{ 187e5c31af7Sopenharmony_ci // default to color white 188e5c31af7Sopenharmony_ci const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_ci drawPrimitives(result, vertexData, colorData, primitiveType); 191e5c31af7Sopenharmony_ci} 192e5c31af7Sopenharmony_ci 193e5c31af7Sopenharmony_civoid BaseRenderingCase::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& colorData, glw::GLenum primitiveType) 194e5c31af7Sopenharmony_ci{ 195e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 196e5c31af7Sopenharmony_ci const glw::GLint positionLoc = gl.getAttribLocation(m_shader->getProgram(), "a_position"); 197e5c31af7Sopenharmony_ci const glw::GLint colorLoc = gl.getAttribLocation(m_shader->getProgram(), "a_color"); 198e5c31af7Sopenharmony_ci const glw::GLint pointSizeLoc = gl.getUniformLocation(m_shader->getProgram(), "u_pointSize"); 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci gl.clearColor (0, 0, 0, 1); 201e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT); 202e5c31af7Sopenharmony_ci gl.viewport (0, 0, m_renderSize, m_renderSize); 203e5c31af7Sopenharmony_ci gl.useProgram (m_shader->getProgram()); 204e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (positionLoc); 205e5c31af7Sopenharmony_ci gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &vertexData[0]); 206e5c31af7Sopenharmony_ci gl.enableVertexAttribArray (colorLoc); 207e5c31af7Sopenharmony_ci gl.vertexAttribPointer (colorLoc, 4, GL_FLOAT, GL_FALSE, 0, &colorData[0]); 208e5c31af7Sopenharmony_ci gl.uniform1f (pointSizeLoc, m_pointSize); 209e5c31af7Sopenharmony_ci gl.lineWidth (m_lineWidth); 210e5c31af7Sopenharmony_ci gl.drawArrays (primitiveType, 0, (glw::GLsizei)vertexData.size()); 211e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (colorLoc); 212e5c31af7Sopenharmony_ci gl.disableVertexAttribArray (positionLoc); 213e5c31af7Sopenharmony_ci gl.useProgram (0); 214e5c31af7Sopenharmony_ci gl.finish (); 215e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR (gl.getError(), "draw primitives"); 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 218e5c31af7Sopenharmony_ci} 219e5c31af7Sopenharmony_ci 220e5c31af7Sopenharmony_ciclass BaseTriangleCase : public BaseRenderingCase 221e5c31af7Sopenharmony_ci{ 222e5c31af7Sopenharmony_cipublic: 223e5c31af7Sopenharmony_ci BaseTriangleCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType); 224e5c31af7Sopenharmony_ci ~BaseTriangleCase (void); 225e5c31af7Sopenharmony_ci IterateResult iterate (void); 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ciprivate: 228e5c31af7Sopenharmony_ci virtual void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL; 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_ci int m_iteration; 231e5c31af7Sopenharmony_ci const int m_iterationCount; 232e5c31af7Sopenharmony_ci const glw::GLenum m_primitiveDrawType; 233e5c31af7Sopenharmony_ci bool m_allIterationsPassed; 234e5c31af7Sopenharmony_ci}; 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ciBaseTriangleCase::BaseTriangleCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType) 237e5c31af7Sopenharmony_ci : BaseRenderingCase (context, name, desc) 238e5c31af7Sopenharmony_ci , m_iteration (0) 239e5c31af7Sopenharmony_ci , m_iterationCount (3) 240e5c31af7Sopenharmony_ci , m_primitiveDrawType (primitiveDrawType) 241e5c31af7Sopenharmony_ci , m_allIterationsPassed (true) 242e5c31af7Sopenharmony_ci{ 243e5c31af7Sopenharmony_ci} 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ciBaseTriangleCase::~BaseTriangleCase (void) 246e5c31af7Sopenharmony_ci{ 247e5c31af7Sopenharmony_ci} 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ciBaseTriangleCase::IterateResult BaseTriangleCase::iterate (void) 250e5c31af7Sopenharmony_ci{ 251e5c31af7Sopenharmony_ci const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount); 252e5c31af7Sopenharmony_ci const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription); 253e5c31af7Sopenharmony_ci tcu::Surface resultImage (m_renderSize, m_renderSize); 254e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> drawBuffer; 255e5c31af7Sopenharmony_ci std::vector<TriangleSceneSpec::SceneTriangle> triangles; 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci generateTriangles(m_iteration, drawBuffer, triangles); 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci // draw image 260e5c31af7Sopenharmony_ci drawPrimitives(resultImage, drawBuffer, m_primitiveDrawType); 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_ci // compare 263e5c31af7Sopenharmony_ci { 264e5c31af7Sopenharmony_ci bool compareOk; 265e5c31af7Sopenharmony_ci RasterizationArguments args; 266e5c31af7Sopenharmony_ci TriangleSceneSpec scene; 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci args.numSamples = m_numSamples; 269e5c31af7Sopenharmony_ci args.subpixelBits = m_subpixelBits; 270e5c31af7Sopenharmony_ci args.redBits = m_context.getRenderTarget().getPixelFormat().redBits; 271e5c31af7Sopenharmony_ci args.greenBits = m_context.getRenderTarget().getPixelFormat().greenBits; 272e5c31af7Sopenharmony_ci args.blueBits = m_context.getRenderTarget().getPixelFormat().blueBits; 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_ci scene.triangles.swap(triangles); 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci compareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_testCtx.getLog()); 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci if (!compareOk) 279e5c31af7Sopenharmony_ci m_allIterationsPassed = false; 280e5c31af7Sopenharmony_ci } 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci // result 283e5c31af7Sopenharmony_ci if (++m_iteration == m_iterationCount) 284e5c31af7Sopenharmony_ci { 285e5c31af7Sopenharmony_ci if (m_allIterationsPassed) 286e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 287e5c31af7Sopenharmony_ci else 288e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rasterization"); 289e5c31af7Sopenharmony_ci 290e5c31af7Sopenharmony_ci return STOP; 291e5c31af7Sopenharmony_ci } 292e5c31af7Sopenharmony_ci else 293e5c31af7Sopenharmony_ci return CONTINUE; 294e5c31af7Sopenharmony_ci} 295e5c31af7Sopenharmony_ci 296e5c31af7Sopenharmony_ciclass BaseLineCase : public BaseRenderingCase 297e5c31af7Sopenharmony_ci{ 298e5c31af7Sopenharmony_cipublic: 299e5c31af7Sopenharmony_ci BaseLineCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType, PrimitiveWideness wideness); 300e5c31af7Sopenharmony_ci ~BaseLineCase (void); 301e5c31af7Sopenharmony_ci IterateResult iterate (void); 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ciprivate: 304e5c31af7Sopenharmony_ci virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL; 305e5c31af7Sopenharmony_ci 306e5c31af7Sopenharmony_ci int m_iteration; 307e5c31af7Sopenharmony_ci const int m_iterationCount; 308e5c31af7Sopenharmony_ci const glw::GLenum m_primitiveDrawType; 309e5c31af7Sopenharmony_ci const PrimitiveWideness m_primitiveWideness; 310e5c31af7Sopenharmony_ci bool m_allIterationsPassed; 311e5c31af7Sopenharmony_ci bool m_multisampleRelaxationRequired; 312e5c31af7Sopenharmony_ci 313e5c31af7Sopenharmony_ci static const float s_wideSize; 314e5c31af7Sopenharmony_ci}; 315e5c31af7Sopenharmony_ci 316e5c31af7Sopenharmony_ciconst float BaseLineCase::s_wideSize = 5.0f; 317e5c31af7Sopenharmony_ci 318e5c31af7Sopenharmony_ciBaseLineCase::BaseLineCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType, PrimitiveWideness wideness) 319e5c31af7Sopenharmony_ci : BaseRenderingCase (context, name, desc) 320e5c31af7Sopenharmony_ci , m_iteration (0) 321e5c31af7Sopenharmony_ci , m_iterationCount (3) 322e5c31af7Sopenharmony_ci , m_primitiveDrawType (primitiveDrawType) 323e5c31af7Sopenharmony_ci , m_primitiveWideness (wideness) 324e5c31af7Sopenharmony_ci , m_allIterationsPassed (true) 325e5c31af7Sopenharmony_ci , m_multisampleRelaxationRequired (false) 326e5c31af7Sopenharmony_ci{ 327e5c31af7Sopenharmony_ci DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST); 328e5c31af7Sopenharmony_ci m_lineWidth = (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE) ? (s_wideSize) : (1.0f); 329e5c31af7Sopenharmony_ci} 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ciBaseLineCase::~BaseLineCase (void) 332e5c31af7Sopenharmony_ci{ 333e5c31af7Sopenharmony_ci} 334e5c31af7Sopenharmony_ci 335e5c31af7Sopenharmony_ciBaseLineCase::IterateResult BaseLineCase::iterate (void) 336e5c31af7Sopenharmony_ci{ 337e5c31af7Sopenharmony_ci const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount); 338e5c31af7Sopenharmony_ci const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription); 339e5c31af7Sopenharmony_ci tcu::Surface resultImage (m_renderSize, m_renderSize); 340e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> drawBuffer; 341e5c31af7Sopenharmony_ci std::vector<LineSceneSpec::SceneLine> lines; 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci // last iteration, max out size 344e5c31af7Sopenharmony_ci if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE && 345e5c31af7Sopenharmony_ci m_iteration+1 == m_iterationCount) 346e5c31af7Sopenharmony_ci { 347e5c31af7Sopenharmony_ci float range[2] = { 0.0f, 0.0f }; 348e5c31af7Sopenharmony_ci m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range); 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci m_lineWidth = range[1]; 351e5c31af7Sopenharmony_ci } 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci // gen data 354e5c31af7Sopenharmony_ci generateLines(m_iteration, drawBuffer, lines); 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ci // draw image 357e5c31af7Sopenharmony_ci drawPrimitives(resultImage, drawBuffer, m_primitiveDrawType); 358e5c31af7Sopenharmony_ci 359e5c31af7Sopenharmony_ci // compare 360e5c31af7Sopenharmony_ci { 361e5c31af7Sopenharmony_ci bool compareOk; 362e5c31af7Sopenharmony_ci RasterizationArguments args; 363e5c31af7Sopenharmony_ci LineSceneSpec scene; 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci args.numSamples = m_numSamples; 366e5c31af7Sopenharmony_ci args.subpixelBits = m_subpixelBits; 367e5c31af7Sopenharmony_ci args.redBits = m_context.getRenderTarget().getPixelFormat().redBits; 368e5c31af7Sopenharmony_ci args.greenBits = m_context.getRenderTarget().getPixelFormat().greenBits; 369e5c31af7Sopenharmony_ci args.blueBits = m_context.getRenderTarget().getPixelFormat().blueBits; 370e5c31af7Sopenharmony_ci 371e5c31af7Sopenharmony_ci scene.lines.swap(lines); 372e5c31af7Sopenharmony_ci scene.lineWidth = m_lineWidth; 373e5c31af7Sopenharmony_ci scene.stippleFactor = 1; 374e5c31af7Sopenharmony_ci scene.stipplePattern = 0xFFFF; 375e5c31af7Sopenharmony_ci scene.allowNonProjectedInterpolation = true; 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci compareOk = verifyLineGroupRasterization(resultImage, scene, args, m_testCtx.getLog()); 378e5c31af7Sopenharmony_ci 379e5c31af7Sopenharmony_ci // multisampled wide lines might not be supported 380e5c31af7Sopenharmony_ci if (scene.lineWidth != 1.0f && m_numSamples > 1 && !compareOk) 381e5c31af7Sopenharmony_ci { 382e5c31af7Sopenharmony_ci m_multisampleRelaxationRequired = true; 383e5c31af7Sopenharmony_ci compareOk = true; 384e5c31af7Sopenharmony_ci } 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci if (!compareOk) 387e5c31af7Sopenharmony_ci m_allIterationsPassed = false; 388e5c31af7Sopenharmony_ci } 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci // result 391e5c31af7Sopenharmony_ci if (++m_iteration == m_iterationCount) 392e5c31af7Sopenharmony_ci { 393e5c31af7Sopenharmony_ci if (m_allIterationsPassed && m_multisampleRelaxationRequired) 394e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Rasterization of multisampled wide lines failed"); 395e5c31af7Sopenharmony_ci else if (m_allIterationsPassed) 396e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 397e5c31af7Sopenharmony_ci else 398e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rasterization"); 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci return STOP; 401e5c31af7Sopenharmony_ci } 402e5c31af7Sopenharmony_ci else 403e5c31af7Sopenharmony_ci return CONTINUE; 404e5c31af7Sopenharmony_ci} 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ciclass PointCase : public BaseRenderingCase 407e5c31af7Sopenharmony_ci{ 408e5c31af7Sopenharmony_cipublic: 409e5c31af7Sopenharmony_ci PointCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness); 410e5c31af7Sopenharmony_ci ~PointCase (void); 411e5c31af7Sopenharmony_ci IterateResult iterate (void); 412e5c31af7Sopenharmony_ci 413e5c31af7Sopenharmony_ciprivate: 414e5c31af7Sopenharmony_ci void generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints); 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_ci int m_iteration; 417e5c31af7Sopenharmony_ci const int m_iterationCount; 418e5c31af7Sopenharmony_ci const PrimitiveWideness m_primitiveWideness; 419e5c31af7Sopenharmony_ci bool m_allIterationsPassed; 420e5c31af7Sopenharmony_ci 421e5c31af7Sopenharmony_ci static const float s_wideSize; 422e5c31af7Sopenharmony_ci}; 423e5c31af7Sopenharmony_ci 424e5c31af7Sopenharmony_ciconst float PointCase::s_wideSize = 10.0f; 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ciPointCase::PointCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness) 427e5c31af7Sopenharmony_ci : BaseRenderingCase (context, name, desc) 428e5c31af7Sopenharmony_ci , m_iteration (0) 429e5c31af7Sopenharmony_ci , m_iterationCount (3) 430e5c31af7Sopenharmony_ci , m_primitiveWideness (wideness) 431e5c31af7Sopenharmony_ci , m_allIterationsPassed (true) 432e5c31af7Sopenharmony_ci{ 433e5c31af7Sopenharmony_ci m_pointSize = (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE) ? (s_wideSize) : (1.0f); 434e5c31af7Sopenharmony_ci} 435e5c31af7Sopenharmony_ci 436e5c31af7Sopenharmony_ciPointCase::~PointCase (void) 437e5c31af7Sopenharmony_ci{ 438e5c31af7Sopenharmony_ci} 439e5c31af7Sopenharmony_ci 440e5c31af7Sopenharmony_ciPointCase::IterateResult PointCase::iterate (void) 441e5c31af7Sopenharmony_ci{ 442e5c31af7Sopenharmony_ci const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount); 443e5c31af7Sopenharmony_ci const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription); 444e5c31af7Sopenharmony_ci tcu::Surface resultImage (m_renderSize, m_renderSize); 445e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> drawBuffer; 446e5c31af7Sopenharmony_ci std::vector<PointSceneSpec::ScenePoint> points; 447e5c31af7Sopenharmony_ci 448e5c31af7Sopenharmony_ci // last iteration, max out size 449e5c31af7Sopenharmony_ci if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE && 450e5c31af7Sopenharmony_ci m_iteration+1 == m_iterationCount) 451e5c31af7Sopenharmony_ci { 452e5c31af7Sopenharmony_ci float range[2] = { 0.0f, 0.0f }; 453e5c31af7Sopenharmony_ci m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_POINT_SIZE_RANGE, range); 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci m_pointSize = range[1]; 456e5c31af7Sopenharmony_ci } 457e5c31af7Sopenharmony_ci 458e5c31af7Sopenharmony_ci // gen data 459e5c31af7Sopenharmony_ci generatePoints(m_iteration, drawBuffer, points); 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci // draw image 462e5c31af7Sopenharmony_ci drawPrimitives(resultImage, drawBuffer, GL_POINTS); 463e5c31af7Sopenharmony_ci 464e5c31af7Sopenharmony_ci // compare 465e5c31af7Sopenharmony_ci { 466e5c31af7Sopenharmony_ci bool compareOk; 467e5c31af7Sopenharmony_ci RasterizationArguments args; 468e5c31af7Sopenharmony_ci PointSceneSpec scene; 469e5c31af7Sopenharmony_ci 470e5c31af7Sopenharmony_ci args.numSamples = m_numSamples; 471e5c31af7Sopenharmony_ci args.subpixelBits = m_subpixelBits; 472e5c31af7Sopenharmony_ci args.redBits = m_context.getRenderTarget().getPixelFormat().redBits; 473e5c31af7Sopenharmony_ci args.greenBits = m_context.getRenderTarget().getPixelFormat().greenBits; 474e5c31af7Sopenharmony_ci args.blueBits = m_context.getRenderTarget().getPixelFormat().blueBits; 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_ci scene.points.swap(points); 477e5c31af7Sopenharmony_ci 478e5c31af7Sopenharmony_ci compareOk = verifyPointGroupRasterization(resultImage, scene, args, m_testCtx.getLog()); 479e5c31af7Sopenharmony_ci 480e5c31af7Sopenharmony_ci if (!compareOk) 481e5c31af7Sopenharmony_ci m_allIterationsPassed = false; 482e5c31af7Sopenharmony_ci } 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ci // result 485e5c31af7Sopenharmony_ci if (++m_iteration == m_iterationCount) 486e5c31af7Sopenharmony_ci { 487e5c31af7Sopenharmony_ci if (m_allIterationsPassed) 488e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 489e5c31af7Sopenharmony_ci else 490e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rasterization"); 491e5c31af7Sopenharmony_ci 492e5c31af7Sopenharmony_ci return STOP; 493e5c31af7Sopenharmony_ci } 494e5c31af7Sopenharmony_ci else 495e5c31af7Sopenharmony_ci return CONTINUE; 496e5c31af7Sopenharmony_ci} 497e5c31af7Sopenharmony_ci 498e5c31af7Sopenharmony_civoid PointCase::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints) 499e5c31af7Sopenharmony_ci{ 500e5c31af7Sopenharmony_ci outData.resize(6); 501e5c31af7Sopenharmony_ci 502e5c31af7Sopenharmony_ci switch (iteration) 503e5c31af7Sopenharmony_ci { 504e5c31af7Sopenharmony_ci case 0: 505e5c31af7Sopenharmony_ci // \note: these values are chosen arbitrarily 506e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f); 507e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f); 508e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f); 509e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f); 510e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f); 511e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f); 512e5c31af7Sopenharmony_ci break; 513e5c31af7Sopenharmony_ci 514e5c31af7Sopenharmony_ci case 1: 515e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f); 516e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f); 517e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f); 518e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 519e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f); 520e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f); 521e5c31af7Sopenharmony_ci break; 522e5c31af7Sopenharmony_ci 523e5c31af7Sopenharmony_ci case 2: 524e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f); 525e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 0.3f, -0.9f, 0.0f, 1.0f); 526e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f); 527e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f); 528e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f); 529e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f); 530e5c31af7Sopenharmony_ci break; 531e5c31af7Sopenharmony_ci } 532e5c31af7Sopenharmony_ci 533e5c31af7Sopenharmony_ci outPoints.resize(outData.size()); 534e5c31af7Sopenharmony_ci for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx) 535e5c31af7Sopenharmony_ci { 536e5c31af7Sopenharmony_ci outPoints[pointNdx].position = outData[pointNdx]; 537e5c31af7Sopenharmony_ci outPoints[pointNdx].pointSize = m_pointSize; 538e5c31af7Sopenharmony_ci } 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_ci // log 541e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << m_pointSize << ")" << tcu::TestLog::EndMessage; 542e5c31af7Sopenharmony_ci for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx) 543e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage; 544e5c31af7Sopenharmony_ci} 545e5c31af7Sopenharmony_ci 546e5c31af7Sopenharmony_ciclass PointSizeClampedTest : public BaseRenderingCase 547e5c31af7Sopenharmony_ci{ 548e5c31af7Sopenharmony_cipublic: 549e5c31af7Sopenharmony_ci PointSizeClampedTest (Context& context, const char* name, const char* desc) 550e5c31af7Sopenharmony_ci : BaseRenderingCase (context, name, desc) 551e5c31af7Sopenharmony_ci { 552e5c31af7Sopenharmony_ci } 553e5c31af7Sopenharmony_ci 554e5c31af7Sopenharmony_ci IterateResult iterate () 555e5c31af7Sopenharmony_ci { 556e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 557e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 558e5c31af7Sopenharmony_ci 559e5c31af7Sopenharmony_ci // Tests that point sizes (written to gl_PointSize) are clamped, 560e5c31af7Sopenharmony_ci // before rasterization, to the ALIASED_POINT_SIZE_RANGE 561e5c31af7Sopenharmony_ci // given by the implementation. 562e5c31af7Sopenharmony_ci static const int fboHeight = 4; 563e5c31af7Sopenharmony_ci static const int testAreaWidth = 4; 564e5c31af7Sopenharmony_ci static const int testAreaWidthWithMargin = testAreaWidth + 4; 565e5c31af7Sopenharmony_ci static const float pointRadiusOverage = 8; 566e5c31af7Sopenharmony_ci int fboWidth = 0; 567e5c31af7Sopenharmony_ci int maxPointDiameter = 0; 568e5c31af7Sopenharmony_ci { 569e5c31af7Sopenharmony_ci int maxRenderbufferSize = 0; 570e5c31af7Sopenharmony_ci int maxViewportDims[2] = {}; 571e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &maxRenderbufferSize); 572e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_VIEWPORT_DIMS, maxViewportDims); 573e5c31af7Sopenharmony_ci int maxFboWidth = std::min(maxRenderbufferSize, maxViewportDims[0]); 574e5c31af7Sopenharmony_ci 575e5c31af7Sopenharmony_ci float pointSizeRange[2] = {}; 576e5c31af7Sopenharmony_ci gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange); 577e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 578e5c31af7Sopenharmony_ci << "GL_ALIASED_POINT_SIZE_RANGE is [" << pointSizeRange[0] << ", " << pointSizeRange[1] << "]" 579e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 580e5c31af7Sopenharmony_ci // Typically (in the correct case), maxPointDiameter is an odd integer. 581e5c31af7Sopenharmony_ci maxPointDiameter = (int) pointSizeRange[1]; 582e5c31af7Sopenharmony_ci // maxPointRadius is inclusive of the center point. 583e5c31af7Sopenharmony_ci int maxPointRadius = (maxPointDiameter + 1) / 2; 584e5c31af7Sopenharmony_ci if (maxPointRadius > maxFboWidth - testAreaWidthWithMargin) 585e5c31af7Sopenharmony_ci { 586e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "max framebuffer size isn't large enough to test max point size"); 587e5c31af7Sopenharmony_ci return STOP; 588e5c31af7Sopenharmony_ci } 589e5c31af7Sopenharmony_ci fboWidth = maxPointRadius + testAreaWidthWithMargin; 590e5c31af7Sopenharmony_ci // Round up to the nearest multiple of 2: 591e5c31af7Sopenharmony_ci fboWidth = ((fboWidth + 1) / 2) * 2; 592e5c31af7Sopenharmony_ci } 593e5c31af7Sopenharmony_ci float pointSize = ((float) maxPointDiameter) + pointRadiusOverage * 2; 594e5c31af7Sopenharmony_ci TCU_CHECK(gl.getError() == GL_NO_ERROR); 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 597e5c31af7Sopenharmony_ci << "Testing with pointSize = " << pointSize 598e5c31af7Sopenharmony_ci << ", fboWidth = " << fboWidth 599e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci // Create a framebuffer that is (fboWidth)x(fboHeight), cleared to green: 602e5c31af7Sopenharmony_ci // +---------------------------+ 603e5c31af7Sopenharmony_ci // |ggggggggggggggggggggggggggg| 604e5c31af7Sopenharmony_ci // +---------------------------+ 605e5c31af7Sopenharmony_ci gl.viewport(0, 0, fboWidth, fboHeight); 606e5c31af7Sopenharmony_ci deUint32 fbo = 0; 607e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &fbo); 608e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); 609e5c31af7Sopenharmony_ci deUint32 rbo = 0; 610e5c31af7Sopenharmony_ci gl.genRenderbuffers(1, &rbo); 611e5c31af7Sopenharmony_ci gl.bindRenderbuffer(GL_RENDERBUFFER, rbo); 612e5c31af7Sopenharmony_ci gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, fboWidth, fboHeight); 613e5c31af7Sopenharmony_ci gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); 614e5c31af7Sopenharmony_ci if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 615e5c31af7Sopenharmony_ci { 616e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "couldn't complete a framebuffer suitable to test max point size"); 617e5c31af7Sopenharmony_ci return STOP; 618e5c31af7Sopenharmony_ci } 619e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 1.0f, 0.0f, 1.0f); 620e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 621e5c31af7Sopenharmony_ci TCU_CHECK(gl.getError() == GL_NO_ERROR); 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci // (Framebuffer is still bound.) 624e5c31af7Sopenharmony_ci 625e5c31af7Sopenharmony_ci // Draw a red point, with size pointSize, at the far right: 626e5c31af7Sopenharmony_ci // +---------------------------+ 627e5c31af7Sopenharmony_ci // |ggggggggRRRRRRRRRRRRRRRRRRR| 628e5c31af7Sopenharmony_ci // +---------------------------+ 629e5c31af7Sopenharmony_ci // x point center 630e5c31af7Sopenharmony_ci // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ fboWidth 631e5c31af7Sopenharmony_ci // ^^^^ testAreaWidth = 4 (this is the area that's tested) 632e5c31af7Sopenharmony_ci // ^^^^^^^^ testAreaWidthWithMargin = 8 (extra 4 pixels for tolerance) 633e5c31af7Sopenharmony_ci // ^^^^^^^^^^^^^^^^^^x^^^^^^^^^^^^^^^^^^ maxPointDiameter = 37 634e5c31af7Sopenharmony_ci // ^^^^^^^^ ^^^^^^^^ pointRadiusOverage = 8 * 2 635e5c31af7Sopenharmony_ci // ^^^^^^^^^^^^^^^^^^^^^^^^^^x^^^^^^^^^^^^^^^^^^^^^^^^^^ pointSize = 53 636e5c31af7Sopenharmony_ci // ^^^^^^^^^^^^^^^^^^^ area of resulting draw, if the size is clamped properly = 19 637e5c31af7Sopenharmony_ci { 638e5c31af7Sopenharmony_ci const glw::GLint positionLoc = gl.getAttribLocation(m_shader->getProgram(), "a_position"); 639e5c31af7Sopenharmony_ci const glw::GLint colorLoc = gl.getAttribLocation(m_shader->getProgram(), "a_color"); 640e5c31af7Sopenharmony_ci const glw::GLint pointSizeLoc = gl.getUniformLocation(m_shader->getProgram(), "u_pointSize"); 641e5c31af7Sopenharmony_ci static const float position[] = {1.0f, 0.0f, 0.0f, 1.0f}; 642e5c31af7Sopenharmony_ci static const float color[] = {1.0f, 0.0f, 0.0f, 1.0f}; 643e5c31af7Sopenharmony_ci gl.useProgram(m_shader->getProgram()); 644e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(positionLoc); 645e5c31af7Sopenharmony_ci gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, position); 646e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(colorLoc); 647e5c31af7Sopenharmony_ci gl.vertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, color); 648e5c31af7Sopenharmony_ci gl.uniform1f(pointSizeLoc, pointSize); 649e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, 1); 650e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(colorLoc); 651e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(positionLoc); 652e5c31af7Sopenharmony_ci gl.useProgram(0); 653e5c31af7Sopenharmony_ci TCU_CHECK(gl.getError() == GL_NO_ERROR); 654e5c31af7Sopenharmony_ci } 655e5c31af7Sopenharmony_ci 656e5c31af7Sopenharmony_ci // And test the resulting draw (the test area should still be green). 657e5c31af7Sopenharmony_ci deUint32 pixels[testAreaWidth * fboHeight] = {}; 658e5c31af7Sopenharmony_ci gl.readPixels(0, 0, testAreaWidth, fboHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 659e5c31af7Sopenharmony_ci TCU_CHECK(gl.getError() == GL_NO_ERROR); 660e5c31af7Sopenharmony_ci 661e5c31af7Sopenharmony_ci const tcu::RGBA threshold(12, 12, 12, 12); 662e5c31af7Sopenharmony_ci for (deUint32 y = 0; y < fboHeight; ++y) 663e5c31af7Sopenharmony_ci { 664e5c31af7Sopenharmony_ci for (deUint32 x = 0; x < testAreaWidth; ++x) 665e5c31af7Sopenharmony_ci { 666e5c31af7Sopenharmony_ci tcu::RGBA color(pixels[y * testAreaWidth + x]); 667e5c31af7Sopenharmony_ci TCU_CHECK(compareThreshold(color, tcu::RGBA::green(), threshold)); 668e5c31af7Sopenharmony_ci } 669e5c31af7Sopenharmony_ci } 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ci return STOP; 672e5c31af7Sopenharmony_ci } 673e5c31af7Sopenharmony_ci}; 674e5c31af7Sopenharmony_ci 675e5c31af7Sopenharmony_ciclass TrianglesCase : public BaseTriangleCase 676e5c31af7Sopenharmony_ci{ 677e5c31af7Sopenharmony_cipublic: 678e5c31af7Sopenharmony_ci TrianglesCase (Context& context, const char* name, const char* desc); 679e5c31af7Sopenharmony_ci ~TrianglesCase (void); 680e5c31af7Sopenharmony_ci 681e5c31af7Sopenharmony_ci void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles); 682e5c31af7Sopenharmony_ci}; 683e5c31af7Sopenharmony_ci 684e5c31af7Sopenharmony_ciTrianglesCase::TrianglesCase (Context& context, const char* name, const char* desc) 685e5c31af7Sopenharmony_ci : BaseTriangleCase(context, name, desc, GL_TRIANGLES) 686e5c31af7Sopenharmony_ci{ 687e5c31af7Sopenharmony_ci} 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_ciTrianglesCase::~TrianglesCase (void) 690e5c31af7Sopenharmony_ci{ 691e5c31af7Sopenharmony_ci 692e5c31af7Sopenharmony_ci} 693e5c31af7Sopenharmony_ci 694e5c31af7Sopenharmony_civoid TrianglesCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) 695e5c31af7Sopenharmony_ci{ 696e5c31af7Sopenharmony_ci outData.resize(6); 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci switch (iteration) 699e5c31af7Sopenharmony_ci { 700e5c31af7Sopenharmony_ci case 0: 701e5c31af7Sopenharmony_ci // \note: these values are chosen arbitrarily 702e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f); 703e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f); 704e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f); 705e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f); 706e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f); 707e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f); 708e5c31af7Sopenharmony_ci break; 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ci case 1: 711e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f); 712e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f); 713e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f); 714e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 715e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f); 716e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f); 717e5c31af7Sopenharmony_ci break; 718e5c31af7Sopenharmony_ci 719e5c31af7Sopenharmony_ci case 2: 720e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f); 721e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f); 722e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f); 723e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f); 724e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f); 725e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f); 726e5c31af7Sopenharmony_ci break; 727e5c31af7Sopenharmony_ci } 728e5c31af7Sopenharmony_ci 729e5c31af7Sopenharmony_ci outTriangles.resize(2); 730e5c31af7Sopenharmony_ci outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false; 731e5c31af7Sopenharmony_ci outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false; 732e5c31af7Sopenharmony_ci outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false; 733e5c31af7Sopenharmony_ci 734e5c31af7Sopenharmony_ci outTriangles[1].positions[0] = outData[3]; outTriangles[1].sharedEdge[0] = false; 735e5c31af7Sopenharmony_ci outTriangles[1].positions[1] = outData[4]; outTriangles[1].sharedEdge[1] = false; 736e5c31af7Sopenharmony_ci outTriangles[1].positions[2] = outData[5]; outTriangles[1].sharedEdge[2] = false; 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ci // log 739e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage; 740e5c31af7Sopenharmony_ci for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx) 741e5c31af7Sopenharmony_ci { 742e5c31af7Sopenharmony_ci m_testCtx.getLog() 743e5c31af7Sopenharmony_ci << tcu::TestLog::Message 744e5c31af7Sopenharmony_ci << "Triangle " << (triangleNdx+1) << ":" 745e5c31af7Sopenharmony_ci << "\n\t" << outTriangles[triangleNdx].positions[0] 746e5c31af7Sopenharmony_ci << "\n\t" << outTriangles[triangleNdx].positions[1] 747e5c31af7Sopenharmony_ci << "\n\t" << outTriangles[triangleNdx].positions[2] 748e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 749e5c31af7Sopenharmony_ci } 750e5c31af7Sopenharmony_ci} 751e5c31af7Sopenharmony_ci 752e5c31af7Sopenharmony_ciclass TriangleStripCase : public BaseTriangleCase 753e5c31af7Sopenharmony_ci{ 754e5c31af7Sopenharmony_cipublic: 755e5c31af7Sopenharmony_ci TriangleStripCase (Context& context, const char* name, const char* desc); 756e5c31af7Sopenharmony_ci 757e5c31af7Sopenharmony_ci void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles); 758e5c31af7Sopenharmony_ci}; 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_ciTriangleStripCase::TriangleStripCase (Context& context, const char* name, const char* desc) 761e5c31af7Sopenharmony_ci : BaseTriangleCase(context, name, desc, GL_TRIANGLE_STRIP) 762e5c31af7Sopenharmony_ci{ 763e5c31af7Sopenharmony_ci} 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_civoid TriangleStripCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) 766e5c31af7Sopenharmony_ci{ 767e5c31af7Sopenharmony_ci outData.resize(5); 768e5c31af7Sopenharmony_ci 769e5c31af7Sopenharmony_ci switch (iteration) 770e5c31af7Sopenharmony_ci { 771e5c31af7Sopenharmony_ci case 0: 772e5c31af7Sopenharmony_ci // \note: these values are chosen arbitrarily 773e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(-0.504f, 0.8f, 0.0f, 1.0f); 774e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(-0.2f, -0.2f, 0.0f, 1.0f); 775e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4(-0.2f, 0.199f, 0.0f, 1.0f); 776e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.5f, 0.201f, 0.0f, 1.0f); 777e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 1.5f, 0.4f, 0.0f, 1.0f); 778e5c31af7Sopenharmony_ci break; 779e5c31af7Sopenharmony_ci 780e5c31af7Sopenharmony_ci case 1: 781e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(-0.499f, 0.129f, 0.0f, 1.0f); 782e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f); 783e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f); 784e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, -0.31f, 0.0f, 1.0f); 785e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f); 786e5c31af7Sopenharmony_ci break; 787e5c31af7Sopenharmony_ci 788e5c31af7Sopenharmony_ci case 2: 789e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f); 790e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f); 791e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4(-0.87f, -0.1f, 0.0f, 1.0f); 792e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.11f, 0.19f, 0.0f, 1.0f); 793e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f); 794e5c31af7Sopenharmony_ci break; 795e5c31af7Sopenharmony_ci } 796e5c31af7Sopenharmony_ci 797e5c31af7Sopenharmony_ci outTriangles.resize(3); 798e5c31af7Sopenharmony_ci outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false; 799e5c31af7Sopenharmony_ci outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = true; 800e5c31af7Sopenharmony_ci outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false; 801e5c31af7Sopenharmony_ci 802e5c31af7Sopenharmony_ci outTriangles[1].positions[0] = outData[2]; outTriangles[1].sharedEdge[0] = true; 803e5c31af7Sopenharmony_ci outTriangles[1].positions[1] = outData[1]; outTriangles[1].sharedEdge[1] = false; 804e5c31af7Sopenharmony_ci outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true; 805e5c31af7Sopenharmony_ci 806e5c31af7Sopenharmony_ci outTriangles[2].positions[0] = outData[2]; outTriangles[2].sharedEdge[0] = true; 807e5c31af7Sopenharmony_ci outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false; 808e5c31af7Sopenharmony_ci outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false; 809e5c31af7Sopenharmony_ci 810e5c31af7Sopenharmony_ci // log 811e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage; 812e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx) 813e5c31af7Sopenharmony_ci { 814e5c31af7Sopenharmony_ci m_testCtx.getLog() 815e5c31af7Sopenharmony_ci << tcu::TestLog::Message 816e5c31af7Sopenharmony_ci << "\t" << outData[vtxNdx] 817e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 818e5c31af7Sopenharmony_ci } 819e5c31af7Sopenharmony_ci} 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ciclass TriangleFanCase : public BaseTriangleCase 822e5c31af7Sopenharmony_ci{ 823e5c31af7Sopenharmony_cipublic: 824e5c31af7Sopenharmony_ci TriangleFanCase (Context& context, const char* name, const char* desc); 825e5c31af7Sopenharmony_ci 826e5c31af7Sopenharmony_ci void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles); 827e5c31af7Sopenharmony_ci}; 828e5c31af7Sopenharmony_ci 829e5c31af7Sopenharmony_ciTriangleFanCase::TriangleFanCase (Context& context, const char* name, const char* desc) 830e5c31af7Sopenharmony_ci : BaseTriangleCase(context, name, desc, GL_TRIANGLE_FAN) 831e5c31af7Sopenharmony_ci{ 832e5c31af7Sopenharmony_ci} 833e5c31af7Sopenharmony_ci 834e5c31af7Sopenharmony_civoid TriangleFanCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) 835e5c31af7Sopenharmony_ci{ 836e5c31af7Sopenharmony_ci outData.resize(5); 837e5c31af7Sopenharmony_ci 838e5c31af7Sopenharmony_ci switch (iteration) 839e5c31af7Sopenharmony_ci { 840e5c31af7Sopenharmony_ci case 0: 841e5c31af7Sopenharmony_ci // \note: these values are chosen arbitrarily 842e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f); 843e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f); 844e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f); 845e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f); 846e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f); 847e5c31af7Sopenharmony_ci break; 848e5c31af7Sopenharmony_ci 849e5c31af7Sopenharmony_ci case 1: 850e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f); 851e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f); 852e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f); 853e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 854e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f); 855e5c31af7Sopenharmony_ci break; 856e5c31af7Sopenharmony_ci 857e5c31af7Sopenharmony_ci case 2: 858e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f); 859e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f); 860e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f); 861e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 862e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f); 863e5c31af7Sopenharmony_ci break; 864e5c31af7Sopenharmony_ci } 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci outTriangles.resize(3); 867e5c31af7Sopenharmony_ci outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false; 868e5c31af7Sopenharmony_ci outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false; 869e5c31af7Sopenharmony_ci outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = true; 870e5c31af7Sopenharmony_ci 871e5c31af7Sopenharmony_ci outTriangles[1].positions[0] = outData[0]; outTriangles[1].sharedEdge[0] = true; 872e5c31af7Sopenharmony_ci outTriangles[1].positions[1] = outData[2]; outTriangles[1].sharedEdge[1] = false; 873e5c31af7Sopenharmony_ci outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true; 874e5c31af7Sopenharmony_ci 875e5c31af7Sopenharmony_ci outTriangles[2].positions[0] = outData[0]; outTriangles[2].sharedEdge[0] = true; 876e5c31af7Sopenharmony_ci outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false; 877e5c31af7Sopenharmony_ci outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false; 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci // log 880e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage; 881e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx) 882e5c31af7Sopenharmony_ci { 883e5c31af7Sopenharmony_ci m_testCtx.getLog() 884e5c31af7Sopenharmony_ci << tcu::TestLog::Message 885e5c31af7Sopenharmony_ci << "\t" << outData[vtxNdx] 886e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 887e5c31af7Sopenharmony_ci } 888e5c31af7Sopenharmony_ci} 889e5c31af7Sopenharmony_ci 890e5c31af7Sopenharmony_ciclass LinesCase : public BaseLineCase 891e5c31af7Sopenharmony_ci{ 892e5c31af7Sopenharmony_cipublic: 893e5c31af7Sopenharmony_ci LinesCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness); 894e5c31af7Sopenharmony_ci 895e5c31af7Sopenharmony_ci void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines); 896e5c31af7Sopenharmony_ci}; 897e5c31af7Sopenharmony_ci 898e5c31af7Sopenharmony_ciLinesCase::LinesCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness) 899e5c31af7Sopenharmony_ci : BaseLineCase(context, name, desc, GL_LINES, wideness) 900e5c31af7Sopenharmony_ci{ 901e5c31af7Sopenharmony_ci} 902e5c31af7Sopenharmony_ci 903e5c31af7Sopenharmony_civoid LinesCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) 904e5c31af7Sopenharmony_ci{ 905e5c31af7Sopenharmony_ci outData.resize(6); 906e5c31af7Sopenharmony_ci 907e5c31af7Sopenharmony_ci switch (iteration) 908e5c31af7Sopenharmony_ci { 909e5c31af7Sopenharmony_ci case 0: 910e5c31af7Sopenharmony_ci // \note: these values are chosen arbitrarily 911e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f); 912e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f); 913e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f); 914e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.3f, 0.2f, 0.0f, 1.0f); 915e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f); 916e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f); 917e5c31af7Sopenharmony_ci break; 918e5c31af7Sopenharmony_ci 919e5c31af7Sopenharmony_ci case 1: 920e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f); 921e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f); 922e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f); 923e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 924e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f); 925e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f); 926e5c31af7Sopenharmony_ci break; 927e5c31af7Sopenharmony_ci 928e5c31af7Sopenharmony_ci case 2: 929e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f); 930e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f); 931e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f); 932e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 933e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f); 934e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f); 935e5c31af7Sopenharmony_ci break; 936e5c31af7Sopenharmony_ci } 937e5c31af7Sopenharmony_ci 938e5c31af7Sopenharmony_ci outLines.resize(3); 939e5c31af7Sopenharmony_ci outLines[0].positions[0] = outData[0]; 940e5c31af7Sopenharmony_ci outLines[0].positions[1] = outData[1]; 941e5c31af7Sopenharmony_ci outLines[1].positions[0] = outData[2]; 942e5c31af7Sopenharmony_ci outLines[1].positions[1] = outData[3]; 943e5c31af7Sopenharmony_ci outLines[2].positions[0] = outData[4]; 944e5c31af7Sopenharmony_ci outLines[2].positions[1] = outData[5]; 945e5c31af7Sopenharmony_ci 946e5c31af7Sopenharmony_ci // log 947e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << m_lineWidth << ")" << tcu::TestLog::EndMessage; 948e5c31af7Sopenharmony_ci for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx) 949e5c31af7Sopenharmony_ci { 950e5c31af7Sopenharmony_ci m_testCtx.getLog() 951e5c31af7Sopenharmony_ci << tcu::TestLog::Message 952e5c31af7Sopenharmony_ci << "Line " << (lineNdx+1) << ":" 953e5c31af7Sopenharmony_ci << "\n\t" << outLines[lineNdx].positions[0] 954e5c31af7Sopenharmony_ci << "\n\t" << outLines[lineNdx].positions[1] 955e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 956e5c31af7Sopenharmony_ci } 957e5c31af7Sopenharmony_ci} 958e5c31af7Sopenharmony_ci 959e5c31af7Sopenharmony_ciclass LineStripCase : public BaseLineCase 960e5c31af7Sopenharmony_ci{ 961e5c31af7Sopenharmony_cipublic: 962e5c31af7Sopenharmony_ci LineStripCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness); 963e5c31af7Sopenharmony_ci 964e5c31af7Sopenharmony_ci void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines); 965e5c31af7Sopenharmony_ci}; 966e5c31af7Sopenharmony_ci 967e5c31af7Sopenharmony_ciLineStripCase::LineStripCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness) 968e5c31af7Sopenharmony_ci : BaseLineCase(context, name, desc, GL_LINE_STRIP, wideness) 969e5c31af7Sopenharmony_ci{ 970e5c31af7Sopenharmony_ci} 971e5c31af7Sopenharmony_ci 972e5c31af7Sopenharmony_civoid LineStripCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) 973e5c31af7Sopenharmony_ci{ 974e5c31af7Sopenharmony_ci outData.resize(4); 975e5c31af7Sopenharmony_ci 976e5c31af7Sopenharmony_ci switch (iteration) 977e5c31af7Sopenharmony_ci { 978e5c31af7Sopenharmony_ci case 0: 979e5c31af7Sopenharmony_ci // \note: these values are chosen arbitrarily 980e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f); 981e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f); 982e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f); 983e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f); 984e5c31af7Sopenharmony_ci break; 985e5c31af7Sopenharmony_ci 986e5c31af7Sopenharmony_ci case 1: 987e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f); 988e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f); 989e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f); 990e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 991e5c31af7Sopenharmony_ci break; 992e5c31af7Sopenharmony_ci 993e5c31af7Sopenharmony_ci case 2: 994e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f); 995e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f); 996e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f); 997e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 998e5c31af7Sopenharmony_ci break; 999e5c31af7Sopenharmony_ci } 1000e5c31af7Sopenharmony_ci 1001e5c31af7Sopenharmony_ci outLines.resize(3); 1002e5c31af7Sopenharmony_ci outLines[0].positions[0] = outData[0]; 1003e5c31af7Sopenharmony_ci outLines[0].positions[1] = outData[1]; 1004e5c31af7Sopenharmony_ci outLines[1].positions[0] = outData[1]; 1005e5c31af7Sopenharmony_ci outLines[1].positions[1] = outData[2]; 1006e5c31af7Sopenharmony_ci outLines[2].positions[0] = outData[2]; 1007e5c31af7Sopenharmony_ci outLines[2].positions[1] = outData[3]; 1008e5c31af7Sopenharmony_ci 1009e5c31af7Sopenharmony_ci // log 1010e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << m_lineWidth << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage; 1011e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx) 1012e5c31af7Sopenharmony_ci { 1013e5c31af7Sopenharmony_ci m_testCtx.getLog() 1014e5c31af7Sopenharmony_ci << tcu::TestLog::Message 1015e5c31af7Sopenharmony_ci << "\t" << outData[vtxNdx] 1016e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1017e5c31af7Sopenharmony_ci } 1018e5c31af7Sopenharmony_ci} 1019e5c31af7Sopenharmony_ci 1020e5c31af7Sopenharmony_ciclass LineLoopCase : public BaseLineCase 1021e5c31af7Sopenharmony_ci{ 1022e5c31af7Sopenharmony_cipublic: 1023e5c31af7Sopenharmony_ci LineLoopCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness); 1024e5c31af7Sopenharmony_ci 1025e5c31af7Sopenharmony_ci void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines); 1026e5c31af7Sopenharmony_ci}; 1027e5c31af7Sopenharmony_ci 1028e5c31af7Sopenharmony_ciLineLoopCase::LineLoopCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness) 1029e5c31af7Sopenharmony_ci : BaseLineCase(context, name, desc, GL_LINE_LOOP, wideness) 1030e5c31af7Sopenharmony_ci{ 1031e5c31af7Sopenharmony_ci} 1032e5c31af7Sopenharmony_ci 1033e5c31af7Sopenharmony_civoid LineLoopCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) 1034e5c31af7Sopenharmony_ci{ 1035e5c31af7Sopenharmony_ci outData.resize(4); 1036e5c31af7Sopenharmony_ci 1037e5c31af7Sopenharmony_ci switch (iteration) 1038e5c31af7Sopenharmony_ci { 1039e5c31af7Sopenharmony_ci case 0: 1040e5c31af7Sopenharmony_ci // \note: these values are chosen arbitrarily 1041e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f); 1042e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f); 1043e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f); 1044e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f); 1045e5c31af7Sopenharmony_ci break; 1046e5c31af7Sopenharmony_ci 1047e5c31af7Sopenharmony_ci case 1: 1048e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f); 1049e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f); 1050e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f); 1051e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 1052e5c31af7Sopenharmony_ci break; 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_ci case 2: 1055e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f); 1056e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f); 1057e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f); 1058e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f); 1059e5c31af7Sopenharmony_ci break; 1060e5c31af7Sopenharmony_ci } 1061e5c31af7Sopenharmony_ci 1062e5c31af7Sopenharmony_ci outLines.resize(4); 1063e5c31af7Sopenharmony_ci outLines[0].positions[0] = outData[0]; 1064e5c31af7Sopenharmony_ci outLines[0].positions[1] = outData[1]; 1065e5c31af7Sopenharmony_ci outLines[1].positions[0] = outData[1]; 1066e5c31af7Sopenharmony_ci outLines[1].positions[1] = outData[2]; 1067e5c31af7Sopenharmony_ci outLines[2].positions[0] = outData[2]; 1068e5c31af7Sopenharmony_ci outLines[2].positions[1] = outData[3]; 1069e5c31af7Sopenharmony_ci outLines[3].positions[0] = outData[3]; 1070e5c31af7Sopenharmony_ci outLines[3].positions[1] = outData[0]; 1071e5c31af7Sopenharmony_ci 1072e5c31af7Sopenharmony_ci // log 1073e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Rendering line loop, width = " << m_lineWidth << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage; 1074e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx) 1075e5c31af7Sopenharmony_ci { 1076e5c31af7Sopenharmony_ci m_testCtx.getLog() 1077e5c31af7Sopenharmony_ci << tcu::TestLog::Message 1078e5c31af7Sopenharmony_ci << "\t" << outData[vtxNdx] 1079e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1080e5c31af7Sopenharmony_ci } 1081e5c31af7Sopenharmony_ci} 1082e5c31af7Sopenharmony_ci 1083e5c31af7Sopenharmony_ciclass FillRuleCase : public BaseRenderingCase 1084e5c31af7Sopenharmony_ci{ 1085e5c31af7Sopenharmony_cipublic: 1086e5c31af7Sopenharmony_ci enum FillRuleCaseType 1087e5c31af7Sopenharmony_ci { 1088e5c31af7Sopenharmony_ci FILLRULECASE_BASIC = 0, 1089e5c31af7Sopenharmony_ci FILLRULECASE_REVERSED, 1090e5c31af7Sopenharmony_ci FILLRULECASE_CLIPPED_FULL, 1091e5c31af7Sopenharmony_ci FILLRULECASE_CLIPPED_PARTIAL, 1092e5c31af7Sopenharmony_ci FILLRULECASE_PROJECTED, 1093e5c31af7Sopenharmony_ci 1094e5c31af7Sopenharmony_ci FILLRULECASE_LAST 1095e5c31af7Sopenharmony_ci }; 1096e5c31af7Sopenharmony_ci 1097e5c31af7Sopenharmony_ci FillRuleCase (Context& ctx, const char* name, const char* desc, FillRuleCaseType type); 1098e5c31af7Sopenharmony_ci ~FillRuleCase (void); 1099e5c31af7Sopenharmony_ci IterateResult iterate (void); 1100e5c31af7Sopenharmony_ci 1101e5c31af7Sopenharmony_ciprivate: 1102e5c31af7Sopenharmony_ci int getRenderSize (FillRuleCase::FillRuleCaseType type) const; 1103e5c31af7Sopenharmony_ci int getNumIterations (FillRuleCase::FillRuleCaseType type) const; 1104e5c31af7Sopenharmony_ci void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const; 1105e5c31af7Sopenharmony_ci 1106e5c31af7Sopenharmony_ci const FillRuleCaseType m_caseType; 1107e5c31af7Sopenharmony_ci int m_iteration; 1108e5c31af7Sopenharmony_ci const int m_iterationCount; 1109e5c31af7Sopenharmony_ci bool m_allIterationsPassed; 1110e5c31af7Sopenharmony_ci 1111e5c31af7Sopenharmony_ci}; 1112e5c31af7Sopenharmony_ci 1113e5c31af7Sopenharmony_ciFillRuleCase::FillRuleCase (Context& ctx, const char* name, const char* desc, FillRuleCaseType type) 1114e5c31af7Sopenharmony_ci : BaseRenderingCase (ctx, name, desc, getRenderSize(type)) 1115e5c31af7Sopenharmony_ci , m_caseType (type) 1116e5c31af7Sopenharmony_ci , m_iteration (0) 1117e5c31af7Sopenharmony_ci , m_iterationCount (getNumIterations(type)) 1118e5c31af7Sopenharmony_ci , m_allIterationsPassed (true) 1119e5c31af7Sopenharmony_ci{ 1120e5c31af7Sopenharmony_ci DE_ASSERT(type < FILLRULECASE_LAST); 1121e5c31af7Sopenharmony_ci} 1122e5c31af7Sopenharmony_ci 1123e5c31af7Sopenharmony_ciFillRuleCase::~FillRuleCase (void) 1124e5c31af7Sopenharmony_ci{ 1125e5c31af7Sopenharmony_ci deinit(); 1126e5c31af7Sopenharmony_ci} 1127e5c31af7Sopenharmony_ci 1128e5c31af7Sopenharmony_ciFillRuleCase::IterateResult FillRuleCase::iterate (void) 1129e5c31af7Sopenharmony_ci{ 1130e5c31af7Sopenharmony_ci const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount); 1131e5c31af7Sopenharmony_ci const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription); 1132e5c31af7Sopenharmony_ci const int thresholdRed = 1 << (8 - m_context.getRenderTarget().getPixelFormat().redBits); 1133e5c31af7Sopenharmony_ci const int thresholdGreen = 1 << (8 - m_context.getRenderTarget().getPixelFormat().greenBits); 1134e5c31af7Sopenharmony_ci const int thresholdBlue = 1 << (8 - m_context.getRenderTarget().getPixelFormat().blueBits); 1135e5c31af7Sopenharmony_ci tcu::Surface resultImage (m_renderSize, m_renderSize); 1136e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> drawBuffer; 1137e5c31af7Sopenharmony_ci bool imageShown = false; 1138e5c31af7Sopenharmony_ci 1139e5c31af7Sopenharmony_ci generateTriangles(m_iteration, drawBuffer); 1140e5c31af7Sopenharmony_ci 1141e5c31af7Sopenharmony_ci // draw image 1142e5c31af7Sopenharmony_ci { 1143e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1144e5c31af7Sopenharmony_ci const std::vector<tcu::Vec4> colorBuffer (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f)); 1145e5c31af7Sopenharmony_ci 1146e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage; 1147e5c31af7Sopenharmony_ci 1148e5c31af7Sopenharmony_ci gl.enable(GL_BLEND); 1149e5c31af7Sopenharmony_ci gl.blendEquation(GL_FUNC_ADD); 1150e5c31af7Sopenharmony_ci gl.blendFunc(GL_ONE, GL_ONE); 1151e5c31af7Sopenharmony_ci drawPrimitives(resultImage, drawBuffer, colorBuffer, GL_TRIANGLES); 1152e5c31af7Sopenharmony_ci } 1153e5c31af7Sopenharmony_ci 1154e5c31af7Sopenharmony_ci // verify no overdraw 1155e5c31af7Sopenharmony_ci { 1156e5c31af7Sopenharmony_ci const tcu::RGBA triangleColor = tcu::RGBA(127, 127, 127, 255); 1157e5c31af7Sopenharmony_ci bool overdraw = false; 1158e5c31af7Sopenharmony_ci 1159e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage; 1160e5c31af7Sopenharmony_ci 1161e5c31af7Sopenharmony_ci for (int y = 0; y < resultImage.getHeight(); ++y) 1162e5c31af7Sopenharmony_ci for (int x = 0; x < resultImage.getWidth(); ++x) 1163e5c31af7Sopenharmony_ci { 1164e5c31af7Sopenharmony_ci const tcu::RGBA color = resultImage.getPixel(x, y); 1165e5c31af7Sopenharmony_ci 1166e5c31af7Sopenharmony_ci // color values are greater than triangle color? Allow lower values for multisampled edges and background. 1167e5c31af7Sopenharmony_ci if ((color.getRed() - triangleColor.getRed()) > thresholdRed || 1168e5c31af7Sopenharmony_ci (color.getGreen() - triangleColor.getGreen()) > thresholdGreen || 1169e5c31af7Sopenharmony_ci (color.getBlue() - triangleColor.getBlue()) > thresholdBlue) 1170e5c31af7Sopenharmony_ci overdraw = true; 1171e5c31af7Sopenharmony_ci } 1172e5c31af7Sopenharmony_ci 1173e5c31af7Sopenharmony_ci // results 1174e5c31af7Sopenharmony_ci if (!overdraw) 1175e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage; 1176e5c31af7Sopenharmony_ci else 1177e5c31af7Sopenharmony_ci { 1178e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage; 1179e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering") 1180e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Result", "Result", resultImage) 1181e5c31af7Sopenharmony_ci << tcu::TestLog::EndImageSet; 1182e5c31af7Sopenharmony_ci 1183e5c31af7Sopenharmony_ci imageShown = true; 1184e5c31af7Sopenharmony_ci m_allIterationsPassed = false; 1185e5c31af7Sopenharmony_ci } 1186e5c31af7Sopenharmony_ci } 1187e5c31af7Sopenharmony_ci 1188e5c31af7Sopenharmony_ci // verify no missing fragments in the full viewport case 1189e5c31af7Sopenharmony_ci if (m_caseType == FILLRULECASE_CLIPPED_FULL) 1190e5c31af7Sopenharmony_ci { 1191e5c31af7Sopenharmony_ci bool missingFragments = false; 1192e5c31af7Sopenharmony_ci 1193e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage; 1194e5c31af7Sopenharmony_ci 1195e5c31af7Sopenharmony_ci for (int y = 0; y < resultImage.getHeight(); ++y) 1196e5c31af7Sopenharmony_ci for (int x = 0; x < resultImage.getWidth(); ++x) 1197e5c31af7Sopenharmony_ci { 1198e5c31af7Sopenharmony_ci const tcu::RGBA color = resultImage.getPixel(x, y); 1199e5c31af7Sopenharmony_ci 1200e5c31af7Sopenharmony_ci // black? (background) 1201e5c31af7Sopenharmony_ci if (color.getRed() <= thresholdRed || 1202e5c31af7Sopenharmony_ci color.getGreen() <= thresholdGreen || 1203e5c31af7Sopenharmony_ci color.getBlue() <= thresholdBlue) 1204e5c31af7Sopenharmony_ci missingFragments = true; 1205e5c31af7Sopenharmony_ci } 1206e5c31af7Sopenharmony_ci 1207e5c31af7Sopenharmony_ci // results 1208e5c31af7Sopenharmony_ci if (!missingFragments) 1209e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage; 1210e5c31af7Sopenharmony_ci else 1211e5c31af7Sopenharmony_ci { 1212e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage; 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci if (!imageShown) 1215e5c31af7Sopenharmony_ci { 1216e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering") 1217e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Result", "Result", resultImage) 1218e5c31af7Sopenharmony_ci << tcu::TestLog::EndImageSet; 1219e5c31af7Sopenharmony_ci } 1220e5c31af7Sopenharmony_ci 1221e5c31af7Sopenharmony_ci m_allIterationsPassed = false; 1222e5c31af7Sopenharmony_ci } 1223e5c31af7Sopenharmony_ci } 1224e5c31af7Sopenharmony_ci 1225e5c31af7Sopenharmony_ci // result 1226e5c31af7Sopenharmony_ci if (++m_iteration == m_iterationCount) 1227e5c31af7Sopenharmony_ci { 1228e5c31af7Sopenharmony_ci if (m_allIterationsPassed) 1229e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1230e5c31af7Sopenharmony_ci else 1231e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Found invalid pixels"); 1232e5c31af7Sopenharmony_ci 1233e5c31af7Sopenharmony_ci return STOP; 1234e5c31af7Sopenharmony_ci } 1235e5c31af7Sopenharmony_ci else 1236e5c31af7Sopenharmony_ci return CONTINUE; 1237e5c31af7Sopenharmony_ci} 1238e5c31af7Sopenharmony_ci 1239e5c31af7Sopenharmony_ciint FillRuleCase::getRenderSize (FillRuleCase::FillRuleCaseType type) const 1240e5c31af7Sopenharmony_ci{ 1241e5c31af7Sopenharmony_ci if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL) 1242e5c31af7Sopenharmony_ci return 64; 1243e5c31af7Sopenharmony_ci else 1244e5c31af7Sopenharmony_ci return 256; 1245e5c31af7Sopenharmony_ci} 1246e5c31af7Sopenharmony_ci 1247e5c31af7Sopenharmony_ciint FillRuleCase::getNumIterations (FillRuleCase::FillRuleCaseType type) const 1248e5c31af7Sopenharmony_ci{ 1249e5c31af7Sopenharmony_ci if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL) 1250e5c31af7Sopenharmony_ci return 15; 1251e5c31af7Sopenharmony_ci else 1252e5c31af7Sopenharmony_ci return 2; 1253e5c31af7Sopenharmony_ci} 1254e5c31af7Sopenharmony_ci 1255e5c31af7Sopenharmony_civoid FillRuleCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const 1256e5c31af7Sopenharmony_ci{ 1257e5c31af7Sopenharmony_ci switch (m_caseType) 1258e5c31af7Sopenharmony_ci { 1259e5c31af7Sopenharmony_ci case FILLRULECASE_BASIC: 1260e5c31af7Sopenharmony_ci case FILLRULECASE_REVERSED: 1261e5c31af7Sopenharmony_ci case FILLRULECASE_PROJECTED: 1262e5c31af7Sopenharmony_ci { 1263e5c31af7Sopenharmony_ci const int numRows = 4; 1264e5c31af7Sopenharmony_ci const int numColumns = 4; 1265e5c31af7Sopenharmony_ci const float quadSide = 0.15f; 1266e5c31af7Sopenharmony_ci de::Random rnd (0xabcd); 1267e5c31af7Sopenharmony_ci 1268e5c31af7Sopenharmony_ci outData.resize(6 * numRows * numColumns); 1269e5c31af7Sopenharmony_ci 1270e5c31af7Sopenharmony_ci for (int col = 0; col < numColumns; ++col) 1271e5c31af7Sopenharmony_ci for (int row = 0; row < numRows; ++row) 1272e5c31af7Sopenharmony_ci { 1273e5c31af7Sopenharmony_ci const tcu::Vec2 center = tcu::Vec2(((float)row + 0.5f) / (float)numRows * 2.0f - 1.0f, ((float)col + 0.5f) / (float)numColumns * 2.0f - 1.0f); 1274e5c31af7Sopenharmony_ci const float rotation = float(iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f; 1275e5c31af7Sopenharmony_ci const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation)); 1276e5c31af7Sopenharmony_ci const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x()); 1277e5c31af7Sopenharmony_ci const tcu::Vec2 quad[4] = 1278e5c31af7Sopenharmony_ci { 1279e5c31af7Sopenharmony_ci center + sideH + sideV, 1280e5c31af7Sopenharmony_ci center + sideH - sideV, 1281e5c31af7Sopenharmony_ci center - sideH - sideV, 1282e5c31af7Sopenharmony_ci center - sideH + sideV, 1283e5c31af7Sopenharmony_ci }; 1284e5c31af7Sopenharmony_ci 1285e5c31af7Sopenharmony_ci if (m_caseType == FILLRULECASE_BASIC) 1286e5c31af7Sopenharmony_ci { 1287e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f); 1288e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f); 1289e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f); 1290e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f); 1291e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f); 1292e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f); 1293e5c31af7Sopenharmony_ci } 1294e5c31af7Sopenharmony_ci else if (m_caseType == FILLRULECASE_REVERSED) 1295e5c31af7Sopenharmony_ci { 1296e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f); 1297e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f); 1298e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f); 1299e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f); 1300e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f); 1301e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f); 1302e5c31af7Sopenharmony_ci } 1303e5c31af7Sopenharmony_ci else if (m_caseType == FILLRULECASE_PROJECTED) 1304e5c31af7Sopenharmony_ci { 1305e5c31af7Sopenharmony_ci const float w0 = rnd.getFloat(0.1f, 4.0f); 1306e5c31af7Sopenharmony_ci const float w1 = rnd.getFloat(0.1f, 4.0f); 1307e5c31af7Sopenharmony_ci const float w2 = rnd.getFloat(0.1f, 4.0f); 1308e5c31af7Sopenharmony_ci const float w3 = rnd.getFloat(0.1f, 4.0f); 1309e5c31af7Sopenharmony_ci 1310e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0); 1311e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1); 1312e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2); 1313e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2); 1314e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0); 1315e5c31af7Sopenharmony_ci outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3); 1316e5c31af7Sopenharmony_ci } 1317e5c31af7Sopenharmony_ci else 1318e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1319e5c31af7Sopenharmony_ci } 1320e5c31af7Sopenharmony_ci 1321e5c31af7Sopenharmony_ci break; 1322e5c31af7Sopenharmony_ci } 1323e5c31af7Sopenharmony_ci 1324e5c31af7Sopenharmony_ci case FILLRULECASE_CLIPPED_PARTIAL: 1325e5c31af7Sopenharmony_ci case FILLRULECASE_CLIPPED_FULL: 1326e5c31af7Sopenharmony_ci { 1327e5c31af7Sopenharmony_ci const float quadSide = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f); 1328e5c31af7Sopenharmony_ci const tcu::Vec2 center = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f)); 1329e5c31af7Sopenharmony_ci const float rotation = (float)(iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f; 1330e5c31af7Sopenharmony_ci const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation)); 1331e5c31af7Sopenharmony_ci const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x()); 1332e5c31af7Sopenharmony_ci const tcu::Vec2 quad[4] = 1333e5c31af7Sopenharmony_ci { 1334e5c31af7Sopenharmony_ci center + sideH + sideV, 1335e5c31af7Sopenharmony_ci center + sideH - sideV, 1336e5c31af7Sopenharmony_ci center - sideH - sideV, 1337e5c31af7Sopenharmony_ci center - sideH + sideV, 1338e5c31af7Sopenharmony_ci }; 1339e5c31af7Sopenharmony_ci 1340e5c31af7Sopenharmony_ci outData.resize(6); 1341e5c31af7Sopenharmony_ci outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f); 1342e5c31af7Sopenharmony_ci outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f); 1343e5c31af7Sopenharmony_ci outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f); 1344e5c31af7Sopenharmony_ci outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f); 1345e5c31af7Sopenharmony_ci outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f); 1346e5c31af7Sopenharmony_ci outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f); 1347e5c31af7Sopenharmony_ci break; 1348e5c31af7Sopenharmony_ci } 1349e5c31af7Sopenharmony_ci 1350e5c31af7Sopenharmony_ci default: 1351e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1352e5c31af7Sopenharmony_ci } 1353e5c31af7Sopenharmony_ci} 1354e5c31af7Sopenharmony_ci 1355e5c31af7Sopenharmony_ciclass CullingTest : public BaseRenderingCase 1356e5c31af7Sopenharmony_ci{ 1357e5c31af7Sopenharmony_cipublic: 1358e5c31af7Sopenharmony_ci CullingTest (Context& ctx, const char* name, const char* desc, glw::GLenum cullMode, glw::GLenum primitive, glw::GLenum faceOrder); 1359e5c31af7Sopenharmony_ci ~CullingTest (void); 1360e5c31af7Sopenharmony_ci IterateResult iterate (void); 1361e5c31af7Sopenharmony_ci 1362e5c31af7Sopenharmony_ciprivate: 1363e5c31af7Sopenharmony_ci void generateVertices (std::vector<tcu::Vec4>& outData) const; 1364e5c31af7Sopenharmony_ci void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const; 1365e5c31af7Sopenharmony_ci bool triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const; 1366e5c31af7Sopenharmony_ci 1367e5c31af7Sopenharmony_ci const glw::GLenum m_cullMode; 1368e5c31af7Sopenharmony_ci const glw::GLenum m_primitive; 1369e5c31af7Sopenharmony_ci const glw::GLenum m_faceOrder; 1370e5c31af7Sopenharmony_ci}; 1371e5c31af7Sopenharmony_ci 1372e5c31af7Sopenharmony_ciCullingTest::CullingTest (Context& ctx, const char* name, const char* desc, glw::GLenum cullMode, glw::GLenum primitive, glw::GLenum faceOrder) 1373e5c31af7Sopenharmony_ci : BaseRenderingCase (ctx, name, desc) 1374e5c31af7Sopenharmony_ci , m_cullMode (cullMode) 1375e5c31af7Sopenharmony_ci , m_primitive (primitive) 1376e5c31af7Sopenharmony_ci , m_faceOrder (faceOrder) 1377e5c31af7Sopenharmony_ci{ 1378e5c31af7Sopenharmony_ci} 1379e5c31af7Sopenharmony_ci 1380e5c31af7Sopenharmony_ciCullingTest::~CullingTest (void) 1381e5c31af7Sopenharmony_ci{ 1382e5c31af7Sopenharmony_ci} 1383e5c31af7Sopenharmony_ci 1384e5c31af7Sopenharmony_ciCullingTest::IterateResult CullingTest::iterate (void) 1385e5c31af7Sopenharmony_ci{ 1386e5c31af7Sopenharmony_ci tcu::Surface resultImage(m_renderSize, m_renderSize); 1387e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> drawBuffer; 1388e5c31af7Sopenharmony_ci std::vector<TriangleSceneSpec::SceneTriangle> triangles; 1389e5c31af7Sopenharmony_ci 1390e5c31af7Sopenharmony_ci // generate scene 1391e5c31af7Sopenharmony_ci generateVertices(drawBuffer); 1392e5c31af7Sopenharmony_ci extractTriangles(triangles, drawBuffer); 1393e5c31af7Sopenharmony_ci 1394e5c31af7Sopenharmony_ci // draw image 1395e5c31af7Sopenharmony_ci { 1396e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1397e5c31af7Sopenharmony_ci 1398e5c31af7Sopenharmony_ci gl.enable(GL_CULL_FACE); 1399e5c31af7Sopenharmony_ci gl.cullFace(m_cullMode); 1400e5c31af7Sopenharmony_ci gl.frontFace(m_faceOrder); 1401e5c31af7Sopenharmony_ci 1402e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Setting front face to " << glu::getWindingName(m_faceOrder) << tcu::TestLog::EndMessage; 1403e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Setting cull face to " << glu::getFaceName(m_cullMode) << tcu::TestLog::EndMessage; 1404e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Drawing test pattern (" << glu::getPrimitiveTypeName(m_primitive) << ")" << tcu::TestLog::EndMessage; 1405e5c31af7Sopenharmony_ci 1406e5c31af7Sopenharmony_ci drawPrimitives(resultImage, drawBuffer, m_primitive); 1407e5c31af7Sopenharmony_ci } 1408e5c31af7Sopenharmony_ci 1409e5c31af7Sopenharmony_ci // compare 1410e5c31af7Sopenharmony_ci { 1411e5c31af7Sopenharmony_ci RasterizationArguments args; 1412e5c31af7Sopenharmony_ci TriangleSceneSpec scene; 1413e5c31af7Sopenharmony_ci 1414e5c31af7Sopenharmony_ci args.numSamples = m_numSamples; 1415e5c31af7Sopenharmony_ci args.subpixelBits = m_subpixelBits; 1416e5c31af7Sopenharmony_ci args.redBits = m_context.getRenderTarget().getPixelFormat().redBits; 1417e5c31af7Sopenharmony_ci args.greenBits = m_context.getRenderTarget().getPixelFormat().greenBits; 1418e5c31af7Sopenharmony_ci args.blueBits = m_context.getRenderTarget().getPixelFormat().blueBits; 1419e5c31af7Sopenharmony_ci 1420e5c31af7Sopenharmony_ci scene.triangles.swap(triangles); 1421e5c31af7Sopenharmony_ci 1422e5c31af7Sopenharmony_ci if (verifyTriangleGroupRasterization(resultImage, scene, args, m_testCtx.getLog(), tcu::VERIFICATIONMODE_WEAK)) 1423e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1424e5c31af7Sopenharmony_ci else 1425e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rendering"); 1426e5c31af7Sopenharmony_ci } 1427e5c31af7Sopenharmony_ci 1428e5c31af7Sopenharmony_ci return STOP; 1429e5c31af7Sopenharmony_ci} 1430e5c31af7Sopenharmony_ci 1431e5c31af7Sopenharmony_civoid CullingTest::generateVertices (std::vector<tcu::Vec4>& outData) const 1432e5c31af7Sopenharmony_ci{ 1433e5c31af7Sopenharmony_ci de::Random rnd(543210); 1434e5c31af7Sopenharmony_ci 1435e5c31af7Sopenharmony_ci outData.resize(6); 1436e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx) 1437e5c31af7Sopenharmony_ci { 1438e5c31af7Sopenharmony_ci outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f); 1439e5c31af7Sopenharmony_ci outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f); 1440e5c31af7Sopenharmony_ci outData[vtxNdx].z() = 0.0f; 1441e5c31af7Sopenharmony_ci outData[vtxNdx].w() = 1.0f; 1442e5c31af7Sopenharmony_ci } 1443e5c31af7Sopenharmony_ci} 1444e5c31af7Sopenharmony_ci 1445e5c31af7Sopenharmony_civoid CullingTest::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const 1446e5c31af7Sopenharmony_ci{ 1447e5c31af7Sopenharmony_ci const bool cullDirection = (m_cullMode == GL_FRONT) ^ (m_faceOrder == GL_CCW); 1448e5c31af7Sopenharmony_ci 1449e5c31af7Sopenharmony_ci // No triangles 1450e5c31af7Sopenharmony_ci if (m_cullMode == GL_FRONT_AND_BACK) 1451e5c31af7Sopenharmony_ci return; 1452e5c31af7Sopenharmony_ci 1453e5c31af7Sopenharmony_ci switch (m_primitive) 1454e5c31af7Sopenharmony_ci { 1455e5c31af7Sopenharmony_ci case GL_TRIANGLES: 1456e5c31af7Sopenharmony_ci { 1457e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3) 1458e5c31af7Sopenharmony_ci { 1459e5c31af7Sopenharmony_ci const tcu::Vec4& v0 = vertices[vtxNdx + 0]; 1460e5c31af7Sopenharmony_ci const tcu::Vec4& v1 = vertices[vtxNdx + 1]; 1461e5c31af7Sopenharmony_ci const tcu::Vec4& v2 = vertices[vtxNdx + 2]; 1462e5c31af7Sopenharmony_ci 1463e5c31af7Sopenharmony_ci if (triangleOrder(v0, v1, v2) != cullDirection) 1464e5c31af7Sopenharmony_ci { 1465e5c31af7Sopenharmony_ci TriangleSceneSpec::SceneTriangle tri; 1466e5c31af7Sopenharmony_ci tri.positions[0] = v0; tri.sharedEdge[0] = false; 1467e5c31af7Sopenharmony_ci tri.positions[1] = v1; tri.sharedEdge[1] = false; 1468e5c31af7Sopenharmony_ci tri.positions[2] = v2; tri.sharedEdge[2] = false; 1469e5c31af7Sopenharmony_ci 1470e5c31af7Sopenharmony_ci outTriangles.push_back(tri); 1471e5c31af7Sopenharmony_ci } 1472e5c31af7Sopenharmony_ci } 1473e5c31af7Sopenharmony_ci break; 1474e5c31af7Sopenharmony_ci } 1475e5c31af7Sopenharmony_ci 1476e5c31af7Sopenharmony_ci case GL_TRIANGLE_STRIP: 1477e5c31af7Sopenharmony_ci { 1478e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx) 1479e5c31af7Sopenharmony_ci { 1480e5c31af7Sopenharmony_ci const tcu::Vec4& v0 = vertices[vtxNdx + 0]; 1481e5c31af7Sopenharmony_ci const tcu::Vec4& v1 = vertices[vtxNdx + 1]; 1482e5c31af7Sopenharmony_ci const tcu::Vec4& v2 = vertices[vtxNdx + 2]; 1483e5c31af7Sopenharmony_ci 1484e5c31af7Sopenharmony_ci if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0))) 1485e5c31af7Sopenharmony_ci { 1486e5c31af7Sopenharmony_ci TriangleSceneSpec::SceneTriangle tri; 1487e5c31af7Sopenharmony_ci tri.positions[0] = v0; tri.sharedEdge[0] = false; 1488e5c31af7Sopenharmony_ci tri.positions[1] = v1; tri.sharedEdge[1] = false; 1489e5c31af7Sopenharmony_ci tri.positions[2] = v2; tri.sharedEdge[2] = false; 1490e5c31af7Sopenharmony_ci 1491e5c31af7Sopenharmony_ci outTriangles.push_back(tri); 1492e5c31af7Sopenharmony_ci } 1493e5c31af7Sopenharmony_ci } 1494e5c31af7Sopenharmony_ci break; 1495e5c31af7Sopenharmony_ci } 1496e5c31af7Sopenharmony_ci 1497e5c31af7Sopenharmony_ci case GL_TRIANGLE_FAN: 1498e5c31af7Sopenharmony_ci { 1499e5c31af7Sopenharmony_ci for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx) 1500e5c31af7Sopenharmony_ci { 1501e5c31af7Sopenharmony_ci const tcu::Vec4& v0 = vertices[0]; 1502e5c31af7Sopenharmony_ci const tcu::Vec4& v1 = vertices[vtxNdx + 0]; 1503e5c31af7Sopenharmony_ci const tcu::Vec4& v2 = vertices[vtxNdx + 1]; 1504e5c31af7Sopenharmony_ci 1505e5c31af7Sopenharmony_ci if (triangleOrder(v0, v1, v2) != cullDirection) 1506e5c31af7Sopenharmony_ci { 1507e5c31af7Sopenharmony_ci TriangleSceneSpec::SceneTriangle tri; 1508e5c31af7Sopenharmony_ci tri.positions[0] = v0; tri.sharedEdge[0] = false; 1509e5c31af7Sopenharmony_ci tri.positions[1] = v1; tri.sharedEdge[1] = false; 1510e5c31af7Sopenharmony_ci tri.positions[2] = v2; tri.sharedEdge[2] = false; 1511e5c31af7Sopenharmony_ci 1512e5c31af7Sopenharmony_ci outTriangles.push_back(tri); 1513e5c31af7Sopenharmony_ci } 1514e5c31af7Sopenharmony_ci } 1515e5c31af7Sopenharmony_ci break; 1516e5c31af7Sopenharmony_ci } 1517e5c31af7Sopenharmony_ci 1518e5c31af7Sopenharmony_ci default: 1519e5c31af7Sopenharmony_ci DE_ASSERT(false); 1520e5c31af7Sopenharmony_ci } 1521e5c31af7Sopenharmony_ci} 1522e5c31af7Sopenharmony_ci 1523e5c31af7Sopenharmony_cibool CullingTest::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const 1524e5c31af7Sopenharmony_ci{ 1525e5c31af7Sopenharmony_ci const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w(); 1526e5c31af7Sopenharmony_ci const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w(); 1527e5c31af7Sopenharmony_ci const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w(); 1528e5c31af7Sopenharmony_ci 1529e5c31af7Sopenharmony_ci // cross 1530e5c31af7Sopenharmony_ci return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) < 0; 1531e5c31af7Sopenharmony_ci} 1532e5c31af7Sopenharmony_ci 1533e5c31af7Sopenharmony_ciclass TriangleInterpolationTest : public BaseRenderingCase 1534e5c31af7Sopenharmony_ci{ 1535e5c31af7Sopenharmony_cipublic: 1536e5c31af7Sopenharmony_ci TriangleInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags); 1537e5c31af7Sopenharmony_ci ~TriangleInterpolationTest (void); 1538e5c31af7Sopenharmony_ci IterateResult iterate (void); 1539e5c31af7Sopenharmony_ci 1540e5c31af7Sopenharmony_ciprivate: 1541e5c31af7Sopenharmony_ci void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const; 1542e5c31af7Sopenharmony_ci void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const; 1543e5c31af7Sopenharmony_ci 1544e5c31af7Sopenharmony_ci const glw::GLenum m_primitive; 1545e5c31af7Sopenharmony_ci const bool m_projective; 1546e5c31af7Sopenharmony_ci const int m_iterationCount; 1547e5c31af7Sopenharmony_ci 1548e5c31af7Sopenharmony_ci int m_iteration; 1549e5c31af7Sopenharmony_ci bool m_allIterationsPassed; 1550e5c31af7Sopenharmony_ci}; 1551e5c31af7Sopenharmony_ci 1552e5c31af7Sopenharmony_ciTriangleInterpolationTest::TriangleInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags) 1553e5c31af7Sopenharmony_ci : BaseRenderingCase (ctx, name, desc) 1554e5c31af7Sopenharmony_ci , m_primitive (primitive) 1555e5c31af7Sopenharmony_ci , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0) 1556e5c31af7Sopenharmony_ci , m_iterationCount (3) 1557e5c31af7Sopenharmony_ci , m_iteration (0) 1558e5c31af7Sopenharmony_ci , m_allIterationsPassed (true) 1559e5c31af7Sopenharmony_ci{ 1560e5c31af7Sopenharmony_ci} 1561e5c31af7Sopenharmony_ci 1562e5c31af7Sopenharmony_ciTriangleInterpolationTest::~TriangleInterpolationTest (void) 1563e5c31af7Sopenharmony_ci{ 1564e5c31af7Sopenharmony_ci deinit(); 1565e5c31af7Sopenharmony_ci} 1566e5c31af7Sopenharmony_ci 1567e5c31af7Sopenharmony_ciTriangleInterpolationTest::IterateResult TriangleInterpolationTest::iterate (void) 1568e5c31af7Sopenharmony_ci{ 1569e5c31af7Sopenharmony_ci const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount); 1570e5c31af7Sopenharmony_ci const tcu::ScopedLogSection section (m_testCtx.getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription); 1571e5c31af7Sopenharmony_ci tcu::Surface resultImage (m_renderSize, m_renderSize); 1572e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> drawBuffer; 1573e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> colorBuffer; 1574e5c31af7Sopenharmony_ci std::vector<TriangleSceneSpec::SceneTriangle> triangles; 1575e5c31af7Sopenharmony_ci 1576e5c31af7Sopenharmony_ci // generate scene 1577e5c31af7Sopenharmony_ci generateVertices(m_iteration, drawBuffer, colorBuffer); 1578e5c31af7Sopenharmony_ci extractTriangles(triangles, drawBuffer, colorBuffer); 1579e5c31af7Sopenharmony_ci 1580e5c31af7Sopenharmony_ci // log 1581e5c31af7Sopenharmony_ci { 1582e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage; 1583e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx) 1584e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage; 1585e5c31af7Sopenharmony_ci } 1586e5c31af7Sopenharmony_ci 1587e5c31af7Sopenharmony_ci // draw image 1588e5c31af7Sopenharmony_ci drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitive); 1589e5c31af7Sopenharmony_ci 1590e5c31af7Sopenharmony_ci // compare 1591e5c31af7Sopenharmony_ci { 1592e5c31af7Sopenharmony_ci RasterizationArguments args; 1593e5c31af7Sopenharmony_ci TriangleSceneSpec scene; 1594e5c31af7Sopenharmony_ci 1595e5c31af7Sopenharmony_ci args.numSamples = m_numSamples; 1596e5c31af7Sopenharmony_ci args.subpixelBits = m_subpixelBits; 1597e5c31af7Sopenharmony_ci args.redBits = m_context.getRenderTarget().getPixelFormat().redBits; 1598e5c31af7Sopenharmony_ci args.greenBits = m_context.getRenderTarget().getPixelFormat().greenBits; 1599e5c31af7Sopenharmony_ci args.blueBits = m_context.getRenderTarget().getPixelFormat().blueBits; 1600e5c31af7Sopenharmony_ci 1601e5c31af7Sopenharmony_ci scene.triangles.swap(triangles); 1602e5c31af7Sopenharmony_ci 1603e5c31af7Sopenharmony_ci if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_testCtx.getLog())) 1604e5c31af7Sopenharmony_ci m_allIterationsPassed = false; 1605e5c31af7Sopenharmony_ci } 1606e5c31af7Sopenharmony_ci 1607e5c31af7Sopenharmony_ci // result 1608e5c31af7Sopenharmony_ci if (++m_iteration == m_iterationCount) 1609e5c31af7Sopenharmony_ci { 1610e5c31af7Sopenharmony_ci if (m_allIterationsPassed) 1611e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1612e5c31af7Sopenharmony_ci else 1613e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Found invalid pixel values"); 1614e5c31af7Sopenharmony_ci 1615e5c31af7Sopenharmony_ci return STOP; 1616e5c31af7Sopenharmony_ci } 1617e5c31af7Sopenharmony_ci else 1618e5c31af7Sopenharmony_ci return CONTINUE; 1619e5c31af7Sopenharmony_ci} 1620e5c31af7Sopenharmony_ci 1621e5c31af7Sopenharmony_civoid TriangleInterpolationTest::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const 1622e5c31af7Sopenharmony_ci{ 1623e5c31af7Sopenharmony_ci // use only red, green and blue 1624e5c31af7Sopenharmony_ci const tcu::Vec4 colors[] = 1625e5c31af7Sopenharmony_ci { 1626e5c31af7Sopenharmony_ci tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), 1627e5c31af7Sopenharmony_ci tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), 1628e5c31af7Sopenharmony_ci tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), 1629e5c31af7Sopenharmony_ci }; 1630e5c31af7Sopenharmony_ci 1631e5c31af7Sopenharmony_ci de::Random rnd(123 + iteration * 1000 + (int)m_primitive); 1632e5c31af7Sopenharmony_ci 1633e5c31af7Sopenharmony_ci outVertices.resize(6); 1634e5c31af7Sopenharmony_ci outColors.resize(6); 1635e5c31af7Sopenharmony_ci 1636e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx) 1637e5c31af7Sopenharmony_ci { 1638e5c31af7Sopenharmony_ci outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f); 1639e5c31af7Sopenharmony_ci outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f); 1640e5c31af7Sopenharmony_ci outVertices[vtxNdx].z() = 0.0f; 1641e5c31af7Sopenharmony_ci 1642e5c31af7Sopenharmony_ci if (!m_projective) 1643e5c31af7Sopenharmony_ci outVertices[vtxNdx].w() = 1.0f; 1644e5c31af7Sopenharmony_ci else 1645e5c31af7Sopenharmony_ci { 1646e5c31af7Sopenharmony_ci const float w = rnd.getFloat(0.2f, 4.0f); 1647e5c31af7Sopenharmony_ci 1648e5c31af7Sopenharmony_ci outVertices[vtxNdx].x() *= w; 1649e5c31af7Sopenharmony_ci outVertices[vtxNdx].y() *= w; 1650e5c31af7Sopenharmony_ci outVertices[vtxNdx].z() *= w; 1651e5c31af7Sopenharmony_ci outVertices[vtxNdx].w() = w; 1652e5c31af7Sopenharmony_ci } 1653e5c31af7Sopenharmony_ci 1654e5c31af7Sopenharmony_ci outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)]; 1655e5c31af7Sopenharmony_ci } 1656e5c31af7Sopenharmony_ci} 1657e5c31af7Sopenharmony_ci 1658e5c31af7Sopenharmony_civoid TriangleInterpolationTest::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const 1659e5c31af7Sopenharmony_ci{ 1660e5c31af7Sopenharmony_ci switch (m_primitive) 1661e5c31af7Sopenharmony_ci { 1662e5c31af7Sopenharmony_ci case GL_TRIANGLES: 1663e5c31af7Sopenharmony_ci { 1664e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3) 1665e5c31af7Sopenharmony_ci { 1666e5c31af7Sopenharmony_ci TriangleSceneSpec::SceneTriangle tri; 1667e5c31af7Sopenharmony_ci tri.positions[0] = vertices[vtxNdx + 0]; 1668e5c31af7Sopenharmony_ci tri.positions[1] = vertices[vtxNdx + 1]; 1669e5c31af7Sopenharmony_ci tri.positions[2] = vertices[vtxNdx + 2]; 1670e5c31af7Sopenharmony_ci tri.sharedEdge[0] = false; 1671e5c31af7Sopenharmony_ci tri.sharedEdge[1] = false; 1672e5c31af7Sopenharmony_ci tri.sharedEdge[2] = false; 1673e5c31af7Sopenharmony_ci 1674e5c31af7Sopenharmony_ci tri.colors[0] = colors[vtxNdx + 0]; 1675e5c31af7Sopenharmony_ci tri.colors[1] = colors[vtxNdx + 1]; 1676e5c31af7Sopenharmony_ci tri.colors[2] = colors[vtxNdx + 2]; 1677e5c31af7Sopenharmony_ci 1678e5c31af7Sopenharmony_ci outTriangles.push_back(tri); 1679e5c31af7Sopenharmony_ci } 1680e5c31af7Sopenharmony_ci break; 1681e5c31af7Sopenharmony_ci } 1682e5c31af7Sopenharmony_ci 1683e5c31af7Sopenharmony_ci case GL_TRIANGLE_STRIP: 1684e5c31af7Sopenharmony_ci { 1685e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx) 1686e5c31af7Sopenharmony_ci { 1687e5c31af7Sopenharmony_ci TriangleSceneSpec::SceneTriangle tri; 1688e5c31af7Sopenharmony_ci tri.positions[0] = vertices[vtxNdx + 0]; 1689e5c31af7Sopenharmony_ci tri.positions[1] = vertices[vtxNdx + 1]; 1690e5c31af7Sopenharmony_ci tri.positions[2] = vertices[vtxNdx + 2]; 1691e5c31af7Sopenharmony_ci tri.sharedEdge[0] = false; 1692e5c31af7Sopenharmony_ci tri.sharedEdge[1] = false; 1693e5c31af7Sopenharmony_ci tri.sharedEdge[2] = false; 1694e5c31af7Sopenharmony_ci 1695e5c31af7Sopenharmony_ci tri.colors[0] = colors[vtxNdx + 0]; 1696e5c31af7Sopenharmony_ci tri.colors[1] = colors[vtxNdx + 1]; 1697e5c31af7Sopenharmony_ci tri.colors[2] = colors[vtxNdx + 2]; 1698e5c31af7Sopenharmony_ci 1699e5c31af7Sopenharmony_ci outTriangles.push_back(tri); 1700e5c31af7Sopenharmony_ci } 1701e5c31af7Sopenharmony_ci break; 1702e5c31af7Sopenharmony_ci } 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci case GL_TRIANGLE_FAN: 1705e5c31af7Sopenharmony_ci { 1706e5c31af7Sopenharmony_ci for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx) 1707e5c31af7Sopenharmony_ci { 1708e5c31af7Sopenharmony_ci TriangleSceneSpec::SceneTriangle tri; 1709e5c31af7Sopenharmony_ci tri.positions[0] = vertices[0]; 1710e5c31af7Sopenharmony_ci tri.positions[1] = vertices[vtxNdx + 0]; 1711e5c31af7Sopenharmony_ci tri.positions[2] = vertices[vtxNdx + 1]; 1712e5c31af7Sopenharmony_ci tri.sharedEdge[0] = false; 1713e5c31af7Sopenharmony_ci tri.sharedEdge[1] = false; 1714e5c31af7Sopenharmony_ci tri.sharedEdge[2] = false; 1715e5c31af7Sopenharmony_ci 1716e5c31af7Sopenharmony_ci tri.colors[0] = colors[0]; 1717e5c31af7Sopenharmony_ci tri.colors[1] = colors[vtxNdx + 0]; 1718e5c31af7Sopenharmony_ci tri.colors[2] = colors[vtxNdx + 1]; 1719e5c31af7Sopenharmony_ci 1720e5c31af7Sopenharmony_ci outTriangles.push_back(tri); 1721e5c31af7Sopenharmony_ci } 1722e5c31af7Sopenharmony_ci break; 1723e5c31af7Sopenharmony_ci } 1724e5c31af7Sopenharmony_ci 1725e5c31af7Sopenharmony_ci default: 1726e5c31af7Sopenharmony_ci DE_ASSERT(false); 1727e5c31af7Sopenharmony_ci } 1728e5c31af7Sopenharmony_ci} 1729e5c31af7Sopenharmony_ci 1730e5c31af7Sopenharmony_ciclass LineInterpolationTest : public BaseRenderingCase 1731e5c31af7Sopenharmony_ci{ 1732e5c31af7Sopenharmony_cipublic: 1733e5c31af7Sopenharmony_ci LineInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, float lineWidth); 1734e5c31af7Sopenharmony_ci ~LineInterpolationTest (void); 1735e5c31af7Sopenharmony_ci IterateResult iterate (void); 1736e5c31af7Sopenharmony_ci 1737e5c31af7Sopenharmony_ciprivate: 1738e5c31af7Sopenharmony_ci void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const; 1739e5c31af7Sopenharmony_ci void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const; 1740e5c31af7Sopenharmony_ci 1741e5c31af7Sopenharmony_ci const glw::GLenum m_primitive; 1742e5c31af7Sopenharmony_ci const bool m_projective; 1743e5c31af7Sopenharmony_ci const int m_iterationCount; 1744e5c31af7Sopenharmony_ci 1745e5c31af7Sopenharmony_ci int m_iteration; 1746e5c31af7Sopenharmony_ci tcu::ResultCollector m_result; 1747e5c31af7Sopenharmony_ci}; 1748e5c31af7Sopenharmony_ci 1749e5c31af7Sopenharmony_ciLineInterpolationTest::LineInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, float lineWidth) 1750e5c31af7Sopenharmony_ci : BaseRenderingCase (ctx, name, desc) 1751e5c31af7Sopenharmony_ci , m_primitive (primitive) 1752e5c31af7Sopenharmony_ci , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0) 1753e5c31af7Sopenharmony_ci , m_iterationCount (3) 1754e5c31af7Sopenharmony_ci , m_iteration (0) 1755e5c31af7Sopenharmony_ci{ 1756e5c31af7Sopenharmony_ci m_lineWidth = lineWidth; 1757e5c31af7Sopenharmony_ci} 1758e5c31af7Sopenharmony_ci 1759e5c31af7Sopenharmony_ciLineInterpolationTest::~LineInterpolationTest (void) 1760e5c31af7Sopenharmony_ci{ 1761e5c31af7Sopenharmony_ci deinit(); 1762e5c31af7Sopenharmony_ci} 1763e5c31af7Sopenharmony_ci 1764e5c31af7Sopenharmony_ciLineInterpolationTest::IterateResult LineInterpolationTest::iterate (void) 1765e5c31af7Sopenharmony_ci{ 1766e5c31af7Sopenharmony_ci const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount); 1767e5c31af7Sopenharmony_ci const tcu::ScopedLogSection section (m_testCtx.getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription); 1768e5c31af7Sopenharmony_ci tcu::Surface resultImage (m_renderSize, m_renderSize); 1769e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> drawBuffer; 1770e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> colorBuffer; 1771e5c31af7Sopenharmony_ci std::vector<LineSceneSpec::SceneLine> lines; 1772e5c31af7Sopenharmony_ci 1773e5c31af7Sopenharmony_ci // generate scene 1774e5c31af7Sopenharmony_ci generateVertices(m_iteration, drawBuffer, colorBuffer); 1775e5c31af7Sopenharmony_ci extractLines(lines, drawBuffer, colorBuffer); 1776e5c31af7Sopenharmony_ci 1777e5c31af7Sopenharmony_ci // log 1778e5c31af7Sopenharmony_ci { 1779e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage; 1780e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx) 1781e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage; 1782e5c31af7Sopenharmony_ci } 1783e5c31af7Sopenharmony_ci 1784e5c31af7Sopenharmony_ci // draw image 1785e5c31af7Sopenharmony_ci drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitive); 1786e5c31af7Sopenharmony_ci 1787e5c31af7Sopenharmony_ci // compare 1788e5c31af7Sopenharmony_ci { 1789e5c31af7Sopenharmony_ci RasterizationArguments args; 1790e5c31af7Sopenharmony_ci LineSceneSpec scene; 1791e5c31af7Sopenharmony_ci LineInterpolationMethod iterationResult; 1792e5c31af7Sopenharmony_ci 1793e5c31af7Sopenharmony_ci args.numSamples = m_numSamples; 1794e5c31af7Sopenharmony_ci args.subpixelBits = m_subpixelBits; 1795e5c31af7Sopenharmony_ci args.redBits = m_context.getRenderTarget().getPixelFormat().redBits; 1796e5c31af7Sopenharmony_ci args.greenBits = m_context.getRenderTarget().getPixelFormat().greenBits; 1797e5c31af7Sopenharmony_ci args.blueBits = m_context.getRenderTarget().getPixelFormat().blueBits; 1798e5c31af7Sopenharmony_ci 1799e5c31af7Sopenharmony_ci scene.lines.swap(lines); 1800e5c31af7Sopenharmony_ci scene.lineWidth = m_lineWidth; 1801e5c31af7Sopenharmony_ci scene.stippleFactor = 1; 1802e5c31af7Sopenharmony_ci scene.stipplePattern = 0xFFFF; 1803e5c31af7Sopenharmony_ci scene.allowNonProjectedInterpolation = true; 1804e5c31af7Sopenharmony_ci 1805e5c31af7Sopenharmony_ci 1806e5c31af7Sopenharmony_ci iterationResult = verifyLineGroupInterpolation(resultImage, scene, args, m_testCtx.getLog()); 1807e5c31af7Sopenharmony_ci switch (iterationResult) 1808e5c31af7Sopenharmony_ci { 1809e5c31af7Sopenharmony_ci case tcu::LINEINTERPOLATION_STRICTLY_CORRECT: 1810e5c31af7Sopenharmony_ci // line interpolation matches the specification 1811e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_PASS, "Pass"); 1812e5c31af7Sopenharmony_ci break; 1813e5c31af7Sopenharmony_ci 1814e5c31af7Sopenharmony_ci case tcu::LINEINTERPOLATION_PROJECTED: 1815e5c31af7Sopenharmony_ci // line interpolation weights are otherwise correct, but they are projected onto major axis 1816e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 1817e5c31af7Sopenharmony_ci << "Interpolation was calculated using coordinates projected onto major axis. " 1818e5c31af7Sopenharmony_ci "This method does not produce the same values as the non-projecting method defined in the specification." 1819e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1820e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Interpolation was calculated using projected coordinateds"); 1821e5c31af7Sopenharmony_ci break; 1822e5c31af7Sopenharmony_ci 1823e5c31af7Sopenharmony_ci case tcu::LINEINTERPOLATION_INCORRECT: 1824e5c31af7Sopenharmony_ci if (scene.lineWidth != 1.0f && m_numSamples > 1) 1825e5c31af7Sopenharmony_ci { 1826e5c31af7Sopenharmony_ci // multisampled wide lines might not be supported 1827e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Interpolation of multisampled wide lines failed"); 1828e5c31af7Sopenharmony_ci } 1829e5c31af7Sopenharmony_ci else 1830e5c31af7Sopenharmony_ci { 1831e5c31af7Sopenharmony_ci // line interpolation is incorrect 1832e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_FAIL, "Found invalid pixel values"); 1833e5c31af7Sopenharmony_ci } 1834e5c31af7Sopenharmony_ci break; 1835e5c31af7Sopenharmony_ci 1836e5c31af7Sopenharmony_ci default: 1837e5c31af7Sopenharmony_ci DE_ASSERT(false); 1838e5c31af7Sopenharmony_ci break; 1839e5c31af7Sopenharmony_ci } 1840e5c31af7Sopenharmony_ci } 1841e5c31af7Sopenharmony_ci 1842e5c31af7Sopenharmony_ci // result 1843e5c31af7Sopenharmony_ci if (++m_iteration == m_iterationCount) 1844e5c31af7Sopenharmony_ci { 1845e5c31af7Sopenharmony_ci m_result.setTestContextResult(m_testCtx); 1846e5c31af7Sopenharmony_ci return STOP; 1847e5c31af7Sopenharmony_ci } 1848e5c31af7Sopenharmony_ci else 1849e5c31af7Sopenharmony_ci return CONTINUE; 1850e5c31af7Sopenharmony_ci} 1851e5c31af7Sopenharmony_ci 1852e5c31af7Sopenharmony_civoid LineInterpolationTest::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const 1853e5c31af7Sopenharmony_ci{ 1854e5c31af7Sopenharmony_ci // use only red, green and blue 1855e5c31af7Sopenharmony_ci const tcu::Vec4 colors[] = 1856e5c31af7Sopenharmony_ci { 1857e5c31af7Sopenharmony_ci tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), 1858e5c31af7Sopenharmony_ci tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), 1859e5c31af7Sopenharmony_ci tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), 1860e5c31af7Sopenharmony_ci }; 1861e5c31af7Sopenharmony_ci 1862e5c31af7Sopenharmony_ci de::Random rnd(123 + iteration * 1000 + (int)m_primitive); 1863e5c31af7Sopenharmony_ci 1864e5c31af7Sopenharmony_ci outVertices.resize(6); 1865e5c31af7Sopenharmony_ci outColors.resize(6); 1866e5c31af7Sopenharmony_ci 1867e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx) 1868e5c31af7Sopenharmony_ci { 1869e5c31af7Sopenharmony_ci outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f); 1870e5c31af7Sopenharmony_ci outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f); 1871e5c31af7Sopenharmony_ci outVertices[vtxNdx].z() = 0.0f; 1872e5c31af7Sopenharmony_ci 1873e5c31af7Sopenharmony_ci if (!m_projective) 1874e5c31af7Sopenharmony_ci outVertices[vtxNdx].w() = 1.0f; 1875e5c31af7Sopenharmony_ci else 1876e5c31af7Sopenharmony_ci { 1877e5c31af7Sopenharmony_ci const float w = rnd.getFloat(0.2f, 4.0f); 1878e5c31af7Sopenharmony_ci 1879e5c31af7Sopenharmony_ci outVertices[vtxNdx].x() *= w; 1880e5c31af7Sopenharmony_ci outVertices[vtxNdx].y() *= w; 1881e5c31af7Sopenharmony_ci outVertices[vtxNdx].z() *= w; 1882e5c31af7Sopenharmony_ci outVertices[vtxNdx].w() = w; 1883e5c31af7Sopenharmony_ci } 1884e5c31af7Sopenharmony_ci 1885e5c31af7Sopenharmony_ci outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)]; 1886e5c31af7Sopenharmony_ci } 1887e5c31af7Sopenharmony_ci} 1888e5c31af7Sopenharmony_ci 1889e5c31af7Sopenharmony_civoid LineInterpolationTest::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const 1890e5c31af7Sopenharmony_ci{ 1891e5c31af7Sopenharmony_ci switch (m_primitive) 1892e5c31af7Sopenharmony_ci { 1893e5c31af7Sopenharmony_ci case GL_LINES: 1894e5c31af7Sopenharmony_ci { 1895e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2) 1896e5c31af7Sopenharmony_ci { 1897e5c31af7Sopenharmony_ci LineSceneSpec::SceneLine line; 1898e5c31af7Sopenharmony_ci line.positions[0] = vertices[vtxNdx + 0]; 1899e5c31af7Sopenharmony_ci line.positions[1] = vertices[vtxNdx + 1]; 1900e5c31af7Sopenharmony_ci 1901e5c31af7Sopenharmony_ci line.colors[0] = colors[vtxNdx + 0]; 1902e5c31af7Sopenharmony_ci line.colors[1] = colors[vtxNdx + 1]; 1903e5c31af7Sopenharmony_ci 1904e5c31af7Sopenharmony_ci outLines.push_back(line); 1905e5c31af7Sopenharmony_ci } 1906e5c31af7Sopenharmony_ci break; 1907e5c31af7Sopenharmony_ci } 1908e5c31af7Sopenharmony_ci 1909e5c31af7Sopenharmony_ci case GL_LINE_STRIP: 1910e5c31af7Sopenharmony_ci { 1911e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx) 1912e5c31af7Sopenharmony_ci { 1913e5c31af7Sopenharmony_ci LineSceneSpec::SceneLine line; 1914e5c31af7Sopenharmony_ci line.positions[0] = vertices[vtxNdx + 0]; 1915e5c31af7Sopenharmony_ci line.positions[1] = vertices[vtxNdx + 1]; 1916e5c31af7Sopenharmony_ci 1917e5c31af7Sopenharmony_ci line.colors[0] = colors[vtxNdx + 0]; 1918e5c31af7Sopenharmony_ci line.colors[1] = colors[vtxNdx + 1]; 1919e5c31af7Sopenharmony_ci 1920e5c31af7Sopenharmony_ci outLines.push_back(line); 1921e5c31af7Sopenharmony_ci } 1922e5c31af7Sopenharmony_ci break; 1923e5c31af7Sopenharmony_ci } 1924e5c31af7Sopenharmony_ci 1925e5c31af7Sopenharmony_ci case GL_LINE_LOOP: 1926e5c31af7Sopenharmony_ci { 1927e5c31af7Sopenharmony_ci for (int vtxNdx = 0; vtxNdx < (int)vertices.size(); ++vtxNdx) 1928e5c31af7Sopenharmony_ci { 1929e5c31af7Sopenharmony_ci LineSceneSpec::SceneLine line; 1930e5c31af7Sopenharmony_ci line.positions[0] = vertices[(vtxNdx + 0) % (int)vertices.size()]; 1931e5c31af7Sopenharmony_ci line.positions[1] = vertices[(vtxNdx + 1) % (int)vertices.size()]; 1932e5c31af7Sopenharmony_ci 1933e5c31af7Sopenharmony_ci line.colors[0] = colors[(vtxNdx + 0) % (int)vertices.size()]; 1934e5c31af7Sopenharmony_ci line.colors[1] = colors[(vtxNdx + 1) % (int)vertices.size()]; 1935e5c31af7Sopenharmony_ci 1936e5c31af7Sopenharmony_ci outLines.push_back(line); 1937e5c31af7Sopenharmony_ci } 1938e5c31af7Sopenharmony_ci break; 1939e5c31af7Sopenharmony_ci } 1940e5c31af7Sopenharmony_ci 1941e5c31af7Sopenharmony_ci default: 1942e5c31af7Sopenharmony_ci DE_ASSERT(false); 1943e5c31af7Sopenharmony_ci } 1944e5c31af7Sopenharmony_ci} 1945e5c31af7Sopenharmony_ci 1946e5c31af7Sopenharmony_ci} // anonymous 1947e5c31af7Sopenharmony_ci 1948e5c31af7Sopenharmony_ciRasterizationTests::RasterizationTests (Context& context) 1949e5c31af7Sopenharmony_ci : TestCaseGroup(context, "rasterization", "Rasterization Tests") 1950e5c31af7Sopenharmony_ci{ 1951e5c31af7Sopenharmony_ci} 1952e5c31af7Sopenharmony_ci 1953e5c31af7Sopenharmony_ciRasterizationTests::~RasterizationTests (void) 1954e5c31af7Sopenharmony_ci{ 1955e5c31af7Sopenharmony_ci} 1956e5c31af7Sopenharmony_ci 1957e5c31af7Sopenharmony_civoid RasterizationTests::init (void) 1958e5c31af7Sopenharmony_ci{ 1959e5c31af7Sopenharmony_ci // .primitives 1960e5c31af7Sopenharmony_ci { 1961e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(m_testCtx, "primitives", "Primitive rasterization"); 1962e5c31af7Sopenharmony_ci 1963e5c31af7Sopenharmony_ci addChild(primitives); 1964e5c31af7Sopenharmony_ci 1965e5c31af7Sopenharmony_ci primitives->addChild(new TrianglesCase (m_context, "triangles", "Render primitives as GL_TRIANGLES, verify rasterization result")); 1966e5c31af7Sopenharmony_ci primitives->addChild(new TriangleStripCase (m_context, "triangle_strip", "Render primitives as GL_TRIANGLE_STRIP, verify rasterization result")); 1967e5c31af7Sopenharmony_ci primitives->addChild(new TriangleFanCase (m_context, "triangle_fan", "Render primitives as GL_TRIANGLE_FAN, verify rasterization result")); 1968e5c31af7Sopenharmony_ci primitives->addChild(new LinesCase (m_context, "lines", "Render primitives as GL_LINES, verify rasterization result", PRIMITIVEWIDENESS_NARROW)); 1969e5c31af7Sopenharmony_ci primitives->addChild(new LineStripCase (m_context, "line_strip", "Render primitives as GL_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW)); 1970e5c31af7Sopenharmony_ci primitives->addChild(new LineLoopCase (m_context, "line_loop", "Render primitives as GL_LINE_LOOP, verify rasterization result", PRIMITIVEWIDENESS_NARROW)); 1971e5c31af7Sopenharmony_ci primitives->addChild(new LinesCase (m_context, "lines_wide", "Render primitives as GL_LINES with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE)); 1972e5c31af7Sopenharmony_ci primitives->addChild(new LineStripCase (m_context, "line_strip_wide", "Render primitives as GL_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE)); 1973e5c31af7Sopenharmony_ci primitives->addChild(new LineLoopCase (m_context, "line_loop_wide", "Render primitives as GL_LINE_LOOP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE)); 1974e5c31af7Sopenharmony_ci primitives->addChild(new PointCase (m_context, "points", "Render primitives as GL_POINTS, verify rasterization result", PRIMITIVEWIDENESS_WIDE)); 1975e5c31af7Sopenharmony_ci } 1976e5c31af7Sopenharmony_ci 1977e5c31af7Sopenharmony_ci // .limits 1978e5c31af7Sopenharmony_ci { 1979e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const limits = new tcu::TestCaseGroup(m_testCtx, "limits", "Primitive width limits"); 1980e5c31af7Sopenharmony_ci 1981e5c31af7Sopenharmony_ci addChild(limits); 1982e5c31af7Sopenharmony_ci 1983e5c31af7Sopenharmony_ci limits->addChild(new PointSizeClampedTest(m_context, "points", "gl_PointSize is clamped to ALIASED_POINT_SIZE_RANGE")); 1984e5c31af7Sopenharmony_ci } 1985e5c31af7Sopenharmony_ci 1986e5c31af7Sopenharmony_ci // .fill_rules 1987e5c31af7Sopenharmony_ci { 1988e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(m_testCtx, "fill_rules", "Primitive fill rules"); 1989e5c31af7Sopenharmony_ci 1990e5c31af7Sopenharmony_ci addChild(fillRules); 1991e5c31af7Sopenharmony_ci 1992e5c31af7Sopenharmony_ci fillRules->addChild(new FillRuleCase(m_context, "basic_quad", "Verify fill rules", FillRuleCase::FILLRULECASE_BASIC)); 1993e5c31af7Sopenharmony_ci fillRules->addChild(new FillRuleCase(m_context, "basic_quad_reverse", "Verify fill rules", FillRuleCase::FILLRULECASE_REVERSED)); 1994e5c31af7Sopenharmony_ci fillRules->addChild(new FillRuleCase(m_context, "clipped_full", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_FULL)); 1995e5c31af7Sopenharmony_ci fillRules->addChild(new FillRuleCase(m_context, "clipped_partly", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_PARTIAL)); 1996e5c31af7Sopenharmony_ci fillRules->addChild(new FillRuleCase(m_context, "projected", "Verify fill rules", FillRuleCase::FILLRULECASE_PROJECTED)); 1997e5c31af7Sopenharmony_ci } 1998e5c31af7Sopenharmony_ci 1999e5c31af7Sopenharmony_ci // .culling 2000e5c31af7Sopenharmony_ci { 2001e5c31af7Sopenharmony_ci static const struct CullMode 2002e5c31af7Sopenharmony_ci { 2003e5c31af7Sopenharmony_ci glw::GLenum mode; 2004e5c31af7Sopenharmony_ci const char* prefix; 2005e5c31af7Sopenharmony_ci } cullModes[] = 2006e5c31af7Sopenharmony_ci { 2007e5c31af7Sopenharmony_ci { GL_FRONT, "front_" }, 2008e5c31af7Sopenharmony_ci { GL_BACK, "back_" }, 2009e5c31af7Sopenharmony_ci { GL_FRONT_AND_BACK, "both_" }, 2010e5c31af7Sopenharmony_ci }; 2011e5c31af7Sopenharmony_ci static const struct PrimitiveType 2012e5c31af7Sopenharmony_ci { 2013e5c31af7Sopenharmony_ci glw::GLenum type; 2014e5c31af7Sopenharmony_ci const char* name; 2015e5c31af7Sopenharmony_ci } primitiveTypes[] = 2016e5c31af7Sopenharmony_ci { 2017e5c31af7Sopenharmony_ci { GL_TRIANGLES, "triangles" }, 2018e5c31af7Sopenharmony_ci { GL_TRIANGLE_STRIP, "triangle_strip" }, 2019e5c31af7Sopenharmony_ci { GL_TRIANGLE_FAN, "triangle_fan" }, 2020e5c31af7Sopenharmony_ci }; 2021e5c31af7Sopenharmony_ci static const struct FrontFaceOrder 2022e5c31af7Sopenharmony_ci { 2023e5c31af7Sopenharmony_ci glw::GLenum mode; 2024e5c31af7Sopenharmony_ci const char* postfix; 2025e5c31af7Sopenharmony_ci } frontOrders[] = 2026e5c31af7Sopenharmony_ci { 2027e5c31af7Sopenharmony_ci { GL_CCW, "" }, 2028e5c31af7Sopenharmony_ci { GL_CW, "_reverse" }, 2029e5c31af7Sopenharmony_ci }; 2030e5c31af7Sopenharmony_ci 2031e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(m_testCtx, "culling", "Culling"); 2032e5c31af7Sopenharmony_ci 2033e5c31af7Sopenharmony_ci addChild(culling); 2034e5c31af7Sopenharmony_ci 2035e5c31af7Sopenharmony_ci for (int cullModeNdx = 0; cullModeNdx < DE_LENGTH_OF_ARRAY(cullModes); ++cullModeNdx) 2036e5c31af7Sopenharmony_ci for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx) 2037e5c31af7Sopenharmony_ci for (int frontOrderNdx = 0; frontOrderNdx < DE_LENGTH_OF_ARRAY(frontOrders); ++frontOrderNdx) 2038e5c31af7Sopenharmony_ci { 2039e5c31af7Sopenharmony_ci const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix; 2040e5c31af7Sopenharmony_ci 2041e5c31af7Sopenharmony_ci culling->addChild(new CullingTest(m_context, name.c_str(), "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode)); 2042e5c31af7Sopenharmony_ci } 2043e5c31af7Sopenharmony_ci } 2044e5c31af7Sopenharmony_ci 2045e5c31af7Sopenharmony_ci // .interpolation 2046e5c31af7Sopenharmony_ci { 2047e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(m_testCtx, "interpolation", "Test interpolation"); 2048e5c31af7Sopenharmony_ci 2049e5c31af7Sopenharmony_ci addChild(interpolation); 2050e5c31af7Sopenharmony_ci 2051e5c31af7Sopenharmony_ci // .basic 2052e5c31af7Sopenharmony_ci { 2053e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(m_testCtx, "basic", "Non-projective interpolation"); 2054e5c31af7Sopenharmony_ci 2055e5c31af7Sopenharmony_ci interpolation->addChild(basic); 2056e5c31af7Sopenharmony_ci 2057e5c31af7Sopenharmony_ci basic->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle interpolation", GL_TRIANGLES, INTERPOLATIONFLAGS_NONE)); 2058e5c31af7Sopenharmony_ci basic->addChild(new TriangleInterpolationTest (m_context, "triangle_strip", "Verify triangle strip interpolation", GL_TRIANGLE_STRIP, INTERPOLATIONFLAGS_NONE)); 2059e5c31af7Sopenharmony_ci basic->addChild(new TriangleInterpolationTest (m_context, "triangle_fan", "Verify triangle fan interpolation", GL_TRIANGLE_FAN, INTERPOLATIONFLAGS_NONE)); 2060e5c31af7Sopenharmony_ci basic->addChild(new LineInterpolationTest (m_context, "lines", "Verify line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, 1.0f)); 2061e5c31af7Sopenharmony_ci basic->addChild(new LineInterpolationTest (m_context, "line_strip", "Verify line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_NONE, 1.0f)); 2062e5c31af7Sopenharmony_ci basic->addChild(new LineInterpolationTest (m_context, "line_loop", "Verify line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_NONE, 1.0f)); 2063e5c31af7Sopenharmony_ci basic->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, 5.0f)); 2064e5c31af7Sopenharmony_ci basic->addChild(new LineInterpolationTest (m_context, "line_strip_wide", "Verify wide line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_NONE, 5.0f)); 2065e5c31af7Sopenharmony_ci basic->addChild(new LineInterpolationTest (m_context, "line_loop_wide", "Verify wide line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_NONE, 5.0f)); 2066e5c31af7Sopenharmony_ci } 2067e5c31af7Sopenharmony_ci 2068e5c31af7Sopenharmony_ci // .projected 2069e5c31af7Sopenharmony_ci { 2070e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(m_testCtx, "projected", "Projective interpolation"); 2071e5c31af7Sopenharmony_ci 2072e5c31af7Sopenharmony_ci interpolation->addChild(projected); 2073e5c31af7Sopenharmony_ci 2074e5c31af7Sopenharmony_ci projected->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle interpolation", GL_TRIANGLES, INTERPOLATIONFLAGS_PROJECTED)); 2075e5c31af7Sopenharmony_ci projected->addChild(new TriangleInterpolationTest (m_context, "triangle_strip", "Verify triangle strip interpolation", GL_TRIANGLE_STRIP, INTERPOLATIONFLAGS_PROJECTED)); 2076e5c31af7Sopenharmony_ci projected->addChild(new TriangleInterpolationTest (m_context, "triangle_fan", "Verify triangle fan interpolation", GL_TRIANGLE_FAN, INTERPOLATIONFLAGS_PROJECTED)); 2077e5c31af7Sopenharmony_ci projected->addChild(new LineInterpolationTest (m_context, "lines", "Verify line interpolation", GL_LINES, INTERPOLATIONFLAGS_PROJECTED, 1.0f)); 2078e5c31af7Sopenharmony_ci projected->addChild(new LineInterpolationTest (m_context, "line_strip", "Verify line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, 1.0f)); 2079e5c31af7Sopenharmony_ci projected->addChild(new LineInterpolationTest (m_context, "line_loop", "Verify line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_PROJECTED, 1.0f)); 2080e5c31af7Sopenharmony_ci projected->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line interpolation", GL_LINES, INTERPOLATIONFLAGS_PROJECTED, 5.0f)); 2081e5c31af7Sopenharmony_ci projected->addChild(new LineInterpolationTest (m_context, "line_strip_wide", "Verify wide line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, 5.0f)); 2082e5c31af7Sopenharmony_ci projected->addChild(new LineInterpolationTest (m_context, "line_loop_wide", "Verify wide line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_PROJECTED, 5.0f)); 2083e5c31af7Sopenharmony_ci } 2084e5c31af7Sopenharmony_ci } 2085e5c31af7Sopenharmony_ci} 2086e5c31af7Sopenharmony_ci 2087e5c31af7Sopenharmony_ci} // Functional 2088e5c31af7Sopenharmony_ci} // gles2 2089e5c31af7Sopenharmony_ci} // deqp 2090