13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Multisample tests 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fMultisampleTests.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluCallLogWrapper.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp" 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h" 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw; 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog; 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2; 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3; 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4; 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic std::string sampleMaskToString (const std::vector<deUint32>& bitfield, int numBits) 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string result(numBits, '0'); 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // move from back to front and set chars to 1 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int wordNdx = 0; wordNdx < (int)bitfield.size(); ++wordNdx) 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int bit = 0; bit < 32; ++bit) 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int targetCharNdx = numBits - (wordNdx*32+bit) - 1; 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // beginning of the string reached 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (targetCharNdx < 0) 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((bitfield[wordNdx] >> bit) & 0x01) 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result[targetCharNdx] = '1'; 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Returns the number of words needed to represent mask of given length 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getEffectiveSampleMaskWordCount (int highestBitNdx) 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int wordSize = 32; 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maskLen = highestBitNdx + 1; 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ((maskLen - 1) / wordSize) + 1; // round_up(mask_len / wordSize) 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Creates sample mask with all less significant bits than nthBit set 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic std::vector<deUint32> genAllSetToNthBitSampleMask (int nthBit) 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int wordSize = 32; 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWords = getEffectiveSampleMaskWordCount(nthBit - 1); 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 topWordBits = (deUint32)(nthBit - (numWords - 1) * wordSize); 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> mask (numWords); 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < numWords - 1; ++ndx) 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mask[ndx] = 0xFFFFFFFF; 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mask[numWords - 1] = (deUint32)((1ULL << topWordBits) - (deUint32)1); 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return mask; 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SamplePosQueryCase : public TestCase 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SamplePosQueryCase (Context& context, const char* name, const char* desc); 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1173c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySamplePosQueryCase::SamplePosQueryCase (Context& context, const char* name, const char* desc) 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase(context, name, desc) 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SamplePosQueryCase::init (void) 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getNumSamples() == 0) 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("No multisample buffers"); 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1283c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySamplePosQueryCase::IterateResult SamplePosQueryCase::iterate (void) 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool error = false; 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enableLogging(true); 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_context.getRenderTarget().getNumSamples(); ++ndx) 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec2 samplePos = tcu::Vec2(-1, -1); 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.glGetMultisamplefv(GL_SAMPLE_POSITION, ndx, samplePos.getPtr()); 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.glGetError(), "getMultisamplefv"); 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check value range 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (samplePos.x() < 0.0f || samplePos.x() > 1.0f || 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry samplePos.y() < 0.0f || samplePos.y() > 1.0f) 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Sample " << ndx << " is not in valid range [0,1], got " << samplePos << tcu::TestLog::EndMessage; 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error = true; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!error) 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid sample pos"); 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Abstract base class handling common stuff for default fbo multisample cases. 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DefaultFBOMultisampleCase : public TestCase 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultFBOMultisampleCase (Context& context, const char* name, const char* desc, int desiredViewportSize); 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual ~DefaultFBOMultisampleCase (void); 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void init (void); 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void deinit (void); 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const; 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const; 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const; 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const; 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& c0, const Vec4& c1, const Vec4& c2, const Vec4& c3) const; 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const; 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void randomizeViewport (void); 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void readImage (tcu::Surface& dst) const; 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numSamples; 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_viewportSize; 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultFBOMultisampleCase (const DefaultFBOMultisampleCase& other); 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultFBOMultisampleCase& operator= (const DefaultFBOMultisampleCase& other); 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_desiredViewportSize; 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_attrPositionLoc; 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_attrColorLoc; 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_viewportX; 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_viewportY; 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random m_rnd; 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool m_initCalled; 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDefaultFBOMultisampleCase::DefaultFBOMultisampleCase (Context& context, const char* name, const char* desc, int desiredViewportSize) 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, desc) 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numSamples (0) 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_viewportSize (0) 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_desiredViewportSize (desiredViewportSize) 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_attrPositionLoc (-1) 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_attrColorLoc (-1) 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_viewportX (0) 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_viewportY (0) 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rnd (deStringHash(name)) 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_initCalled (false) 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDefaultFBOMultisampleCase::~DefaultFBOMultisampleCase (void) 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultFBOMultisampleCase::deinit(); 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::init (void) 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* vertShaderSource = 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#version 310 es\n" 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 a_position;\n" 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump vec4 a_color;\n" 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out mediump vec4 v_color;\n" 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = a_position;\n" 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = a_color;\n" 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* fragShaderSource = 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#version 310 es\n" 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump vec4 v_color;\n" 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(location = 0) out mediump vec4 o_color;\n" 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = v_color;\n" 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getNumSamples() <= 1) 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("No multisample buffers"); 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_initCalled = true; 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Query and log number of samples per pixel. 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_SAMPLES, &m_numSamples); 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv(GL_SAMPLES)"); 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "GL_SAMPLES = " << m_numSamples << TestLog::EndMessage; 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Prepare program. 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_program); 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource)); 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("Failed to compile program", DE_NULL, __FILE__, __LINE__); 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_attrPositionLoc = gl.getAttribLocation(m_program->getProgram(), "a_position"); 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_attrColorLoc = gl.getAttribLocation(m_program->getProgram(), "a_color"); 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation"); 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_attrPositionLoc < 0 || m_attrColorLoc < 0) 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("Invalid attribute locations", DE_NULL, __FILE__, __LINE__); 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Get suitable viewport size. 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_viewportSize = de::min<int>(m_desiredViewportSize, de::min(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())); 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry randomizeViewport(); 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::deinit (void) 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Do not try to call GL functions during case list creation 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_initCalled) 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float vertexPositions[] = 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry p0.x(), p0.y(), p0.z(), 1.0f, 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry p1.x(), p1.y(), p1.z(), 1.0f, 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry p2.x(), p2.y(), p2.z(), 1.0f 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float vertexColors[] = 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry c0.x(), c0.y(), c0.z(), c0.w(), 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry c1.x(), c1.y(), c1.z(), c1.w(), 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry c2.x(), c2.y(), c2.z(), c2.w(), 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Buffer vtxBuf (m_context.getRenderContext()); 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Buffer colBuf (m_context.getRenderContext()); 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::VertexArray vao (m_context.getRenderContext()); 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray"); 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, *vtxBuf); 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), &vertexPositions[0], GL_STATIC_DRAW); 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "vtx buf"); 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enableVertexAttribArray(m_attrPositionLoc); 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, DE_NULL); 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "vtx vertexAttribPointer"); 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, *colBuf); 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexColors), &vertexColors[0], GL_STATIC_DRAW); 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "col buf"); 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enableVertexAttribArray(m_attrColorLoc); 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, DE_NULL); 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "col vertexAttribPointer"); 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_program->getProgram()); 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_TRIANGLES, 0, 3); 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays"); 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTriangle(p0, p1, p2, color, color, color); 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTriangle(Vec3(p0.x(), p0.y(), 0.0f), 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3(p1.x(), p1.y(), 0.0f), 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3(p2.x(), p2.y(), 0.0f), 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry c0, c1, c2); 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTriangle(p0, p1, p2, color, color, color); 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& c0, const Vec4& c1, const Vec4& c2, const Vec4& c3) const 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTriangle(p0, p1, p2, c0, c1, c2); 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTriangle(p2, p1, p3, c2, c1, c3); 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderQuad(p0, p1, p2, p3, color, color, color, color); 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::randomizeViewport (void) 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_viewportX = m_rnd.getInt(0, m_context.getRenderTarget().getWidth() - m_viewportSize); 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_viewportY = m_rnd.getInt(0, m_context.getRenderTarget().getHeight() - m_viewportSize); 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(m_viewportX, m_viewportY, m_viewportSize, m_viewportSize); 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "viewport"); 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultFBOMultisampleCase::readImage (tcu::Surface& dst) const 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), m_viewportX, m_viewportY, dst.getAccess()); 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask inversion validity. 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the coverage masks obtained by masks set with glSampleMaski(mask) 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and glSampleMaski(~mask) are indeed each others' inverses. 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is done by drawing a pattern, with varying coverage values, 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * overlapped by a pattern that has inverted masks and is otherwise 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * identical. The resulting image is compared to one obtained by drawing 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the same pattern but with all-ones coverage masks. 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaskInvertCase : public DefaultFBOMultisampleCase 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MaskInvertCase (Context& context, const char* name, const char* description); 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~MaskInvertCase (void) {} 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void drawPattern (bool invert) const; 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskInvertCase::MaskInvertCase (Context& context, const char* name, const char* description) 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DefaultFBOMultisampleCase (context, name, description, 256) 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskInvertCase::init (void) 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check the test is even possible 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLint maxSampleMaskWords = 0; 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords); 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getEffectiveSampleMaskWordCount(m_numSamples - 1) > maxSampleMaskWords) 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS"); 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // normal init 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultFBOMultisampleCase::init(); 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskInvertCase::IterateResult MaskInvertCase::iterate (void) 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface renderedImgNoSampleCoverage (m_viewportSize, m_viewportSize); 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface renderedImgSampleCoverage (m_viewportSize, m_viewportSize); 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry randomizeViewport(); 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_BLEND); 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.blendEquation(GL_FUNC_ADD); 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.blendFunc(GL_ONE, GL_ONE); 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set blend"); 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples" << TestLog::EndMessage; 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage; 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_MASK disabled" << TestLog::EndMessage; 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawPattern(false); 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readImage(renderedImgNoSampleCoverage); 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImageNoSampleMask", "Rendered image with GL_SAMPLE_MASK disabled", renderedImgNoSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG); 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage; 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_SAMPLE_MASK); 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_SAMPLE_MASK)"); 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_MASK enabled, using non-inverted sample masks" << TestLog::EndMessage; 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawPattern(false); 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_MASK enabled, using inverted sample masks" << TestLog::EndMessage; 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawPattern(true); 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readImage(renderedImgSampleCoverage); 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImageSampleMask", "Rendered image with GL_SAMPLE_MASK enabled", renderedImgSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG); 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool passed = tcu::pixelThresholdCompare(log, 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "CoverageVsNoCoverage", 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Comparison of same pattern with GL_SAMPLE_MASK disabled and enabled", 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderedImgNoSampleCoverage, 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderedImgSampleCoverage, 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::RGBA(0), 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::COMPARE_LOG_ON_ERROR); 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (passed) 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage; 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry passed ? "Passed" : "Failed"); 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskInvertCase::drawPattern (bool invert) const 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numTriangles = 25; 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int triNdx = 0; triNdx < numTriangles; triNdx++) 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float angle0 = 2.0f*DE_PI * (float)triNdx / (float)numTriangles; 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float angle1 = 2.0f*DE_PI * (float)(triNdx + 0.5f) / (float)numTriangles; 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec4 color = Vec4(0.4f + (float)triNdx/(float)numTriangles*0.6f, 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.5f + (float)triNdx/(float)numTriangles*0.3f, 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.6f - (float)triNdx/(float)numTriangles*0.5f, 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.7f - (float)triNdx/(float)numTriangles*0.7f); 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int wordCount = getEffectiveSampleMaskWordCount(m_numSamples - 1); 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield finalWordBits = m_numSamples - 32 * ((m_numSamples-1) / 32); 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield finalWordMask = (GLbitfield)(1ULL << finalWordBits) - 1UL; 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int wordNdx = 0; wordNdx < wordCount; ++wordNdx) 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield rawMask = (GLbitfield)deUint32Hash(wordNdx * 32 + triNdx); 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield mask = (invert) ? (~rawMask) : (rawMask); 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isFinalWord = (wordNdx + 1) == wordCount; 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield maskMask = (isFinalWord) ? (finalWordMask) : (0xFFFFFFFFUL); // maskMask prevents setting coverage bits higher than sample count 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.sampleMaski(wordNdx, mask & maskMask); 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski"); 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTriangle(Vec2(0.0f, 0.0f), 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f), 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f), 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry color); 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask generation proportionality property. 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the number of coverage bits in a coverage mask set with 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * glSampleMaski is, on average, proportional to the number of set bits. 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws multiple frames, each time increasing the number of mask bits set 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and checks that the average color is changing appropriately. 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaskProportionalityCase : public DefaultFBOMultisampleCase 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MaskProportionalityCase (Context& context, const char* name, const char* description); 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~MaskProportionalityCase (void) {} 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numIterations; 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_currentIteration; 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 m_previousIterationColorSum; 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskProportionalityCase::MaskProportionalityCase (Context& context, const char* name, const char* description) 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DefaultFBOMultisampleCase (context, name, description, 32) 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numIterations (-1) 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_currentIteration (0) 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_previousIterationColorSum (-1) 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskProportionalityCase::init (void) 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check the test is even possible 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLint maxSampleMaskWords = 0; 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords); 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getEffectiveSampleMaskWordCount(m_numSamples - 1) > maxSampleMaskWords) 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS"); 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultFBOMultisampleCase::init(); 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set state 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_SAMPLE_MASK); 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_SAMPLE_MASK)"); 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "GL_SAMPLE_MASK is enabled" << TestLog::EndMessage; 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_numIterations = m_numSamples + 1; 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry randomizeViewport(); // \note Using the same viewport for every iteration since coverage mask may depend on window-relative pixel coordinate. 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskProportionalityCase::IterateResult MaskProportionalityCase::iterate (void) 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface renderedImg (m_viewportSize, m_viewportSize); 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 numPixels = (deInt32)renderedImg.getWidth()*(deInt32)renderedImg.getHeight(); 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_numIterations >= 0); 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage; 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Draw quad. 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec2 pt0 (-1.0f, -1.0f); 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec2 pt1 ( 1.0f, -1.0f); 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec2 pt2 (-1.0f, 1.0f); 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec2 pt3 ( 1.0f, 1.0f); 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec4 quadColor (1.0f, 0.0f, 0.0f, 1.0f); 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<deUint32> sampleMask = genAllSetToNthBitSampleMask(m_currentIteration); 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_currentIteration <= m_numSamples + 1); 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Drawing a red quad using sample mask 0b" << sampleMaskToString(sampleMask, m_numSamples) << TestLog::EndMessage; 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int wordNdx = 0; wordNdx < getEffectiveSampleMaskWordCount(m_numSamples - 1); ++wordNdx) 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield mask = (wordNdx < (int)sampleMask.size()) ? ((GLbitfield)(sampleMask[wordNdx])) : (0); 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.sampleMaski(wordNdx, mask); 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski"); 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderQuad(pt0, pt1, pt2, pt3, quadColor); 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read ang log image. 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readImage(renderedImg); 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG); 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute average red component in rendered image. 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 sumRed = 0; 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < renderedImg.getHeight(); y++) 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < renderedImg.getWidth(); x++) 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sumRed += renderedImg.getPixel(x, y).getRed(); 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Average red color component: " << de::floatToString((float)sumRed / 255.0f / (float)numPixels, 2) << TestLog::EndMessage; 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check if average color has decreased from previous frame's color. 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (sumRed < m_previousIterationColorSum) 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: Current average red color component is lower than previous" << TestLog::EndMessage; 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed"); 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check if coverage mask is not all-zeros if alpha or coverage value is 0 (or 1, if inverted). 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_currentIteration == 0 && sumRed != 0) 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: Image should be completely black" << TestLog::EndMessage; 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed"); 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_currentIteration == m_numIterations-1 && sumRed != 0xff*numPixels) 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: Image should be completely red" << TestLog::EndMessage; 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed"); 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_previousIterationColorSum = sumRed; 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_currentIteration++; 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_currentIteration >= m_numIterations) 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Success: Number of coverage mask bits set appears to be, on average, proportional to the number of set sample mask bits" << TestLog::EndMessage; 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed"); 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return CONTINUE; 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests coverage mask generation constancy property. 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the coverage mask created by GL_SAMPLE_MASK is constant at 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * given pixel coordinates. Draws two quads, with the second one fully 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * overlapping the first one such that at any given pixel, both quads have 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the same coverage mask value. This way, if the constancy property is 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * fulfilled, only the second quad should be visible. 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaskConstancyCase : public DefaultFBOMultisampleCase 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum CaseBits 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASEBIT_ALPHA_TO_COVERAGE = 1, //!< Use alpha-to-coverage. 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASEBIT_SAMPLE_COVERAGE = 2, //!< Use sample coverage. 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASEBIT_SAMPLE_COVERAGE_INVERTED = 4, //!< Inverted sample coverage. 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASEBIT_SAMPLE_MASK = 8, //!< Use sample mask. 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MaskConstancyCase (Context& context, const char* name, const char* description, deUint32 typeBits); 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~MaskConstancyCase (void) {} 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_isAlphaToCoverageCase; 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_isSampleCoverageCase; 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_isInvertedSampleCoverageCase; 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_isSampleMaskCase; 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskConstancyCase::MaskConstancyCase (Context& context, const char* name, const char* description, deUint32 typeBits) 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DefaultFBOMultisampleCase (context, name, description, 256) 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isAlphaToCoverageCase (0 != (typeBits & CASEBIT_ALPHA_TO_COVERAGE)) 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isSampleCoverageCase (0 != (typeBits & CASEBIT_SAMPLE_COVERAGE)) 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isInvertedSampleCoverageCase (0 != (typeBits & CASEBIT_SAMPLE_COVERAGE_INVERTED)) 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isSampleMaskCase (0 != (typeBits & CASEBIT_SAMPLE_MASK)) 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // CASEBIT_SAMPLE_COVERAGE_INVERT => CASEBIT_SAMPLE_COVERAGE 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((typeBits & CASEBIT_SAMPLE_COVERAGE) || ~(typeBits & CASEBIT_SAMPLE_COVERAGE_INVERTED)); 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_isSampleMaskCase); // no point testing non-sample-mask cases, they are checked already in gles3 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MaskConstancyCase::init (void) 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check the test is even possible 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_isSampleMaskCase) 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLint maxSampleMaskWords = 0; 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords); 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getEffectiveSampleMaskWordCount(m_numSamples - 1) > maxSampleMaskWords) 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS"); 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // normal init 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultFBOMultisampleCase::init(); 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaskConstancyCase::IterateResult MaskConstancyCase::iterate (void) 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface renderedImg (m_viewportSize, m_viewportSize); 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry randomizeViewport(); 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage; 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_isAlphaToCoverageCase) 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_SAMPLE_ALPHA_TO_COVERAGE); 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "enable GL_SAMPLE_ALPHA_TO_COVERAGE"); 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage; 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Color mask is TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage; 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_isSampleCoverageCase) 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_SAMPLE_COVERAGE); 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "enable GL_SAMPLE_COVERAGE"); 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage; 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_isSampleMaskCase) 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_SAMPLE_MASK); 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "enable GL_SAMPLE_MASK"); 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "GL_SAMPLE_MASK is enabled" << TestLog::EndMessage; 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Drawing several green quads, each fully overlapped by a red quad with the same " 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isAlphaToCoverageCase ? "alpha" : "") 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isAlphaToCoverageCase && (m_isSampleCoverageCase || m_isSampleMaskCase) ? " and " : "") 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isInvertedSampleCoverageCase ? "inverted " : "") 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isSampleCoverageCase ? "sample coverage" : "") 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isSampleCoverageCase && m_isSampleMaskCase ? " and " : "") 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isSampleMaskCase ? "sample mask" : "") 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " values" 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numQuadRowsCols = m_numSamples*4; 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int row = 0; row < numQuadRowsCols; row++) 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < numQuadRowsCols; col++) 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float x0 = (float)(col+0) / (float)numQuadRowsCols * 2.0f - 1.0f; 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float x1 = (float)(col+1) / (float)numQuadRowsCols * 2.0f - 1.0f; 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float y0 = (float)(row+0) / (float)numQuadRowsCols * 2.0f - 1.0f; 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float y1 = (float)(row+1) / (float)numQuadRowsCols * 2.0f - 1.0f; 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec4 baseGreen (0.0f, 1.0f, 0.0f, 0.0f); 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec4 baseRed (1.0f, 0.0f, 0.0f, 0.0f); 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec4 alpha0 (0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)col / (float)(numQuadRowsCols-1) : 1.0f); 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec4 alpha1 (0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)row / (float)(numQuadRowsCols-1) : 1.0f); 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_isSampleCoverageCase) 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float value = (float)(row*numQuadRowsCols + col) / (float)(numQuadRowsCols*numQuadRowsCols-1); 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.sampleCoverage(m_isInvertedSampleCoverageCase ? 1.0f - value : value, m_isInvertedSampleCoverageCase ? GL_TRUE : GL_FALSE); 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleCoverage"); 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_isSampleMaskCase) 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int wordCount = getEffectiveSampleMaskWordCount(m_numSamples - 1); 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield finalWordBits = m_numSamples - 32 * ((m_numSamples-1) / 32); 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield finalWordMask = (GLbitfield)(1ULL << finalWordBits) - 1UL; 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int wordNdx = 0; wordNdx < wordCount; ++wordNdx) 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield mask = (GLbitfield)deUint32Hash((col << (m_numSamples / 2)) ^ row); 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isFinalWord = (wordNdx + 1) == wordCount; 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield maskMask = (isFinalWord) ? (finalWordMask) : (0xFFFFFFFFUL); // maskMask prevents setting coverage bits higher than sample count 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.sampleMaski(wordNdx, mask & maskMask); 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski"); 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseGreen + alpha0, baseGreen + alpha1, baseGreen + alpha0, baseGreen + alpha1); 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseRed + alpha0, baseRed + alpha1, baseRed + alpha0, baseRed + alpha1); 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readImage(renderedImg); 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG); 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < renderedImg.getHeight(); y++) 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < renderedImg.getWidth(); x++) 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (renderedImg.getPixel(x, y).getGreen() > 0) 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: Non-zero green color component detected - should have been completely overwritten by red quad" << TestLog::EndMessage; 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed"); 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Success: Coverage mask appears to be constant at a given pixel coordinate with a given " 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isAlphaToCoverageCase ? "alpha" : "") 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "") 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_isSampleCoverageCase ? "coverage value" : "") 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed"); 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tests that unused bits of a sample mask have no effect 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Tests that the bits in the sample mask with positions higher than 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the number of samples do not have effect. In multisample fragment 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * operations the sample mask is ANDed with the fragment coverage value. 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The coverage value cannot have the corresponding bits set. 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is done by drawing a quads with varying sample masks and then 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * redrawing the quads with identical masks but with the mask's high bits 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * having different values. Only the latter quad pattern should be visible. 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SampleMaskHighBitsCase : public DefaultFBOMultisampleCase 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SampleMaskHighBitsCase (Context& context, const char* name, const char* description); 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~SampleMaskHighBitsCase (void) {} 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8793c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySampleMaskHighBitsCase::SampleMaskHighBitsCase (Context& context, const char* name, const char* description) 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DefaultFBOMultisampleCase(context, name, description, 256) 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SampleMaskHighBitsCase::init (void) 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLint maxSampleMaskWords = 0; 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check the test is even possible 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords); 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getEffectiveSampleMaskWordCount(m_numSamples - 1) > maxSampleMaskWords) 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS"); 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // normal init 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultFBOMultisampleCase::init(); 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8983c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySampleMaskHighBitsCase::IterateResult SampleMaskHighBitsCase::iterate (void) 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface renderedImg (m_viewportSize, m_viewportSize); 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (12345); 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_numSamples % 32 == 0) 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Sample count is multiple of word size. No unused high bits in sample mask.\nSkipping." << TestLog::EndMessage; 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Skipped"); 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry randomizeViewport(); 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage; 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_SAMPLE_MASK); 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "enable GL_SAMPLE_MASK"); 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "GL_SAMPLE_MASK is enabled" << TestLog::EndMessage; 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Drawing several green quads, each fully overlapped by a red quad with the same effective sample mask values" << TestLog::EndMessage; 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numQuadRowsCols = m_numSamples*4; 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int row = 0; row < numQuadRowsCols; row++) 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < numQuadRowsCols; col++) 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float x0 = (float)(col+0) / (float)numQuadRowsCols * 2.0f - 1.0f; 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float x1 = (float)(col+1) / (float)numQuadRowsCols * 2.0f - 1.0f; 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float y0 = (float)(row+0) / (float)numQuadRowsCols * 2.0f - 1.0f; 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float y1 = (float)(row+1) / (float)numQuadRowsCols * 2.0f - 1.0f; 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec4 baseGreen (0.0f, 1.0f, 0.0f, 1.0f); 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec4 baseRed (1.0f, 0.0f, 0.0f, 1.0f); 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int wordCount = getEffectiveSampleMaskWordCount(m_numSamples - 1); 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield finalWordBits = m_numSamples - 32 * ((m_numSamples-1) / 32); 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield finalWordMask = (GLbitfield)(1ULL << finalWordBits) - 1UL; 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int wordNdx = 0; wordNdx < wordCount; ++wordNdx) 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield mask = (GLbitfield)deUint32Hash((col << (m_numSamples / 2)) ^ row); 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isFinalWord = (wordNdx + 1) == wordCount; 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield maskMask = (isFinalWord) ? (finalWordMask) : (0xFFFFFFFFUL); // maskMask is 1 on bits in lower positions than sample count 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield highBits = rnd.getUint32(); 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.sampleMaski(wordNdx, (mask & maskMask) | (highBits & ~maskMask)); 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski"); 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseGreen, baseGreen, baseGreen, baseGreen); 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int wordNdx = 0; wordNdx < wordCount; ++wordNdx) 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield mask = (GLbitfield)deUint32Hash((col << (m_numSamples / 2)) ^ row); 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isFinalWord = (wordNdx + 1) == wordCount; 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield maskMask = (isFinalWord) ? (finalWordMask) : (0xFFFFFFFFUL); // maskMask is 1 on bits in lower positions than sample count 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLbitfield highBits = rnd.getUint32(); 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.sampleMaski(wordNdx, (mask & maskMask) | (highBits & ~maskMask)); 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glSampleMaski"); 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseRed, baseRed, baseRed, baseRed); 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readImage(renderedImg); 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG); 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < renderedImg.getHeight(); y++) 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < renderedImg.getWidth(); x++) 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (renderedImg.getPixel(x, y).getGreen() > 0) 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: Non-zero green color component detected - should have been completely overwritten by red quad. Mask unused bits have effect." << TestLog::EndMessage; 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Unused mask bits modified mask"); 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Success: Coverage mask high bits appear to have no effect." << TestLog::EndMessage; 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed"); 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleTests::MultisampleTests (Context& context) 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCaseGroup(context, "multisample", "Multisample tests") 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultisampleTests::~MultisampleTests (void) 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultisampleTests::init (void) 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "default_framebuffer", "Test with default framebuffer"); 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(group); 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .default_framebuffer 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // sample positions 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new SamplePosQueryCase (m_context, "sample_position", "test SAMPLE_POSITION")); 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // sample mask 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new MaskInvertCase (m_context, "sample_mask_sum_of_inverses", "Test that mask and its negation's sum equal the fully set mask")); 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new MaskProportionalityCase (m_context, "proportionality_sample_mask", "Test the proportionality property of GL_SAMPLE_MASK")); 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new MaskConstancyCase (m_context, "constancy_sample_mask", 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_MASK", 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MaskConstancyCase::CASEBIT_SAMPLE_MASK)); 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new MaskConstancyCase (m_context, "constancy_alpha_to_coverage_sample_mask", 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and GL_SAMPLE_MASK", 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MaskConstancyCase::CASEBIT_ALPHA_TO_COVERAGE | MaskConstancyCase::CASEBIT_SAMPLE_MASK)); 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new MaskConstancyCase (m_context, "constancy_sample_coverage_sample_mask", 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_COVERAGE and GL_SAMPLE_MASK", 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MaskConstancyCase::CASEBIT_SAMPLE_COVERAGE | MaskConstancyCase::CASEBIT_SAMPLE_MASK)); 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new MaskConstancyCase (m_context, "constancy_alpha_to_coverage_sample_coverage_sample_mask", 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE, GL_SAMPLE_COVERAGE and GL_SAMPLE_MASK", 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MaskConstancyCase::CASEBIT_ALPHA_TO_COVERAGE | MaskConstancyCase::CASEBIT_SAMPLE_COVERAGE | MaskConstancyCase::CASEBIT_SAMPLE_MASK)); 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new SampleMaskHighBitsCase (m_context, "sample_mask_non_effective_bits", 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Test that values of unused bits of a sample mask (bit index > sample count) have no effect")); 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 1034