xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fMultisampleTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Multisampling tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es3fMultisampleTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
37*35238bceSAndroid Build Coastguard Worker #include "deString.h"
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker #include <string>
40*35238bceSAndroid Build Coastguard Worker #include <vector>
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker #include "glw.h"
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker namespace deqp
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker namespace gles3
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker namespace Functional
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker 
51*35238bceSAndroid Build Coastguard Worker using std::vector;
52*35238bceSAndroid Build Coastguard Worker using tcu::IVec2;
53*35238bceSAndroid Build Coastguard Worker using tcu::IVec4;
54*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
55*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
56*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
57*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
58*35238bceSAndroid Build Coastguard Worker 
59*35238bceSAndroid Build Coastguard Worker static const GLenum FBO_COLOR_FORMAT = GL_RGBA8;
60*35238bceSAndroid Build Coastguard Worker static const float SQRT_HALF         = 0.707107f;
61*35238bceSAndroid Build Coastguard Worker 
62*35238bceSAndroid Build Coastguard Worker namespace
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker struct QuadCorners
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker     Vec2 p0;
68*35238bceSAndroid Build Coastguard Worker     Vec2 p1;
69*35238bceSAndroid Build Coastguard Worker     Vec2 p2;
70*35238bceSAndroid Build Coastguard Worker     Vec2 p3;
71*35238bceSAndroid Build Coastguard Worker 
QuadCornersdeqp::gles3::Functional::__anon229183b90111::QuadCorners72*35238bceSAndroid Build Coastguard Worker     QuadCorners(const Vec2 &p0_, const Vec2 &p1_, const Vec2 &p2_, const Vec2 &p3_) : p0(p0_), p1(p1_), p2(p2_), p3(p3_)
73*35238bceSAndroid Build Coastguard Worker     {
74*35238bceSAndroid Build Coastguard Worker     }
75*35238bceSAndroid Build Coastguard Worker };
76*35238bceSAndroid Build Coastguard Worker 
77*35238bceSAndroid Build Coastguard Worker } // namespace
78*35238bceSAndroid Build Coastguard Worker 
getIterationCount(const tcu::TestContext & ctx,int defaultCount)79*35238bceSAndroid Build Coastguard Worker static inline int getIterationCount(const tcu::TestContext &ctx, int defaultCount)
80*35238bceSAndroid Build Coastguard Worker {
81*35238bceSAndroid Build Coastguard Worker     int cmdLineValue = ctx.getCommandLine().getTestIterationCount();
82*35238bceSAndroid Build Coastguard Worker     return cmdLineValue > 0 ? cmdLineValue : defaultCount;
83*35238bceSAndroid Build Coastguard Worker }
84*35238bceSAndroid Build Coastguard Worker 
getGLInteger(GLenum name)85*35238bceSAndroid Build Coastguard Worker static inline int getGLInteger(GLenum name)
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker     int result;
88*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glGetIntegerv(name, &result));
89*35238bceSAndroid Build Coastguard Worker     return result;
90*35238bceSAndroid Build Coastguard Worker }
91*35238bceSAndroid Build Coastguard Worker 
92*35238bceSAndroid Build Coastguard Worker template <typename T>
min4(T a,T b,T c,T d)93*35238bceSAndroid Build Coastguard Worker static inline T min4(T a, T b, T c, T d)
94*35238bceSAndroid Build Coastguard Worker {
95*35238bceSAndroid Build Coastguard Worker     return de::min(de::min(de::min(a, b), c), d);
96*35238bceSAndroid Build Coastguard Worker }
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker template <typename T>
max4(T a,T b,T c,T d)99*35238bceSAndroid Build Coastguard Worker static inline T max4(T a, T b, T c, T d)
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker     return de::max(de::max(de::max(a, b), c), d);
102*35238bceSAndroid Build Coastguard Worker }
103*35238bceSAndroid Build Coastguard Worker 
isInsideQuad(const IVec2 & point,const IVec2 & p0,const IVec2 & p1,const IVec2 & p2,const IVec2 & p3)104*35238bceSAndroid Build Coastguard Worker static inline bool isInsideQuad(const IVec2 &point, const IVec2 &p0, const IVec2 &p1, const IVec2 &p2, const IVec2 &p3)
105*35238bceSAndroid Build Coastguard Worker {
106*35238bceSAndroid Build Coastguard Worker     int dot0 = (point.x() - p0.x()) * (p1.y() - p0.y()) + (point.y() - p0.y()) * (p0.x() - p1.x());
107*35238bceSAndroid Build Coastguard Worker     int dot1 = (point.x() - p1.x()) * (p2.y() - p1.y()) + (point.y() - p1.y()) * (p1.x() - p2.x());
108*35238bceSAndroid Build Coastguard Worker     int dot2 = (point.x() - p2.x()) * (p3.y() - p2.y()) + (point.y() - p2.y()) * (p2.x() - p3.x());
109*35238bceSAndroid Build Coastguard Worker     int dot3 = (point.x() - p3.x()) * (p0.y() - p3.y()) + (point.y() - p3.y()) * (p3.x() - p0.x());
110*35238bceSAndroid Build Coastguard Worker 
111*35238bceSAndroid Build Coastguard Worker     return (dot0 > 0) == (dot1 > 0) && (dot1 > 0) == (dot2 > 0) && (dot2 > 0) == (dot3 > 0);
112*35238bceSAndroid Build Coastguard Worker }
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
115*35238bceSAndroid Build Coastguard Worker  * \brief Check if a region in an image is unicolored.
116*35238bceSAndroid Build Coastguard Worker  *
117*35238bceSAndroid Build Coastguard Worker  * Checks if the pixels in img inside the convex quadilateral defined by
118*35238bceSAndroid Build Coastguard Worker  * p0, p1, p2 and p3 are all (approximately) of the same color.
119*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
isPixelRegionUnicolored(const tcu::Surface & img,const IVec2 & p0,const IVec2 & p1,const IVec2 & p2,const IVec2 & p3)120*35238bceSAndroid Build Coastguard Worker static bool isPixelRegionUnicolored(const tcu::Surface &img, const IVec2 &p0, const IVec2 &p1, const IVec2 &p2,
121*35238bceSAndroid Build Coastguard Worker                                     const IVec2 &p3)
122*35238bceSAndroid Build Coastguard Worker {
123*35238bceSAndroid Build Coastguard Worker     int xMin               = de::clamp(min4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth() - 1);
124*35238bceSAndroid Build Coastguard Worker     int yMin               = de::clamp(min4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight() - 1);
125*35238bceSAndroid Build Coastguard Worker     int xMax               = de::clamp(max4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth() - 1);
126*35238bceSAndroid Build Coastguard Worker     int yMax               = de::clamp(max4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight() - 1);
127*35238bceSAndroid Build Coastguard Worker     bool insideEncountered = false; //!< Whether we have already seen at least one pixel inside the region.
128*35238bceSAndroid Build Coastguard Worker     tcu::RGBA insideColor;          //!< Color of the first pixel inside the region.
129*35238bceSAndroid Build Coastguard Worker 
130*35238bceSAndroid Build Coastguard Worker     for (int y = yMin; y <= yMax; y++)
131*35238bceSAndroid Build Coastguard Worker         for (int x = xMin; x <= xMax; x++)
132*35238bceSAndroid Build Coastguard Worker         {
133*35238bceSAndroid Build Coastguard Worker             if (isInsideQuad(IVec2(x, y), p0, p1, p2, p3))
134*35238bceSAndroid Build Coastguard Worker             {
135*35238bceSAndroid Build Coastguard Worker                 tcu::RGBA pixColor = img.getPixel(x, y);
136*35238bceSAndroid Build Coastguard Worker 
137*35238bceSAndroid Build Coastguard Worker                 if (insideEncountered)
138*35238bceSAndroid Build Coastguard Worker                 {
139*35238bceSAndroid Build Coastguard Worker                     if (!tcu::compareThreshold(
140*35238bceSAndroid Build Coastguard Worker                             pixColor, insideColor,
141*35238bceSAndroid Build Coastguard Worker                             tcu::RGBA(
142*35238bceSAndroid Build Coastguard Worker                                 3, 3, 3,
143*35238bceSAndroid Build Coastguard Worker                                 3))) // Pixel color differs from already-detected color inside same region - region not unicolored.
144*35238bceSAndroid Build Coastguard Worker                         return false;
145*35238bceSAndroid Build Coastguard Worker                 }
146*35238bceSAndroid Build Coastguard Worker                 else
147*35238bceSAndroid Build Coastguard Worker                 {
148*35238bceSAndroid Build Coastguard Worker                     insideEncountered = true;
149*35238bceSAndroid Build Coastguard Worker                     insideColor       = pixColor;
150*35238bceSAndroid Build Coastguard Worker                 }
151*35238bceSAndroid Build Coastguard Worker             }
152*35238bceSAndroid Build Coastguard Worker         }
153*35238bceSAndroid Build Coastguard Worker 
154*35238bceSAndroid Build Coastguard Worker     return true;
155*35238bceSAndroid Build Coastguard Worker }
156*35238bceSAndroid Build Coastguard Worker 
drawUnicolorTestErrors(tcu::Surface & img,const tcu::PixelBufferAccess & errorImg,const IVec2 & p0,const IVec2 & p1,const IVec2 & p2,const IVec2 & p3)157*35238bceSAndroid Build Coastguard Worker static bool drawUnicolorTestErrors(tcu::Surface &img, const tcu::PixelBufferAccess &errorImg, const IVec2 &p0,
158*35238bceSAndroid Build Coastguard Worker                                    const IVec2 &p1, const IVec2 &p2, const IVec2 &p3)
159*35238bceSAndroid Build Coastguard Worker {
160*35238bceSAndroid Build Coastguard Worker     int xMin           = de::clamp(min4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth() - 1);
161*35238bceSAndroid Build Coastguard Worker     int yMin           = de::clamp(min4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight() - 1);
162*35238bceSAndroid Build Coastguard Worker     int xMax           = de::clamp(max4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth() - 1);
163*35238bceSAndroid Build Coastguard Worker     int yMax           = de::clamp(max4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight() - 1);
164*35238bceSAndroid Build Coastguard Worker     tcu::RGBA refColor = img.getPixel((xMin + xMax) / 2, (yMin + yMax) / 2);
165*35238bceSAndroid Build Coastguard Worker 
166*35238bceSAndroid Build Coastguard Worker     for (int y = yMin; y <= yMax; y++)
167*35238bceSAndroid Build Coastguard Worker         for (int x = xMin; x <= xMax; x++)
168*35238bceSAndroid Build Coastguard Worker         {
169*35238bceSAndroid Build Coastguard Worker             if (isInsideQuad(IVec2(x, y), p0, p1, p2, p3))
170*35238bceSAndroid Build Coastguard Worker             {
171*35238bceSAndroid Build Coastguard Worker                 if (!tcu::compareThreshold(img.getPixel(x, y), refColor, tcu::RGBA(3, 3, 3, 3)))
172*35238bceSAndroid Build Coastguard Worker                 {
173*35238bceSAndroid Build Coastguard Worker                     img.setPixel(x, y, tcu::RGBA::red());
174*35238bceSAndroid Build Coastguard Worker                     errorImg.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
175*35238bceSAndroid Build Coastguard Worker                 }
176*35238bceSAndroid Build Coastguard Worker             }
177*35238bceSAndroid Build Coastguard Worker         }
178*35238bceSAndroid Build Coastguard Worker 
179*35238bceSAndroid Build Coastguard Worker     return true;
180*35238bceSAndroid Build Coastguard Worker }
181*35238bceSAndroid Build Coastguard Worker 
182*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
183*35238bceSAndroid Build Coastguard Worker  * \brief Abstract base class handling common stuff for multisample cases.
184*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
185*35238bceSAndroid Build Coastguard Worker class MultisampleCase : public TestCase
186*35238bceSAndroid Build Coastguard Worker {
187*35238bceSAndroid Build Coastguard Worker public:
188*35238bceSAndroid Build Coastguard Worker     struct FboParams
189*35238bceSAndroid Build Coastguard Worker     {
190*35238bceSAndroid Build Coastguard Worker         bool useFbo;
191*35238bceSAndroid Build Coastguard Worker         int numSamples; //!< If 0, use implementation-defined maximum.
192*35238bceSAndroid Build Coastguard Worker         bool useDepth;
193*35238bceSAndroid Build Coastguard Worker         bool useStencil;
194*35238bceSAndroid Build Coastguard Worker 
FboParamsdeqp::gles3::Functional::MultisampleCase::FboParams195*35238bceSAndroid Build Coastguard Worker         FboParams(int numSamples_, bool useDepth_, bool useStencil_)
196*35238bceSAndroid Build Coastguard Worker             : useFbo(true)
197*35238bceSAndroid Build Coastguard Worker             , numSamples(numSamples_)
198*35238bceSAndroid Build Coastguard Worker             , useDepth(useDepth_)
199*35238bceSAndroid Build Coastguard Worker             , useStencil(useStencil_)
200*35238bceSAndroid Build Coastguard Worker         {
201*35238bceSAndroid Build Coastguard Worker         }
202*35238bceSAndroid Build Coastguard Worker 
FboParamsdeqp::gles3::Functional::MultisampleCase::FboParams203*35238bceSAndroid Build Coastguard Worker         FboParams(void) : useFbo(false), numSamples(-1), useDepth(false), useStencil(false)
204*35238bceSAndroid Build Coastguard Worker         {
205*35238bceSAndroid Build Coastguard Worker         }
206*35238bceSAndroid Build Coastguard Worker     };
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker     MultisampleCase(Context &context, const char *name, const char *desc, int desiredViewportSize,
209*35238bceSAndroid Build Coastguard Worker                     const FboParams &fboParams = FboParams());
210*35238bceSAndroid Build Coastguard Worker     virtual ~MultisampleCase(void);
211*35238bceSAndroid Build Coastguard Worker 
212*35238bceSAndroid Build Coastguard Worker     virtual void init(void);
213*35238bceSAndroid Build Coastguard Worker     virtual void deinit(void);
214*35238bceSAndroid Build Coastguard Worker 
215*35238bceSAndroid Build Coastguard Worker protected:
216*35238bceSAndroid Build Coastguard Worker     void renderTriangle(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec4 &c0, const Vec4 &c1,
217*35238bceSAndroid Build Coastguard Worker                         const Vec4 &c2) const;
218*35238bceSAndroid Build Coastguard Worker     void renderTriangle(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec4 &color) const;
219*35238bceSAndroid Build Coastguard Worker     void renderTriangle(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec4 &c0, const Vec4 &c1,
220*35238bceSAndroid Build Coastguard Worker                         const Vec4 &c2) const;
221*35238bceSAndroid Build Coastguard Worker     void renderTriangle(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec4 &color) const;
222*35238bceSAndroid Build Coastguard Worker     void renderQuad(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, const Vec4 &c0, const Vec4 &c1,
223*35238bceSAndroid Build Coastguard Worker                     const Vec4 &c2, const Vec4 &c3) const;
224*35238bceSAndroid Build Coastguard Worker     void renderQuad(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, const Vec4 &color) const;
225*35238bceSAndroid Build Coastguard Worker     void renderLine(const Vec2 &p0, const Vec2 &p1, const Vec4 &color) const;
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker     void randomizeViewport(void);
228*35238bceSAndroid Build Coastguard Worker     void readImage(tcu::Surface &dst) const;
229*35238bceSAndroid Build Coastguard Worker 
getRenderTargetSize(void) const230*35238bceSAndroid Build Coastguard Worker     IVec2 getRenderTargetSize(void) const
231*35238bceSAndroid Build Coastguard Worker     {
232*35238bceSAndroid Build Coastguard Worker         return IVec2(m_renderWidth, m_renderHeight);
233*35238bceSAndroid Build Coastguard Worker     }
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker     int m_numSamples;
236*35238bceSAndroid Build Coastguard Worker 
237*35238bceSAndroid Build Coastguard Worker     int m_viewportSize;
238*35238bceSAndroid Build Coastguard Worker 
239*35238bceSAndroid Build Coastguard Worker private:
240*35238bceSAndroid Build Coastguard Worker     MultisampleCase(const MultisampleCase &other);
241*35238bceSAndroid Build Coastguard Worker     MultisampleCase &operator=(const MultisampleCase &other);
242*35238bceSAndroid Build Coastguard Worker 
243*35238bceSAndroid Build Coastguard Worker     const int m_desiredViewportSize;
244*35238bceSAndroid Build Coastguard Worker 
245*35238bceSAndroid Build Coastguard Worker     const FboParams m_fboParams;
246*35238bceSAndroid Build Coastguard Worker     uint32_t m_msColorRbo;
247*35238bceSAndroid Build Coastguard Worker     uint32_t m_msDepthStencilRbo;
248*35238bceSAndroid Build Coastguard Worker     uint32_t m_resolveColorRbo;
249*35238bceSAndroid Build Coastguard Worker     uint32_t m_msFbo;
250*35238bceSAndroid Build Coastguard Worker     uint32_t m_resolveFbo;
251*35238bceSAndroid Build Coastguard Worker 
252*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_program;
253*35238bceSAndroid Build Coastguard Worker     int m_attrPositionLoc;
254*35238bceSAndroid Build Coastguard Worker     int m_attrColorLoc;
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker     int m_renderWidth;
257*35238bceSAndroid Build Coastguard Worker     int m_renderHeight;
258*35238bceSAndroid Build Coastguard Worker     int m_viewportX;
259*35238bceSAndroid Build Coastguard Worker     int m_viewportY;
260*35238bceSAndroid Build Coastguard Worker     de::Random m_rnd;
261*35238bceSAndroid Build Coastguard Worker };
262*35238bceSAndroid Build Coastguard Worker 
MultisampleCase(Context & context,const char * name,const char * desc,int desiredViewportSize,const FboParams & fboParams)263*35238bceSAndroid Build Coastguard Worker MultisampleCase::MultisampleCase(Context &context, const char *name, const char *desc, int desiredViewportSize,
264*35238bceSAndroid Build Coastguard Worker                                  const FboParams &fboParams)
265*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
266*35238bceSAndroid Build Coastguard Worker     , m_numSamples(0)
267*35238bceSAndroid Build Coastguard Worker     , m_viewportSize(0)
268*35238bceSAndroid Build Coastguard Worker     , m_desiredViewportSize(desiredViewportSize)
269*35238bceSAndroid Build Coastguard Worker     , m_fboParams(fboParams)
270*35238bceSAndroid Build Coastguard Worker     , m_msColorRbo(0)
271*35238bceSAndroid Build Coastguard Worker     , m_msDepthStencilRbo(0)
272*35238bceSAndroid Build Coastguard Worker     , m_resolveColorRbo(0)
273*35238bceSAndroid Build Coastguard Worker     , m_msFbo(0)
274*35238bceSAndroid Build Coastguard Worker     , m_resolveFbo(0)
275*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
276*35238bceSAndroid Build Coastguard Worker     , m_attrPositionLoc(-1)
277*35238bceSAndroid Build Coastguard Worker     , m_attrColorLoc(-1)
278*35238bceSAndroid Build Coastguard Worker     , m_renderWidth(fboParams.useFbo ? 2 * desiredViewportSize : context.getRenderTarget().getWidth())
279*35238bceSAndroid Build Coastguard Worker     , m_renderHeight(fboParams.useFbo ? 2 * desiredViewportSize : context.getRenderTarget().getHeight())
280*35238bceSAndroid Build Coastguard Worker     , m_viewportX(0)
281*35238bceSAndroid Build Coastguard Worker     , m_viewportY(0)
282*35238bceSAndroid Build Coastguard Worker     , m_rnd(deStringHash(name))
283*35238bceSAndroid Build Coastguard Worker {
284*35238bceSAndroid Build Coastguard Worker     if (m_fboParams.useFbo)
285*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_fboParams.numSamples >= 0);
286*35238bceSAndroid Build Coastguard Worker }
287*35238bceSAndroid Build Coastguard Worker 
~MultisampleCase(void)288*35238bceSAndroid Build Coastguard Worker MultisampleCase::~MultisampleCase(void)
289*35238bceSAndroid Build Coastguard Worker {
290*35238bceSAndroid Build Coastguard Worker     MultisampleCase::deinit();
291*35238bceSAndroid Build Coastguard Worker }
292*35238bceSAndroid Build Coastguard Worker 
deinit(void)293*35238bceSAndroid Build Coastguard Worker void MultisampleCase::deinit(void)
294*35238bceSAndroid Build Coastguard Worker {
295*35238bceSAndroid Build Coastguard Worker     delete m_program;
296*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
299*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
300*35238bceSAndroid Build Coastguard Worker 
301*35238bceSAndroid Build Coastguard Worker     if (m_msColorRbo != 0)
302*35238bceSAndroid Build Coastguard Worker     {
303*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glDeleteRenderbuffers(1, &m_msColorRbo));
304*35238bceSAndroid Build Coastguard Worker         m_msColorRbo = 0;
305*35238bceSAndroid Build Coastguard Worker     }
306*35238bceSAndroid Build Coastguard Worker     if (m_msDepthStencilRbo != 0)
307*35238bceSAndroid Build Coastguard Worker     {
308*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glDeleteRenderbuffers(1, &m_msDepthStencilRbo));
309*35238bceSAndroid Build Coastguard Worker         m_msDepthStencilRbo = 0;
310*35238bceSAndroid Build Coastguard Worker     }
311*35238bceSAndroid Build Coastguard Worker     if (m_resolveColorRbo != 0)
312*35238bceSAndroid Build Coastguard Worker     {
313*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glDeleteRenderbuffers(1, &m_resolveColorRbo));
314*35238bceSAndroid Build Coastguard Worker         m_resolveColorRbo = 0;
315*35238bceSAndroid Build Coastguard Worker     }
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker     if (m_msFbo != 0)
318*35238bceSAndroid Build Coastguard Worker     {
319*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glDeleteFramebuffers(1, &m_msFbo));
320*35238bceSAndroid Build Coastguard Worker         m_msFbo = 0;
321*35238bceSAndroid Build Coastguard Worker     }
322*35238bceSAndroid Build Coastguard Worker     if (m_resolveFbo != 0)
323*35238bceSAndroid Build Coastguard Worker     {
324*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glDeleteFramebuffers(1, &m_resolveFbo));
325*35238bceSAndroid Build Coastguard Worker         m_resolveFbo = 0;
326*35238bceSAndroid Build Coastguard Worker     }
327*35238bceSAndroid Build Coastguard Worker }
328*35238bceSAndroid Build Coastguard Worker 
renderTriangle(const Vec3 & p0,const Vec3 & p1,const Vec3 & p2,const Vec4 & c0,const Vec4 & c1,const Vec4 & c2) const329*35238bceSAndroid Build Coastguard Worker void MultisampleCase::renderTriangle(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec4 &c0, const Vec4 &c1,
330*35238bceSAndroid Build Coastguard Worker                                      const Vec4 &c2) const
331*35238bceSAndroid Build Coastguard Worker {
332*35238bceSAndroid Build Coastguard Worker     float vertexPositions[] = {p0.x(), p0.y(), p0.z(), 1.0f,   p1.x(), p1.y(),
333*35238bceSAndroid Build Coastguard Worker                                p1.z(), 1.0f,   p2.x(), p2.y(), p2.z(), 1.0f};
334*35238bceSAndroid Build Coastguard Worker     float vertexColors[]    = {
335*35238bceSAndroid Build Coastguard Worker         c0.x(), c0.y(), c0.z(), c0.w(), c1.x(), c1.y(), c1.z(), c1.w(), c2.x(), c2.y(), c2.z(), c2.w(),
336*35238bceSAndroid Build Coastguard Worker     };
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrPositionLoc));
339*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glVertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, &vertexPositions[0]));
340*35238bceSAndroid Build Coastguard Worker 
341*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrColorLoc));
342*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glVertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, &vertexColors[0]));
343*35238bceSAndroid Build Coastguard Worker 
344*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
345*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
346*35238bceSAndroid Build Coastguard Worker }
347*35238bceSAndroid Build Coastguard Worker 
renderTriangle(const Vec3 & p0,const Vec3 & p1,const Vec3 & p2,const Vec4 & color) const348*35238bceSAndroid Build Coastguard Worker void MultisampleCase::renderTriangle(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec4 &color) const
349*35238bceSAndroid Build Coastguard Worker {
350*35238bceSAndroid Build Coastguard Worker     renderTriangle(p0, p1, p2, color, color, color);
351*35238bceSAndroid Build Coastguard Worker }
352*35238bceSAndroid Build Coastguard Worker 
renderTriangle(const Vec2 & p0,const Vec2 & p1,const Vec2 & p2,const Vec4 & c0,const Vec4 & c1,const Vec4 & c2) const353*35238bceSAndroid Build Coastguard Worker void MultisampleCase::renderTriangle(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec4 &c0, const Vec4 &c1,
354*35238bceSAndroid Build Coastguard Worker                                      const Vec4 &c2) const
355*35238bceSAndroid Build Coastguard Worker {
356*35238bceSAndroid Build Coastguard Worker     renderTriangle(Vec3(p0.x(), p0.y(), 0.0f), Vec3(p1.x(), p1.y(), 0.0f), Vec3(p2.x(), p2.y(), 0.0f), c0, c1, c2);
357*35238bceSAndroid Build Coastguard Worker }
358*35238bceSAndroid Build Coastguard Worker 
renderTriangle(const Vec2 & p0,const Vec2 & p1,const Vec2 & p2,const Vec4 & color) const359*35238bceSAndroid Build Coastguard Worker void MultisampleCase::renderTriangle(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec4 &color) const
360*35238bceSAndroid Build Coastguard Worker {
361*35238bceSAndroid Build Coastguard Worker     renderTriangle(p0, p1, p2, color, color, color);
362*35238bceSAndroid Build Coastguard Worker }
363*35238bceSAndroid Build Coastguard Worker 
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) const364*35238bceSAndroid Build Coastguard Worker void MultisampleCase::renderQuad(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, const Vec4 &c0,
365*35238bceSAndroid Build Coastguard Worker                                  const Vec4 &c1, const Vec4 &c2, const Vec4 &c3) const
366*35238bceSAndroid Build Coastguard Worker {
367*35238bceSAndroid Build Coastguard Worker     renderTriangle(p0, p1, p2, c0, c1, c2);
368*35238bceSAndroid Build Coastguard Worker     renderTriangle(p2, p1, p3, c2, c1, c3);
369*35238bceSAndroid Build Coastguard Worker }
370*35238bceSAndroid Build Coastguard Worker 
renderQuad(const Vec2 & p0,const Vec2 & p1,const Vec2 & p2,const Vec2 & p3,const Vec4 & color) const371*35238bceSAndroid Build Coastguard Worker void MultisampleCase::renderQuad(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
372*35238bceSAndroid Build Coastguard Worker                                  const Vec4 &color) const
373*35238bceSAndroid Build Coastguard Worker {
374*35238bceSAndroid Build Coastguard Worker     renderQuad(p0, p1, p2, p3, color, color, color, color);
375*35238bceSAndroid Build Coastguard Worker }
376*35238bceSAndroid Build Coastguard Worker 
renderLine(const Vec2 & p0,const Vec2 & p1,const Vec4 & color) const377*35238bceSAndroid Build Coastguard Worker void MultisampleCase::renderLine(const Vec2 &p0, const Vec2 &p1, const Vec4 &color) const
378*35238bceSAndroid Build Coastguard Worker {
379*35238bceSAndroid Build Coastguard Worker     float vertexPositions[] = {p0.x(), p0.y(), 0.0f, 1.0f, p1.x(), p1.y(), 0.0f, 1.0f};
380*35238bceSAndroid Build Coastguard Worker     float vertexColors[]    = {color.x(), color.y(), color.z(), color.w(), color.x(), color.y(), color.z(), color.w()};
381*35238bceSAndroid Build Coastguard Worker 
382*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrPositionLoc));
383*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glVertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, &vertexPositions[0]));
384*35238bceSAndroid Build Coastguard Worker 
385*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrColorLoc));
386*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glVertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, &vertexColors[0]));
387*35238bceSAndroid Build Coastguard Worker 
388*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
389*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glDrawArrays(GL_LINES, 0, 2));
390*35238bceSAndroid Build Coastguard Worker }
391*35238bceSAndroid Build Coastguard Worker 
randomizeViewport(void)392*35238bceSAndroid Build Coastguard Worker void MultisampleCase::randomizeViewport(void)
393*35238bceSAndroid Build Coastguard Worker {
394*35238bceSAndroid Build Coastguard Worker     m_viewportX = m_rnd.getInt(0, m_renderWidth - m_viewportSize);
395*35238bceSAndroid Build Coastguard Worker     m_viewportY = m_rnd.getInt(0, m_renderHeight - m_viewportSize);
396*35238bceSAndroid Build Coastguard Worker 
397*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glViewport(m_viewportX, m_viewportY, m_viewportSize, m_viewportSize));
398*35238bceSAndroid Build Coastguard Worker }
399*35238bceSAndroid Build Coastguard Worker 
readImage(tcu::Surface & dst) const400*35238bceSAndroid Build Coastguard Worker void MultisampleCase::readImage(tcu::Surface &dst) const
401*35238bceSAndroid Build Coastguard Worker {
402*35238bceSAndroid Build Coastguard Worker     if (m_fboParams.useFbo)
403*35238bceSAndroid Build Coastguard Worker     {
404*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolveFbo));
405*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBlitFramebuffer(0, 0, m_renderWidth, m_renderHeight, 0, 0, m_renderWidth, m_renderHeight,
406*35238bceSAndroid Build Coastguard Worker                                          GL_COLOR_BUFFER_BIT, GL_NEAREST));
407*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_resolveFbo));
408*35238bceSAndroid Build Coastguard Worker 
409*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), m_viewportX, m_viewportY, dst.getAccess());
410*35238bceSAndroid Build Coastguard Worker 
411*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_msFbo));
412*35238bceSAndroid Build Coastguard Worker     }
413*35238bceSAndroid Build Coastguard Worker     else
414*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), m_viewportX, m_viewportY, dst.getAccess());
415*35238bceSAndroid Build Coastguard Worker }
416*35238bceSAndroid Build Coastguard Worker 
init(void)417*35238bceSAndroid Build Coastguard Worker void MultisampleCase::init(void)
418*35238bceSAndroid Build Coastguard Worker {
419*35238bceSAndroid Build Coastguard Worker     static const char *vertShaderSource = "#version 300 es\n"
420*35238bceSAndroid Build Coastguard Worker                                           "in highp vec4 a_position;\n"
421*35238bceSAndroid Build Coastguard Worker                                           "in mediump vec4 a_color;\n"
422*35238bceSAndroid Build Coastguard Worker                                           "out mediump vec4 v_color;\n"
423*35238bceSAndroid Build Coastguard Worker                                           "void main()\n"
424*35238bceSAndroid Build Coastguard Worker                                           "{\n"
425*35238bceSAndroid Build Coastguard Worker                                           "    gl_Position = a_position;\n"
426*35238bceSAndroid Build Coastguard Worker                                           "    v_color = a_color;\n"
427*35238bceSAndroid Build Coastguard Worker                                           "}\n";
428*35238bceSAndroid Build Coastguard Worker 
429*35238bceSAndroid Build Coastguard Worker     static const char *fragShaderSource = "#version 300 es\n"
430*35238bceSAndroid Build Coastguard Worker                                           "in mediump vec4 v_color;\n"
431*35238bceSAndroid Build Coastguard Worker                                           "layout(location = 0) out mediump vec4 o_color;\n"
432*35238bceSAndroid Build Coastguard Worker                                           "void main()\n"
433*35238bceSAndroid Build Coastguard Worker                                           "{\n"
434*35238bceSAndroid Build Coastguard Worker                                           "    o_color = v_color;\n"
435*35238bceSAndroid Build Coastguard Worker                                           "}\n";
436*35238bceSAndroid Build Coastguard Worker 
437*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
438*35238bceSAndroid Build Coastguard Worker 
439*35238bceSAndroid Build Coastguard Worker     if (!m_fboParams.useFbo && m_context.getRenderTarget().getNumSamples() <= 1)
440*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("No multisample buffers");
441*35238bceSAndroid Build Coastguard Worker 
442*35238bceSAndroid Build Coastguard Worker     if (m_fboParams.useFbo)
443*35238bceSAndroid Build Coastguard Worker     {
444*35238bceSAndroid Build Coastguard Worker         if (m_fboParams.numSamples > 0)
445*35238bceSAndroid Build Coastguard Worker             m_numSamples = m_fboParams.numSamples;
446*35238bceSAndroid Build Coastguard Worker         else
447*35238bceSAndroid Build Coastguard Worker         {
448*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "Querying maximum number of samples for "
449*35238bceSAndroid Build Coastguard Worker                 << glu::getTextureFormatName(FBO_COLOR_FORMAT) << " with glGetInternalformativ()"
450*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
451*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glGetInternalformativ(GL_RENDERBUFFER, FBO_COLOR_FORMAT, GL_SAMPLES, 1, &m_numSamples));
452*35238bceSAndroid Build Coastguard Worker         }
453*35238bceSAndroid Build Coastguard Worker 
454*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Using FBO of size (" << m_renderWidth << ", " << m_renderHeight << ") with "
455*35238bceSAndroid Build Coastguard Worker             << m_numSamples << " samples" << TestLog::EndMessage;
456*35238bceSAndroid Build Coastguard Worker     }
457*35238bceSAndroid Build Coastguard Worker     else
458*35238bceSAndroid Build Coastguard Worker     {
459*35238bceSAndroid Build Coastguard Worker         // Query and log number of samples per pixel.
460*35238bceSAndroid Build Coastguard Worker 
461*35238bceSAndroid Build Coastguard Worker         m_numSamples = getGLInteger(GL_SAMPLES);
462*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "GL_SAMPLES = " << m_numSamples << TestLog::EndMessage;
463*35238bceSAndroid Build Coastguard Worker     }
464*35238bceSAndroid Build Coastguard Worker 
465*35238bceSAndroid Build Coastguard Worker     // Prepare program.
466*35238bceSAndroid Build Coastguard Worker 
467*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_program);
468*35238bceSAndroid Build Coastguard Worker 
469*35238bceSAndroid Build Coastguard Worker     m_program = new glu::ShaderProgram(m_context.getRenderContext(),
470*35238bceSAndroid Build Coastguard Worker                                        glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
471*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
472*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("Failed to compile program", DE_NULL, __FILE__, __LINE__);
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(m_attrPositionLoc = glGetAttribLocation(m_program->getProgram(), "a_position"));
475*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(m_attrColorLoc = glGetAttribLocation(m_program->getProgram(), "a_color"));
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker     if (m_attrPositionLoc < 0 || m_attrColorLoc < 0)
478*35238bceSAndroid Build Coastguard Worker     {
479*35238bceSAndroid Build Coastguard Worker         delete m_program;
480*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("Invalid attribute locations", DE_NULL, __FILE__, __LINE__);
481*35238bceSAndroid Build Coastguard Worker     }
482*35238bceSAndroid Build Coastguard Worker 
483*35238bceSAndroid Build Coastguard Worker     if (m_fboParams.useFbo)
484*35238bceSAndroid Build Coastguard Worker     {
485*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(sizeof(uint32_t) == sizeof(GLuint));
486*35238bceSAndroid Build Coastguard Worker 
487*35238bceSAndroid Build Coastguard Worker         // Setup ms color RBO.
488*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glGenRenderbuffers(1, &m_msColorRbo));
489*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, m_msColorRbo));
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker         // If glRenderbufferStorageMultisample() fails, check if it's because of a too high sample count.
492*35238bceSAndroid Build Coastguard Worker         // \note We don't do the check until now because some implementations can't handle the GL_SAMPLES query with glGetInternalformativ(),
493*35238bceSAndroid Build Coastguard Worker         //         and we don't want that to be the cause of test case failure.
494*35238bceSAndroid Build Coastguard Worker         try
495*35238bceSAndroid Build Coastguard Worker         {
496*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, FBO_COLOR_FORMAT,
497*35238bceSAndroid Build Coastguard Worker                                                             m_renderWidth, m_renderHeight));
498*35238bceSAndroid Build Coastguard Worker         }
499*35238bceSAndroid Build Coastguard Worker         catch (const glu::Error &)
500*35238bceSAndroid Build Coastguard Worker         {
501*35238bceSAndroid Build Coastguard Worker             GLint maxSampleCount = -1;
502*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glGetInternalformativ(GL_RENDERBUFFER, FBO_COLOR_FORMAT, GL_SAMPLES, 1, &maxSampleCount));
503*35238bceSAndroid Build Coastguard Worker             if (maxSampleCount < m_numSamples)
504*35238bceSAndroid Build Coastguard Worker                 throw tcu::NotSupportedError(
505*35238bceSAndroid Build Coastguard Worker                     std::string("") + "Maximum sample count returned by glGetInternalformativ() for " +
506*35238bceSAndroid Build Coastguard Worker                     glu::getTextureFormatName(FBO_COLOR_FORMAT) + " is only " + de::toString(maxSampleCount));
507*35238bceSAndroid Build Coastguard Worker             else
508*35238bceSAndroid Build Coastguard Worker                 throw;
509*35238bceSAndroid Build Coastguard Worker         }
510*35238bceSAndroid Build Coastguard Worker 
511*35238bceSAndroid Build Coastguard Worker         if (m_fboParams.useDepth || m_fboParams.useStencil)
512*35238bceSAndroid Build Coastguard Worker         {
513*35238bceSAndroid Build Coastguard Worker             // Setup ms depth & stencil RBO.
514*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glGenRenderbuffers(1, &m_msDepthStencilRbo));
515*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, m_msDepthStencilRbo));
516*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, GL_DEPTH24_STENCIL8,
517*35238bceSAndroid Build Coastguard Worker                                                             m_renderWidth, m_renderHeight));
518*35238bceSAndroid Build Coastguard Worker         }
519*35238bceSAndroid Build Coastguard Worker 
520*35238bceSAndroid Build Coastguard Worker         // Setup ms FBO.
521*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glGenFramebuffers(1, &m_msFbo));
522*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_msFbo));
523*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_msColorRbo));
524*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
525*35238bceSAndroid Build Coastguard Worker                                                  m_msDepthStencilRbo));
526*35238bceSAndroid Build Coastguard Worker 
527*35238bceSAndroid Build Coastguard Worker         // Setup resolve color RBO.
528*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glGenRenderbuffers(1, &m_resolveColorRbo));
529*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, m_resolveColorRbo));
530*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, FBO_COLOR_FORMAT, m_renderWidth, m_renderHeight));
531*35238bceSAndroid Build Coastguard Worker 
532*35238bceSAndroid Build Coastguard Worker         // Setup resolve FBO.
533*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glGenFramebuffers(1, &m_resolveFbo));
534*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo));
535*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(
536*35238bceSAndroid Build Coastguard Worker             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_resolveColorRbo));
537*35238bceSAndroid Build Coastguard Worker 
538*35238bceSAndroid Build Coastguard Worker         // Use ms FBO.
539*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_msFbo));
540*35238bceSAndroid Build Coastguard Worker     }
541*35238bceSAndroid Build Coastguard Worker 
542*35238bceSAndroid Build Coastguard Worker     // Get suitable viewport size.
543*35238bceSAndroid Build Coastguard Worker 
544*35238bceSAndroid Build Coastguard Worker     m_viewportSize = de::min<int>(m_desiredViewportSize, de::min(m_renderWidth, m_renderHeight));
545*35238bceSAndroid Build Coastguard Worker     randomizeViewport();
546*35238bceSAndroid Build Coastguard Worker }
547*35238bceSAndroid Build Coastguard Worker 
548*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
549*35238bceSAndroid Build Coastguard Worker  * \brief Base class for cases testing the value of sample count.
550*35238bceSAndroid Build Coastguard Worker  *
551*35238bceSAndroid Build Coastguard Worker  * Draws a test pattern (defined by renderPattern() of an inheriting class)
552*35238bceSAndroid Build Coastguard Worker  * and counts the number of distinct colors in the resulting image. That
553*35238bceSAndroid Build Coastguard Worker  * number should be at least the value of sample count plus one. This is
554*35238bceSAndroid Build Coastguard Worker  * repeated with increased values of m_currentIteration until this correct
555*35238bceSAndroid Build Coastguard Worker  * number of colors is detected or m_currentIteration reaches
556*35238bceSAndroid Build Coastguard Worker  * m_maxNumIterations.
557*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
558*35238bceSAndroid Build Coastguard Worker class NumSamplesCase : public MultisampleCase
559*35238bceSAndroid Build Coastguard Worker {
560*35238bceSAndroid Build Coastguard Worker public:
561*35238bceSAndroid Build Coastguard Worker     NumSamplesCase(Context &context, const char *name, const char *description,
562*35238bceSAndroid Build Coastguard Worker                    const FboParams &fboParams = FboParams());
~NumSamplesCase(void)563*35238bceSAndroid Build Coastguard Worker     ~NumSamplesCase(void)
564*35238bceSAndroid Build Coastguard Worker     {
565*35238bceSAndroid Build Coastguard Worker     }
566*35238bceSAndroid Build Coastguard Worker 
567*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
568*35238bceSAndroid Build Coastguard Worker 
569*35238bceSAndroid Build Coastguard Worker protected:
570*35238bceSAndroid Build Coastguard Worker     virtual void renderPattern(void) const = 0;
571*35238bceSAndroid Build Coastguard Worker 
572*35238bceSAndroid Build Coastguard Worker     int m_currentIteration;
573*35238bceSAndroid Build Coastguard Worker 
574*35238bceSAndroid Build Coastguard Worker private:
575*35238bceSAndroid Build Coastguard Worker     enum
576*35238bceSAndroid Build Coastguard Worker     {
577*35238bceSAndroid Build Coastguard Worker         DEFAULT_MAX_NUM_ITERATIONS = 16
578*35238bceSAndroid Build Coastguard Worker     };
579*35238bceSAndroid Build Coastguard Worker 
580*35238bceSAndroid Build Coastguard Worker     const int m_maxNumIterations;
581*35238bceSAndroid Build Coastguard Worker     vector<tcu::RGBA> m_detectedColors;
582*35238bceSAndroid Build Coastguard Worker };
583*35238bceSAndroid Build Coastguard Worker 
NumSamplesCase(Context & context,const char * name,const char * description,const FboParams & fboParams)584*35238bceSAndroid Build Coastguard Worker NumSamplesCase::NumSamplesCase(Context &context, const char *name, const char *description, const FboParams &fboParams)
585*35238bceSAndroid Build Coastguard Worker     : MultisampleCase(context, name, description, 256, fboParams)
586*35238bceSAndroid Build Coastguard Worker     , m_currentIteration(0)
587*35238bceSAndroid Build Coastguard Worker     , m_maxNumIterations(getIterationCount(m_testCtx, DEFAULT_MAX_NUM_ITERATIONS))
588*35238bceSAndroid Build Coastguard Worker {
589*35238bceSAndroid Build Coastguard Worker }
590*35238bceSAndroid Build Coastguard Worker 
iterate(void)591*35238bceSAndroid Build Coastguard Worker NumSamplesCase::IterateResult NumSamplesCase::iterate(void)
592*35238bceSAndroid Build Coastguard Worker {
593*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
594*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImg(m_viewportSize, m_viewportSize);
595*35238bceSAndroid Build Coastguard Worker 
596*35238bceSAndroid Build Coastguard Worker     randomizeViewport();
597*35238bceSAndroid Build Coastguard Worker 
598*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
599*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
600*35238bceSAndroid Build Coastguard Worker 
601*35238bceSAndroid Build Coastguard Worker     renderPattern();
602*35238bceSAndroid Build Coastguard Worker 
603*35238bceSAndroid Build Coastguard Worker     // Read and log rendered image.
604*35238bceSAndroid Build Coastguard Worker 
605*35238bceSAndroid Build Coastguard Worker     readImage(renderedImg);
606*35238bceSAndroid Build Coastguard Worker 
607*35238bceSAndroid Build Coastguard Worker     log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
608*35238bceSAndroid Build Coastguard Worker 
609*35238bceSAndroid Build Coastguard Worker     // Detect new, previously unseen colors from image.
610*35238bceSAndroid Build Coastguard Worker 
611*35238bceSAndroid Build Coastguard Worker     int requiredNumDistinctColors = m_numSamples + 1;
612*35238bceSAndroid Build Coastguard Worker 
613*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < renderedImg.getHeight() && (int)m_detectedColors.size() < requiredNumDistinctColors; y++)
614*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < renderedImg.getWidth() && (int)m_detectedColors.size() < requiredNumDistinctColors; x++)
615*35238bceSAndroid Build Coastguard Worker         {
616*35238bceSAndroid Build Coastguard Worker             tcu::RGBA color = renderedImg.getPixel(x, y);
617*35238bceSAndroid Build Coastguard Worker 
618*35238bceSAndroid Build Coastguard Worker             int i;
619*35238bceSAndroid Build Coastguard Worker             for (i = 0; i < (int)m_detectedColors.size(); i++)
620*35238bceSAndroid Build Coastguard Worker             {
621*35238bceSAndroid Build Coastguard Worker                 if (tcu::compareThreshold(color, m_detectedColors[i], tcu::RGBA(3, 3, 3, 3)))
622*35238bceSAndroid Build Coastguard Worker                     break;
623*35238bceSAndroid Build Coastguard Worker             }
624*35238bceSAndroid Build Coastguard Worker 
625*35238bceSAndroid Build Coastguard Worker             if (i == (int)m_detectedColors.size())
626*35238bceSAndroid Build Coastguard Worker                 m_detectedColors.push_back(color); // Color not previously detected.
627*35238bceSAndroid Build Coastguard Worker         }
628*35238bceSAndroid Build Coastguard Worker 
629*35238bceSAndroid Build Coastguard Worker     // Log results.
630*35238bceSAndroid Build Coastguard Worker 
631*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Number of distinct colors detected so far: "
632*35238bceSAndroid Build Coastguard Worker         << ((int)m_detectedColors.size() >= requiredNumDistinctColors ? "at least " : "")
633*35238bceSAndroid Build Coastguard Worker         << de::toString(m_detectedColors.size()) << TestLog::EndMessage;
634*35238bceSAndroid Build Coastguard Worker 
635*35238bceSAndroid Build Coastguard Worker     if ((int)m_detectedColors.size() < requiredNumDistinctColors)
636*35238bceSAndroid Build Coastguard Worker     {
637*35238bceSAndroid Build Coastguard Worker         // Haven't detected enough different colors yet.
638*35238bceSAndroid Build Coastguard Worker 
639*35238bceSAndroid Build Coastguard Worker         m_currentIteration++;
640*35238bceSAndroid Build Coastguard Worker 
641*35238bceSAndroid Build Coastguard Worker         if (m_currentIteration >= m_maxNumIterations)
642*35238bceSAndroid Build Coastguard Worker         {
643*35238bceSAndroid Build Coastguard Worker             const IVec2 targetSize       = getRenderTargetSize();
644*35238bceSAndroid Build Coastguard Worker             const int detectedNumSamples = (int)m_detectedColors.size() - 1; // One color is the background
645*35238bceSAndroid Build Coastguard Worker 
646*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "Failure: Number of distinct colors detected is lower than sample count+1"
647*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
648*35238bceSAndroid Build Coastguard Worker 
649*35238bceSAndroid Build Coastguard Worker             // For high resolution render targets the lack of samples is not likely detected by a human
650*35238bceSAndroid Build Coastguard Worker             // and for GLES 3.0 the application cannot observe the sample count directly. So, it only
651*35238bceSAndroid Build Coastguard Worker             // warrants a quality warning.
652*35238bceSAndroid Build Coastguard Worker             if ((targetSize.x() >= 2048 || targetSize.y() >= 2048) && (detectedNumSamples >= (m_numSamples / 2)))
653*35238bceSAndroid Build Coastguard Worker                 m_context.getTestContext().setTestResult(QP_TEST_RESULT_QUALITY_WARNING,
654*35238bceSAndroid Build Coastguard Worker                                                          "Measured sample count below the advertised count");
655*35238bceSAndroid Build Coastguard Worker             else
656*35238bceSAndroid Build Coastguard Worker                 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
657*35238bceSAndroid Build Coastguard Worker             return STOP;
658*35238bceSAndroid Build Coastguard Worker         }
659*35238bceSAndroid Build Coastguard Worker         else
660*35238bceSAndroid Build Coastguard Worker         {
661*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message
662*35238bceSAndroid Build Coastguard Worker                 << "The number of distinct colors detected is lower than sample count+1 - trying again with a slightly "
663*35238bceSAndroid Build Coastguard Worker                    "altered pattern"
664*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
665*35238bceSAndroid Build Coastguard Worker             return CONTINUE;
666*35238bceSAndroid Build Coastguard Worker         }
667*35238bceSAndroid Build Coastguard Worker     }
668*35238bceSAndroid Build Coastguard Worker     else
669*35238bceSAndroid Build Coastguard Worker     {
670*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Success: The number of distinct colors detected is at least sample count+1"
671*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
672*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
673*35238bceSAndroid Build Coastguard Worker         return STOP;
674*35238bceSAndroid Build Coastguard Worker     }
675*35238bceSAndroid Build Coastguard Worker }
676*35238bceSAndroid Build Coastguard Worker 
677*35238bceSAndroid Build Coastguard Worker class PolygonNumSamplesCase : public NumSamplesCase
678*35238bceSAndroid Build Coastguard Worker {
679*35238bceSAndroid Build Coastguard Worker public:
680*35238bceSAndroid Build Coastguard Worker     PolygonNumSamplesCase(Context &context, const char *name, const char *description, int numFboSamples = 0);
~PolygonNumSamplesCase(void)681*35238bceSAndroid Build Coastguard Worker     ~PolygonNumSamplesCase(void)
682*35238bceSAndroid Build Coastguard Worker     {
683*35238bceSAndroid Build Coastguard Worker     }
684*35238bceSAndroid Build Coastguard Worker 
685*35238bceSAndroid Build Coastguard Worker protected:
686*35238bceSAndroid Build Coastguard Worker     void renderPattern(void) const;
687*35238bceSAndroid Build Coastguard Worker };
688*35238bceSAndroid Build Coastguard Worker 
PolygonNumSamplesCase(Context & context,const char * name,const char * description,int numFboSamples)689*35238bceSAndroid Build Coastguard Worker PolygonNumSamplesCase::PolygonNumSamplesCase(Context &context, const char *name, const char *description,
690*35238bceSAndroid Build Coastguard Worker                                              int numFboSamples)
691*35238bceSAndroid Build Coastguard Worker     : NumSamplesCase(context, name, description,
692*35238bceSAndroid Build Coastguard Worker                      numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
693*35238bceSAndroid Build Coastguard Worker {
694*35238bceSAndroid Build Coastguard Worker }
695*35238bceSAndroid Build Coastguard Worker 
renderPattern(void) const696*35238bceSAndroid Build Coastguard Worker void PolygonNumSamplesCase::renderPattern(void) const
697*35238bceSAndroid Build Coastguard Worker {
698*35238bceSAndroid Build Coastguard Worker     // The test pattern consists of several triangles with edges at different angles.
699*35238bceSAndroid Build Coastguard Worker 
700*35238bceSAndroid Build Coastguard Worker     const int numTriangles = 25;
701*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numTriangles; i++)
702*35238bceSAndroid Build Coastguard Worker     {
703*35238bceSAndroid Build Coastguard Worker         float angle0 = 2.0f * DE_PI * (float)i / (float)numTriangles + 0.001f * (float)m_currentIteration;
704*35238bceSAndroid Build Coastguard Worker         float angle1 = 2.0f * DE_PI * ((float)i + 0.5f) / (float)numTriangles + 0.001f * (float)m_currentIteration;
705*35238bceSAndroid Build Coastguard Worker 
706*35238bceSAndroid Build Coastguard Worker         renderTriangle(Vec2(0.0f, 0.0f), Vec2(deFloatCos(angle0) * 0.95f, deFloatSin(angle0) * 0.95f),
707*35238bceSAndroid Build Coastguard Worker                        Vec2(deFloatCos(angle1) * 0.95f, deFloatSin(angle1) * 0.95f), Vec4(1.0f));
708*35238bceSAndroid Build Coastguard Worker     }
709*35238bceSAndroid Build Coastguard Worker }
710*35238bceSAndroid Build Coastguard Worker 
711*35238bceSAndroid Build Coastguard Worker class LineNumSamplesCase : public NumSamplesCase
712*35238bceSAndroid Build Coastguard Worker {
713*35238bceSAndroid Build Coastguard Worker public:
714*35238bceSAndroid Build Coastguard Worker     LineNumSamplesCase(Context &context, const char *name, const char *description, int numFboSamples = 0);
~LineNumSamplesCase(void)715*35238bceSAndroid Build Coastguard Worker     ~LineNumSamplesCase(void)
716*35238bceSAndroid Build Coastguard Worker     {
717*35238bceSAndroid Build Coastguard Worker     }
718*35238bceSAndroid Build Coastguard Worker 
719*35238bceSAndroid Build Coastguard Worker protected:
720*35238bceSAndroid Build Coastguard Worker     void renderPattern(void) const;
721*35238bceSAndroid Build Coastguard Worker };
722*35238bceSAndroid Build Coastguard Worker 
LineNumSamplesCase(Context & context,const char * name,const char * description,int numFboSamples)723*35238bceSAndroid Build Coastguard Worker LineNumSamplesCase::LineNumSamplesCase(Context &context, const char *name, const char *description, int numFboSamples)
724*35238bceSAndroid Build Coastguard Worker     : NumSamplesCase(context, name, description,
725*35238bceSAndroid Build Coastguard Worker                      numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
726*35238bceSAndroid Build Coastguard Worker {
727*35238bceSAndroid Build Coastguard Worker }
728*35238bceSAndroid Build Coastguard Worker 
renderPattern(void) const729*35238bceSAndroid Build Coastguard Worker void LineNumSamplesCase::renderPattern(void) const
730*35238bceSAndroid Build Coastguard Worker {
731*35238bceSAndroid Build Coastguard Worker     // The test pattern consists of several lines at different angles.
732*35238bceSAndroid Build Coastguard Worker 
733*35238bceSAndroid Build Coastguard Worker     // We scale the number of lines based on the viewport size. This is because a gl line's thickness is
734*35238bceSAndroid Build Coastguard Worker     // constant in pixel units, i.e. they get relatively thicker as viewport size decreases. Thus we must
735*35238bceSAndroid Build Coastguard Worker     // decrease the number of lines in order to decrease the extent of overlap among the lines in the
736*35238bceSAndroid Build Coastguard Worker     // center of the pattern.
737*35238bceSAndroid Build Coastguard Worker     const int numLines = (int)(100.0f * deFloatSqrt((float)m_viewportSize / 256.0f));
738*35238bceSAndroid Build Coastguard Worker 
739*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numLines; i++)
740*35238bceSAndroid Build Coastguard Worker     {
741*35238bceSAndroid Build Coastguard Worker         float angle = 2.0f * DE_PI * (float)i / (float)numLines + 0.001f * (float)m_currentIteration;
742*35238bceSAndroid Build Coastguard Worker         renderLine(Vec2(0.0f, 0.0f), Vec2(deFloatCos(angle) * 0.95f, deFloatSin(angle) * 0.95f), Vec4(1.0f));
743*35238bceSAndroid Build Coastguard Worker     }
744*35238bceSAndroid Build Coastguard Worker }
745*35238bceSAndroid Build Coastguard Worker 
746*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
747*35238bceSAndroid Build Coastguard Worker  * \brief Case testing behaviour of common edges when multisampling.
748*35238bceSAndroid Build Coastguard Worker  *
749*35238bceSAndroid Build Coastguard Worker  * Draws a number of test patterns, each with a number of quads, each made
750*35238bceSAndroid Build Coastguard Worker  * of two triangles, rotated at different angles. The inner edge inside the
751*35238bceSAndroid Build Coastguard Worker  * quad (i.e. the common edge of the two triangles) still should not be
752*35238bceSAndroid Build Coastguard Worker  * visible, despite multisampling - i.e. the two triangles forming the quad
753*35238bceSAndroid Build Coastguard Worker  * should never get any common coverage bits in any pixel.
754*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
755*35238bceSAndroid Build Coastguard Worker class CommonEdgeCase : public MultisampleCase
756*35238bceSAndroid Build Coastguard Worker {
757*35238bceSAndroid Build Coastguard Worker public:
758*35238bceSAndroid Build Coastguard Worker     enum CaseType
759*35238bceSAndroid Build Coastguard Worker     {
760*35238bceSAndroid Build Coastguard Worker         CASETYPE_SMALL_QUADS = 0,           //!< Draw several small quads per iteration.
761*35238bceSAndroid Build Coastguard Worker         CASETYPE_BIGGER_THAN_VIEWPORT_QUAD, //!< Draw one bigger-than-viewport quad per iteration.
762*35238bceSAndroid Build Coastguard Worker         CASETYPE_FIT_VIEWPORT_QUAD,         //!< Draw one exactly viewport-sized, axis aligned quad per iteration.
763*35238bceSAndroid Build Coastguard Worker 
764*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
765*35238bceSAndroid Build Coastguard Worker     };
766*35238bceSAndroid Build Coastguard Worker 
767*35238bceSAndroid Build Coastguard Worker     CommonEdgeCase(Context &context, const char *name, const char *description, CaseType caseType,
768*35238bceSAndroid Build Coastguard Worker                    int numFboSamples = 0);
~CommonEdgeCase(void)769*35238bceSAndroid Build Coastguard Worker     ~CommonEdgeCase(void)
770*35238bceSAndroid Build Coastguard Worker     {
771*35238bceSAndroid Build Coastguard Worker     }
772*35238bceSAndroid Build Coastguard Worker 
773*35238bceSAndroid Build Coastguard Worker     void init(void);
774*35238bceSAndroid Build Coastguard Worker 
775*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
776*35238bceSAndroid Build Coastguard Worker 
777*35238bceSAndroid Build Coastguard Worker private:
778*35238bceSAndroid Build Coastguard Worker     enum
779*35238bceSAndroid Build Coastguard Worker     {
780*35238bceSAndroid Build Coastguard Worker         DEFAULT_SMALL_QUADS_ITERATIONS               = 16,
781*35238bceSAndroid Build Coastguard Worker         DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS = 8 * 8
782*35238bceSAndroid Build Coastguard Worker         // \note With CASETYPE_FIT_VIEWPORT_QUAD, we don't do rotations other than multiples of 90 deg -> constant number of iterations.
783*35238bceSAndroid Build Coastguard Worker     };
784*35238bceSAndroid Build Coastguard Worker 
785*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
786*35238bceSAndroid Build Coastguard Worker 
787*35238bceSAndroid Build Coastguard Worker     const int m_numIterations;
788*35238bceSAndroid Build Coastguard Worker     int m_currentIteration;
789*35238bceSAndroid Build Coastguard Worker };
790*35238bceSAndroid Build Coastguard Worker 
CommonEdgeCase(Context & context,const char * name,const char * description,CaseType caseType,int numFboSamples)791*35238bceSAndroid Build Coastguard Worker CommonEdgeCase::CommonEdgeCase(Context &context, const char *name, const char *description, CaseType caseType,
792*35238bceSAndroid Build Coastguard Worker                                int numFboSamples)
793*35238bceSAndroid Build Coastguard Worker     : MultisampleCase(context, name, description, caseType == CASETYPE_SMALL_QUADS ? 128 : 32,
794*35238bceSAndroid Build Coastguard Worker                       numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
795*35238bceSAndroid Build Coastguard Worker     , m_caseType(caseType)
796*35238bceSAndroid Build Coastguard Worker     , m_numIterations(caseType == CASETYPE_SMALL_QUADS ?
797*35238bceSAndroid Build Coastguard Worker                           getIterationCount(m_testCtx, DEFAULT_SMALL_QUADS_ITERATIONS) :
798*35238bceSAndroid Build Coastguard Worker                       caseType == CASETYPE_BIGGER_THAN_VIEWPORT_QUAD ?
799*35238bceSAndroid Build Coastguard Worker                           getIterationCount(m_testCtx, DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS) :
800*35238bceSAndroid Build Coastguard Worker                           8)
801*35238bceSAndroid Build Coastguard Worker     , m_currentIteration(0)
802*35238bceSAndroid Build Coastguard Worker {
803*35238bceSAndroid Build Coastguard Worker }
804*35238bceSAndroid Build Coastguard Worker 
init(void)805*35238bceSAndroid Build Coastguard Worker void CommonEdgeCase::init(void)
806*35238bceSAndroid Build Coastguard Worker {
807*35238bceSAndroid Build Coastguard Worker     MultisampleCase::init();
808*35238bceSAndroid Build Coastguard Worker 
809*35238bceSAndroid Build Coastguard Worker     if (m_caseType == CASETYPE_SMALL_QUADS)
810*35238bceSAndroid Build Coastguard Worker     {
811*35238bceSAndroid Build Coastguard Worker         // Check for a big enough viewport. With too small viewports the test case can't analyze the resulting image well enough.
812*35238bceSAndroid Build Coastguard Worker 
813*35238bceSAndroid Build Coastguard Worker         const int minViewportSize = 32;
814*35238bceSAndroid Build Coastguard Worker 
815*35238bceSAndroid Build Coastguard Worker         if (m_viewportSize < minViewportSize)
816*35238bceSAndroid Build Coastguard Worker             throw tcu::InternalError("Render target width or height too low (is " + de::toString(m_viewportSize) +
817*35238bceSAndroid Build Coastguard Worker                                      ", should be at least " + de::toString(minViewportSize) + ")");
818*35238bceSAndroid Build Coastguard Worker     }
819*35238bceSAndroid Build Coastguard Worker 
820*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnable(GL_BLEND));
821*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glBlendEquation(GL_FUNC_ADD));
822*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glBlendFunc(GL_ONE, GL_ONE));
823*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << TestLog::Message
824*35238bceSAndroid Build Coastguard Worker                        << "Additive blending enabled in order to detect (erroneously) overlapping samples"
825*35238bceSAndroid Build Coastguard Worker                        << TestLog::EndMessage;
826*35238bceSAndroid Build Coastguard Worker }
827*35238bceSAndroid Build Coastguard Worker 
iterate(void)828*35238bceSAndroid Build Coastguard Worker CommonEdgeCase::IterateResult CommonEdgeCase::iterate(void)
829*35238bceSAndroid Build Coastguard Worker {
830*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
831*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImg(m_viewportSize, m_viewportSize);
832*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorImg(m_viewportSize, m_viewportSize);
833*35238bceSAndroid Build Coastguard Worker 
834*35238bceSAndroid Build Coastguard Worker     randomizeViewport();
835*35238bceSAndroid Build Coastguard Worker 
836*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
837*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
838*35238bceSAndroid Build Coastguard Worker 
839*35238bceSAndroid Build Coastguard Worker     // Draw test pattern. Test patterns consist of quads formed with two triangles.
840*35238bceSAndroid Build Coastguard Worker     // After drawing the pattern, we check that the interior pixels of each quad are
841*35238bceSAndroid Build Coastguard Worker     // all the same color - this is meant to verify that there are no artifacts on the inner edge.
842*35238bceSAndroid Build Coastguard Worker 
843*35238bceSAndroid Build Coastguard Worker     vector<QuadCorners> unicoloredRegions;
844*35238bceSAndroid Build Coastguard Worker 
845*35238bceSAndroid Build Coastguard Worker     if (m_caseType == CASETYPE_SMALL_QUADS)
846*35238bceSAndroid Build Coastguard Worker     {
847*35238bceSAndroid Build Coastguard Worker         // Draw several quads, rotated at different angles.
848*35238bceSAndroid Build Coastguard Worker 
849*35238bceSAndroid Build Coastguard Worker         const float quadDiagLen = 2.0f / 3.0f * 0.9f; // \note Fit 3 quads in both x and y directions.
850*35238bceSAndroid Build Coastguard Worker         float angleCos;
851*35238bceSAndroid Build Coastguard Worker         float angleSin;
852*35238bceSAndroid Build Coastguard Worker 
853*35238bceSAndroid Build Coastguard Worker         // \note First and second iteration get exact 0 (and 90, 180, 270) and 45 (and 135, 225, 315) angle quads, as they are kind of a special case.
854*35238bceSAndroid Build Coastguard Worker 
855*35238bceSAndroid Build Coastguard Worker         if (m_currentIteration == 0)
856*35238bceSAndroid Build Coastguard Worker         {
857*35238bceSAndroid Build Coastguard Worker             angleCos = 1.0f;
858*35238bceSAndroid Build Coastguard Worker             angleSin = 0.0f;
859*35238bceSAndroid Build Coastguard Worker         }
860*35238bceSAndroid Build Coastguard Worker         else if (m_currentIteration == 1)
861*35238bceSAndroid Build Coastguard Worker         {
862*35238bceSAndroid Build Coastguard Worker             angleCos = SQRT_HALF;
863*35238bceSAndroid Build Coastguard Worker             angleSin = SQRT_HALF;
864*35238bceSAndroid Build Coastguard Worker         }
865*35238bceSAndroid Build Coastguard Worker         else
866*35238bceSAndroid Build Coastguard Worker         {
867*35238bceSAndroid Build Coastguard Worker             float angle = 0.5f * DE_PI * (float)(m_currentIteration - 1) / (float)(m_numIterations - 1);
868*35238bceSAndroid Build Coastguard Worker             angleCos    = deFloatCos(angle);
869*35238bceSAndroid Build Coastguard Worker             angleSin    = deFloatSin(angle);
870*35238bceSAndroid Build Coastguard Worker         }
871*35238bceSAndroid Build Coastguard Worker 
872*35238bceSAndroid Build Coastguard Worker         Vec2 corners[4] = {
873*35238bceSAndroid Build Coastguard Worker             0.5f * quadDiagLen * Vec2(angleCos, angleSin), 0.5f * quadDiagLen * Vec2(-angleSin, angleCos),
874*35238bceSAndroid Build Coastguard Worker             0.5f * quadDiagLen * Vec2(-angleCos, -angleSin), 0.5f * quadDiagLen * Vec2(angleSin, -angleCos)};
875*35238bceSAndroid Build Coastguard Worker 
876*35238bceSAndroid Build Coastguard Worker         unicoloredRegions.reserve(8);
877*35238bceSAndroid Build Coastguard Worker 
878*35238bceSAndroid Build Coastguard Worker         // Draw 8 quads.
879*35238bceSAndroid Build Coastguard Worker         // First four are rotated at angles angle+0, angle+90, angle+180 and angle+270.
880*35238bceSAndroid Build Coastguard Worker         // Last four are rotated the same angles as the first four, but the ordering of the last triangle's vertices is reversed.
881*35238bceSAndroid Build Coastguard Worker 
882*35238bceSAndroid Build Coastguard Worker         for (int quadNdx = 0; quadNdx < 8; quadNdx++)
883*35238bceSAndroid Build Coastguard Worker         {
884*35238bceSAndroid Build Coastguard Worker             Vec2 center = (2.0f - quadDiagLen) * Vec2((float)(quadNdx % 3), (float)(quadNdx / 3)) / 2.0f -
885*35238bceSAndroid Build Coastguard Worker                           0.5f * (2.0f - quadDiagLen);
886*35238bceSAndroid Build Coastguard Worker 
887*35238bceSAndroid Build Coastguard Worker             renderTriangle(corners[(0 + quadNdx) % 4] + center, corners[(1 + quadNdx) % 4] + center,
888*35238bceSAndroid Build Coastguard Worker                            corners[(2 + quadNdx) % 4] + center, Vec4(0.5f, 0.5f, 0.5f, 1.0f));
889*35238bceSAndroid Build Coastguard Worker 
890*35238bceSAndroid Build Coastguard Worker             if (quadNdx >= 4)
891*35238bceSAndroid Build Coastguard Worker             {
892*35238bceSAndroid Build Coastguard Worker                 renderTriangle(corners[(3 + quadNdx) % 4] + center, corners[(2 + quadNdx) % 4] + center,
893*35238bceSAndroid Build Coastguard Worker                                corners[(0 + quadNdx) % 4] + center, Vec4(0.5f, 0.5f, 0.5f, 1.0f));
894*35238bceSAndroid Build Coastguard Worker             }
895*35238bceSAndroid Build Coastguard Worker             else
896*35238bceSAndroid Build Coastguard Worker             {
897*35238bceSAndroid Build Coastguard Worker                 renderTriangle(corners[(0 + quadNdx) % 4] + center, corners[(2 + quadNdx) % 4] + center,
898*35238bceSAndroid Build Coastguard Worker                                corners[(3 + quadNdx) % 4] + center, Vec4(0.5f, 0.5f, 0.5f, 1.0f));
899*35238bceSAndroid Build Coastguard Worker             }
900*35238bceSAndroid Build Coastguard Worker 
901*35238bceSAndroid Build Coastguard Worker             // The size of the "interior" of a quad is assumed to be approximately unicolorRegionScale*<actual size of quad>.
902*35238bceSAndroid Build Coastguard Worker             // By "interior" we here mean the region of non-boundary pixels of the rendered quad for which we can safely assume
903*35238bceSAndroid Build Coastguard Worker             // that it has all coverage bits set to 1, for every pixel.
904*35238bceSAndroid Build Coastguard Worker             float unicolorRegionScale = 1.0f - 6.0f * 2.0f / (float)m_viewportSize / quadDiagLen;
905*35238bceSAndroid Build Coastguard Worker             unicoloredRegions.push_back(
906*35238bceSAndroid Build Coastguard Worker                 QuadCorners((center + corners[0] * unicolorRegionScale), (center + corners[1] * unicolorRegionScale),
907*35238bceSAndroid Build Coastguard Worker                             (center + corners[2] * unicolorRegionScale), (center + corners[3] * unicolorRegionScale)));
908*35238bceSAndroid Build Coastguard Worker         }
909*35238bceSAndroid Build Coastguard Worker     }
910*35238bceSAndroid Build Coastguard Worker     else if (m_caseType == CASETYPE_BIGGER_THAN_VIEWPORT_QUAD)
911*35238bceSAndroid Build Coastguard Worker     {
912*35238bceSAndroid Build Coastguard Worker         // Draw a bigger-than-viewport quad, rotated at an angle depending on m_currentIteration.
913*35238bceSAndroid Build Coastguard Worker 
914*35238bceSAndroid Build Coastguard Worker         int quadBaseAngleNdx = m_currentIteration / 8;
915*35238bceSAndroid Build Coastguard Worker         int quadSubAngleNdx  = m_currentIteration % 8;
916*35238bceSAndroid Build Coastguard Worker         float angleCos;
917*35238bceSAndroid Build Coastguard Worker         float angleSin;
918*35238bceSAndroid Build Coastguard Worker 
919*35238bceSAndroid Build Coastguard Worker         if (quadBaseAngleNdx == 0)
920*35238bceSAndroid Build Coastguard Worker         {
921*35238bceSAndroid Build Coastguard Worker             angleCos = 1.0f;
922*35238bceSAndroid Build Coastguard Worker             angleSin = 0.0f;
923*35238bceSAndroid Build Coastguard Worker         }
924*35238bceSAndroid Build Coastguard Worker         else if (quadBaseAngleNdx == 1)
925*35238bceSAndroid Build Coastguard Worker         {
926*35238bceSAndroid Build Coastguard Worker             angleCos = SQRT_HALF;
927*35238bceSAndroid Build Coastguard Worker             angleSin = SQRT_HALF;
928*35238bceSAndroid Build Coastguard Worker         }
929*35238bceSAndroid Build Coastguard Worker         else
930*35238bceSAndroid Build Coastguard Worker         {
931*35238bceSAndroid Build Coastguard Worker             float angle = 0.5f * DE_PI * (float)(m_currentIteration - 1) / (float)(m_numIterations - 1);
932*35238bceSAndroid Build Coastguard Worker             angleCos    = deFloatCos(angle);
933*35238bceSAndroid Build Coastguard Worker             angleSin    = deFloatSin(angle);
934*35238bceSAndroid Build Coastguard Worker         }
935*35238bceSAndroid Build Coastguard Worker 
936*35238bceSAndroid Build Coastguard Worker         float quadDiagLen = 2.5f / de::max(angleCos, angleSin);
937*35238bceSAndroid Build Coastguard Worker 
938*35238bceSAndroid Build Coastguard Worker         Vec2 corners[4] = {
939*35238bceSAndroid Build Coastguard Worker             0.5f * quadDiagLen * Vec2(angleCos, angleSin), 0.5f * quadDiagLen * Vec2(-angleSin, angleCos),
940*35238bceSAndroid Build Coastguard Worker             0.5f * quadDiagLen * Vec2(-angleCos, -angleSin), 0.5f * quadDiagLen * Vec2(angleSin, -angleCos)};
941*35238bceSAndroid Build Coastguard Worker 
942*35238bceSAndroid Build Coastguard Worker         renderTriangle(corners[(0 + quadSubAngleNdx) % 4], corners[(1 + quadSubAngleNdx) % 4],
943*35238bceSAndroid Build Coastguard Worker                        corners[(2 + quadSubAngleNdx) % 4], Vec4(0.5f, 0.5f, 0.5f, 1.0f));
944*35238bceSAndroid Build Coastguard Worker 
945*35238bceSAndroid Build Coastguard Worker         if (quadSubAngleNdx >= 4)
946*35238bceSAndroid Build Coastguard Worker         {
947*35238bceSAndroid Build Coastguard Worker             renderTriangle(corners[(3 + quadSubAngleNdx) % 4], corners[(2 + quadSubAngleNdx) % 4],
948*35238bceSAndroid Build Coastguard Worker                            corners[(0 + quadSubAngleNdx) % 4], Vec4(0.5f, 0.5f, 0.5f, 1.0f));
949*35238bceSAndroid Build Coastguard Worker         }
950*35238bceSAndroid Build Coastguard Worker         else
951*35238bceSAndroid Build Coastguard Worker         {
952*35238bceSAndroid Build Coastguard Worker             renderTriangle(corners[(0 + quadSubAngleNdx) % 4], corners[(2 + quadSubAngleNdx) % 4],
953*35238bceSAndroid Build Coastguard Worker                            corners[(3 + quadSubAngleNdx) % 4], Vec4(0.5f, 0.5f, 0.5f, 1.0f));
954*35238bceSAndroid Build Coastguard Worker         }
955*35238bceSAndroid Build Coastguard Worker 
956*35238bceSAndroid Build Coastguard Worker         float unicolorRegionScale = 1.0f - 6.0f * 2.0f / (float)m_viewportSize / quadDiagLen;
957*35238bceSAndroid Build Coastguard Worker         unicoloredRegions.push_back(QuadCorners((corners[0] * unicolorRegionScale), (corners[1] * unicolorRegionScale),
958*35238bceSAndroid Build Coastguard Worker                                                 (corners[2] * unicolorRegionScale),
959*35238bceSAndroid Build Coastguard Worker                                                 (corners[3] * unicolorRegionScale)));
960*35238bceSAndroid Build Coastguard Worker     }
961*35238bceSAndroid Build Coastguard Worker     else if (m_caseType == CASETYPE_FIT_VIEWPORT_QUAD)
962*35238bceSAndroid Build Coastguard Worker     {
963*35238bceSAndroid Build Coastguard Worker         // Draw an exactly viewport-sized quad, rotated by multiples of 90 degrees angle depending on m_currentIteration.
964*35238bceSAndroid Build Coastguard Worker 
965*35238bceSAndroid Build Coastguard Worker         int quadSubAngleNdx = m_currentIteration % 8;
966*35238bceSAndroid Build Coastguard Worker 
967*35238bceSAndroid Build Coastguard Worker         Vec2 corners[4] = {Vec2(1.0f, 1.0f), Vec2(-1.0f, 1.0f), Vec2(-1.0f, -1.0f), Vec2(1.0f, -1.0f)};
968*35238bceSAndroid Build Coastguard Worker 
969*35238bceSAndroid Build Coastguard Worker         renderTriangle(corners[(0 + quadSubAngleNdx) % 4], corners[(1 + quadSubAngleNdx) % 4],
970*35238bceSAndroid Build Coastguard Worker                        corners[(2 + quadSubAngleNdx) % 4], Vec4(0.5f, 0.5f, 0.5f, 1.0f));
971*35238bceSAndroid Build Coastguard Worker 
972*35238bceSAndroid Build Coastguard Worker         if (quadSubAngleNdx >= 4)
973*35238bceSAndroid Build Coastguard Worker         {
974*35238bceSAndroid Build Coastguard Worker             renderTriangle(corners[(3 + quadSubAngleNdx) % 4], corners[(2 + quadSubAngleNdx) % 4],
975*35238bceSAndroid Build Coastguard Worker                            corners[(0 + quadSubAngleNdx) % 4], Vec4(0.5f, 0.5f, 0.5f, 1.0f));
976*35238bceSAndroid Build Coastguard Worker         }
977*35238bceSAndroid Build Coastguard Worker         else
978*35238bceSAndroid Build Coastguard Worker         {
979*35238bceSAndroid Build Coastguard Worker             renderTriangle(corners[(0 + quadSubAngleNdx) % 4], corners[(2 + quadSubAngleNdx) % 4],
980*35238bceSAndroid Build Coastguard Worker                            corners[(3 + quadSubAngleNdx) % 4], Vec4(0.5f, 0.5f, 0.5f, 1.0f));
981*35238bceSAndroid Build Coastguard Worker         }
982*35238bceSAndroid Build Coastguard Worker 
983*35238bceSAndroid Build Coastguard Worker         unicoloredRegions.push_back(QuadCorners(corners[0], corners[1], corners[2], corners[3]));
984*35238bceSAndroid Build Coastguard Worker     }
985*35238bceSAndroid Build Coastguard Worker     else
986*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
987*35238bceSAndroid Build Coastguard Worker 
988*35238bceSAndroid Build Coastguard Worker     // Read pixels and check unicolored regions.
989*35238bceSAndroid Build Coastguard Worker 
990*35238bceSAndroid Build Coastguard Worker     readImage(renderedImg);
991*35238bceSAndroid Build Coastguard Worker 
992*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorImg.getAccess(), Vec4(0.0f, 1.0f, 0.0f, 1.0f));
993*35238bceSAndroid Build Coastguard Worker 
994*35238bceSAndroid Build Coastguard Worker     log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
995*35238bceSAndroid Build Coastguard Worker 
996*35238bceSAndroid Build Coastguard Worker     bool errorsDetected = false;
997*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)unicoloredRegions.size(); i++)
998*35238bceSAndroid Build Coastguard Worker     {
999*35238bceSAndroid Build Coastguard Worker         const QuadCorners &region  = unicoloredRegions[i];
1000*35238bceSAndroid Build Coastguard Worker         IVec2 p0Win                = ((region.p0 + 1.0f) * 0.5f * (float)(m_viewportSize - 1) + 0.5f).asInt();
1001*35238bceSAndroid Build Coastguard Worker         IVec2 p1Win                = ((region.p1 + 1.0f) * 0.5f * (float)(m_viewportSize - 1) + 0.5f).asInt();
1002*35238bceSAndroid Build Coastguard Worker         IVec2 p2Win                = ((region.p2 + 1.0f) * 0.5f * (float)(m_viewportSize - 1) + 0.5f).asInt();
1003*35238bceSAndroid Build Coastguard Worker         IVec2 p3Win                = ((region.p3 + 1.0f) * 0.5f * (float)(m_viewportSize - 1) + 0.5f).asInt();
1004*35238bceSAndroid Build Coastguard Worker         bool errorsInCurrentRegion = !isPixelRegionUnicolored(renderedImg, p0Win, p1Win, p2Win, p3Win);
1005*35238bceSAndroid Build Coastguard Worker 
1006*35238bceSAndroid Build Coastguard Worker         if (errorsInCurrentRegion)
1007*35238bceSAndroid Build Coastguard Worker             drawUnicolorTestErrors(renderedImg, errorImg.getAccess(), p0Win, p1Win, p2Win, p3Win);
1008*35238bceSAndroid Build Coastguard Worker 
1009*35238bceSAndroid Build Coastguard Worker         errorsDetected = errorsDetected || errorsInCurrentRegion;
1010*35238bceSAndroid Build Coastguard Worker     }
1011*35238bceSAndroid Build Coastguard Worker 
1012*35238bceSAndroid Build Coastguard Worker     m_currentIteration++;
1013*35238bceSAndroid Build Coastguard Worker 
1014*35238bceSAndroid Build Coastguard Worker     if (errorsDetected)
1015*35238bceSAndroid Build Coastguard Worker     {
1016*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Failure: Not all quad interiors seem unicolored - common-edge artifacts?"
1017*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
1018*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Erroneous pixels are drawn red in the following image" << TestLog::EndMessage;
1019*35238bceSAndroid Build Coastguard Worker         log << TestLog::Image("RenderedImageWithErrors", "Rendered image with errors marked", renderedImg,
1020*35238bceSAndroid Build Coastguard Worker                               QP_IMAGE_COMPRESSION_MODE_PNG);
1021*35238bceSAndroid Build Coastguard Worker         log << TestLog::Image("ErrorsOnly", "Image with error pixels only", errorImg, QP_IMAGE_COMPRESSION_MODE_PNG);
1022*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
1023*35238bceSAndroid Build Coastguard Worker         return STOP;
1024*35238bceSAndroid Build Coastguard Worker     }
1025*35238bceSAndroid Build Coastguard Worker     else if (m_currentIteration < m_numIterations)
1026*35238bceSAndroid Build Coastguard Worker     {
1027*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Quads seem OK - moving on to next pattern" << TestLog::EndMessage;
1028*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
1029*35238bceSAndroid Build Coastguard Worker     }
1030*35238bceSAndroid Build Coastguard Worker     else
1031*35238bceSAndroid Build Coastguard Worker     {
1032*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Success: All quad interiors seem unicolored (no common-edge artifacts)"
1033*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
1034*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
1035*35238bceSAndroid Build Coastguard Worker         return STOP;
1036*35238bceSAndroid Build Coastguard Worker     }
1037*35238bceSAndroid Build Coastguard Worker }
1038*35238bceSAndroid Build Coastguard Worker 
1039*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1040*35238bceSAndroid Build Coastguard Worker  * \brief Test that depth values are per-sample.
1041*35238bceSAndroid Build Coastguard Worker  *
1042*35238bceSAndroid Build Coastguard Worker  * Draws intersecting, differently-colored polygons and checks that there
1043*35238bceSAndroid Build Coastguard Worker  * are at least sample count+1 distinct colors present, due to some of the
1044*35238bceSAndroid Build Coastguard Worker  * samples at the intersection line belonging to one and some to another
1045*35238bceSAndroid Build Coastguard Worker  * polygon.
1046*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
1047*35238bceSAndroid Build Coastguard Worker class SampleDepthCase : public NumSamplesCase
1048*35238bceSAndroid Build Coastguard Worker {
1049*35238bceSAndroid Build Coastguard Worker public:
1050*35238bceSAndroid Build Coastguard Worker     SampleDepthCase(Context &context, const char *name, const char *description, int numFboSamples = 0);
~SampleDepthCase(void)1051*35238bceSAndroid Build Coastguard Worker     ~SampleDepthCase(void)
1052*35238bceSAndroid Build Coastguard Worker     {
1053*35238bceSAndroid Build Coastguard Worker     }
1054*35238bceSAndroid Build Coastguard Worker 
1055*35238bceSAndroid Build Coastguard Worker     void init(void);
1056*35238bceSAndroid Build Coastguard Worker 
1057*35238bceSAndroid Build Coastguard Worker protected:
1058*35238bceSAndroid Build Coastguard Worker     void renderPattern(void) const;
1059*35238bceSAndroid Build Coastguard Worker };
1060*35238bceSAndroid Build Coastguard Worker 
SampleDepthCase(Context & context,const char * name,const char * description,int numFboSamples)1061*35238bceSAndroid Build Coastguard Worker SampleDepthCase::SampleDepthCase(Context &context, const char *name, const char *description, int numFboSamples)
1062*35238bceSAndroid Build Coastguard Worker     : NumSamplesCase(context, name, description,
1063*35238bceSAndroid Build Coastguard Worker                      numFboSamples >= 0 ? FboParams(numFboSamples, true, false) : FboParams())
1064*35238bceSAndroid Build Coastguard Worker {
1065*35238bceSAndroid Build Coastguard Worker }
1066*35238bceSAndroid Build Coastguard Worker 
init(void)1067*35238bceSAndroid Build Coastguard Worker void SampleDepthCase::init(void)
1068*35238bceSAndroid Build Coastguard Worker {
1069*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1070*35238bceSAndroid Build Coastguard Worker 
1071*35238bceSAndroid Build Coastguard Worker     if (m_context.getRenderTarget().getDepthBits() == 0)
1072*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Test requires depth buffer");
1073*35238bceSAndroid Build Coastguard Worker 
1074*35238bceSAndroid Build Coastguard Worker     MultisampleCase::init();
1075*35238bceSAndroid Build Coastguard Worker 
1076*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnable(GL_DEPTH_TEST));
1077*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glDepthFunc(GL_LESS));
1078*35238bceSAndroid Build Coastguard Worker 
1079*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Depth test enabled, depth func is GL_LESS" << TestLog::EndMessage;
1080*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Drawing several bigger-than-viewport black or white polygons intersecting each other"
1081*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1082*35238bceSAndroid Build Coastguard Worker }
1083*35238bceSAndroid Build Coastguard Worker 
renderPattern(void) const1084*35238bceSAndroid Build Coastguard Worker void SampleDepthCase::renderPattern(void) const
1085*35238bceSAndroid Build Coastguard Worker {
1086*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
1087*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearDepthf(1.0f));
1088*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
1089*35238bceSAndroid Build Coastguard Worker 
1090*35238bceSAndroid Build Coastguard Worker     {
1091*35238bceSAndroid Build Coastguard Worker         const int numPolygons = 50;
1092*35238bceSAndroid Build Coastguard Worker 
1093*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numPolygons; i++)
1094*35238bceSAndroid Build Coastguard Worker         {
1095*35238bceSAndroid Build Coastguard Worker             Vec4 color  = i % 2 == 0 ? Vec4(1.0f, 1.0f, 1.0f, 1.0f) : Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1096*35238bceSAndroid Build Coastguard Worker             float angle = 2.0f * DE_PI * (float)i / (float)numPolygons + 0.001f * (float)m_currentIteration;
1097*35238bceSAndroid Build Coastguard Worker             Vec3 pt0(3.0f * deFloatCos(angle + 2.0f * DE_PI * 0.0f / 3.0f),
1098*35238bceSAndroid Build Coastguard Worker                      3.0f * deFloatSin(angle + 2.0f * DE_PI * 0.0f / 3.0f), 1.0f);
1099*35238bceSAndroid Build Coastguard Worker             Vec3 pt1(3.0f * deFloatCos(angle + 2.0f * DE_PI * 1.0f / 3.0f),
1100*35238bceSAndroid Build Coastguard Worker                      3.0f * deFloatSin(angle + 2.0f * DE_PI * 1.0f / 3.0f), 0.0f);
1101*35238bceSAndroid Build Coastguard Worker             Vec3 pt2(3.0f * deFloatCos(angle + 2.0f * DE_PI * 2.0f / 3.0f),
1102*35238bceSAndroid Build Coastguard Worker                      3.0f * deFloatSin(angle + 2.0f * DE_PI * 2.0f / 3.0f), 0.0f);
1103*35238bceSAndroid Build Coastguard Worker 
1104*35238bceSAndroid Build Coastguard Worker             renderTriangle(pt0, pt1, pt2, color);
1105*35238bceSAndroid Build Coastguard Worker         }
1106*35238bceSAndroid Build Coastguard Worker     }
1107*35238bceSAndroid Build Coastguard Worker }
1108*35238bceSAndroid Build Coastguard Worker 
1109*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1110*35238bceSAndroid Build Coastguard Worker  * \brief Test that stencil buffer values are per-sample.
1111*35238bceSAndroid Build Coastguard Worker  *
1112*35238bceSAndroid Build Coastguard Worker  * Draws a unicolored pattern and marks drawn samples in stencil buffer;
1113*35238bceSAndroid Build Coastguard Worker  * then clears and draws a viewport-size quad with that color and with
1114*35238bceSAndroid Build Coastguard Worker  * proper stencil test such that the resulting image should be exactly the
1115*35238bceSAndroid Build Coastguard Worker  * same as after the pattern was first drawn.
1116*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
1117*35238bceSAndroid Build Coastguard Worker class SampleStencilCase : public MultisampleCase
1118*35238bceSAndroid Build Coastguard Worker {
1119*35238bceSAndroid Build Coastguard Worker public:
1120*35238bceSAndroid Build Coastguard Worker     SampleStencilCase(Context &context, const char *name, const char *description, int numFboSamples = 0);
~SampleStencilCase(void)1121*35238bceSAndroid Build Coastguard Worker     ~SampleStencilCase(void)
1122*35238bceSAndroid Build Coastguard Worker     {
1123*35238bceSAndroid Build Coastguard Worker     }
1124*35238bceSAndroid Build Coastguard Worker 
1125*35238bceSAndroid Build Coastguard Worker     void init(void);
1126*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1127*35238bceSAndroid Build Coastguard Worker };
1128*35238bceSAndroid Build Coastguard Worker 
SampleStencilCase(Context & context,const char * name,const char * description,int numFboSamples)1129*35238bceSAndroid Build Coastguard Worker SampleStencilCase::SampleStencilCase(Context &context, const char *name, const char *description, int numFboSamples)
1130*35238bceSAndroid Build Coastguard Worker     : MultisampleCase(context, name, description, 256,
1131*35238bceSAndroid Build Coastguard Worker                       numFboSamples >= 0 ? FboParams(numFboSamples, false, true) : FboParams())
1132*35238bceSAndroid Build Coastguard Worker {
1133*35238bceSAndroid Build Coastguard Worker }
1134*35238bceSAndroid Build Coastguard Worker 
init(void)1135*35238bceSAndroid Build Coastguard Worker void SampleStencilCase::init(void)
1136*35238bceSAndroid Build Coastguard Worker {
1137*35238bceSAndroid Build Coastguard Worker     if (m_context.getRenderTarget().getStencilBits() == 0)
1138*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Test requires stencil buffer");
1139*35238bceSAndroid Build Coastguard Worker 
1140*35238bceSAndroid Build Coastguard Worker     MultisampleCase::init();
1141*35238bceSAndroid Build Coastguard Worker }
1142*35238bceSAndroid Build Coastguard Worker 
iterate(void)1143*35238bceSAndroid Build Coastguard Worker SampleStencilCase::IterateResult SampleStencilCase::iterate(void)
1144*35238bceSAndroid Build Coastguard Worker {
1145*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1146*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImgFirst(m_viewportSize, m_viewportSize);
1147*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImgSecond(m_viewportSize, m_viewportSize);
1148*35238bceSAndroid Build Coastguard Worker 
1149*35238bceSAndroid Build Coastguard Worker     randomizeViewport();
1150*35238bceSAndroid Build Coastguard Worker 
1151*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
1152*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearStencil(0));
1153*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
1154*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnable(GL_STENCIL_TEST));
1155*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glStencilFunc(GL_ALWAYS, 1, 1));
1156*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE));
1157*35238bceSAndroid Build Coastguard Worker 
1158*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message
1159*35238bceSAndroid Build Coastguard Worker         << "Drawing a pattern with glStencilFunc(GL_ALWAYS, 1, 1) and glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)"
1160*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1161*35238bceSAndroid Build Coastguard Worker 
1162*35238bceSAndroid Build Coastguard Worker     {
1163*35238bceSAndroid Build Coastguard Worker         const int numTriangles = 25;
1164*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numTriangles; i++)
1165*35238bceSAndroid Build Coastguard Worker         {
1166*35238bceSAndroid Build Coastguard Worker             float angle0 = 2.0f * DE_PI * (float)i / (float)numTriangles;
1167*35238bceSAndroid Build Coastguard Worker             float angle1 = 2.0f * DE_PI * ((float)i + 0.5f) / (float)numTriangles;
1168*35238bceSAndroid Build Coastguard Worker 
1169*35238bceSAndroid Build Coastguard Worker             renderTriangle(Vec2(0.0f, 0.0f), Vec2(deFloatCos(angle0) * 0.95f, deFloatSin(angle0) * 0.95f),
1170*35238bceSAndroid Build Coastguard Worker                            Vec2(deFloatCos(angle1) * 0.95f, deFloatSin(angle1) * 0.95f), Vec4(1.0f));
1171*35238bceSAndroid Build Coastguard Worker         }
1172*35238bceSAndroid Build Coastguard Worker     }
1173*35238bceSAndroid Build Coastguard Worker 
1174*35238bceSAndroid Build Coastguard Worker     readImage(renderedImgFirst);
1175*35238bceSAndroid Build Coastguard Worker     log << TestLog::Image("RenderedImgFirst", "First image rendered", renderedImgFirst, QP_IMAGE_COMPRESSION_MODE_PNG);
1176*35238bceSAndroid Build Coastguard Worker 
1177*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Clearing color buffer to black" << TestLog::EndMessage;
1178*35238bceSAndroid Build Coastguard Worker 
1179*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
1180*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glStencilFunc(GL_EQUAL, 1, 1));
1181*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP));
1182*35238bceSAndroid Build Coastguard Worker 
1183*35238bceSAndroid Build Coastguard Worker     {
1184*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Checking that color buffer was actually cleared to black" << TestLog::EndMessage;
1185*35238bceSAndroid Build Coastguard Worker 
1186*35238bceSAndroid Build Coastguard Worker         tcu::Surface clearedImg(m_viewportSize, m_viewportSize);
1187*35238bceSAndroid Build Coastguard Worker         readImage(clearedImg);
1188*35238bceSAndroid Build Coastguard Worker 
1189*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < clearedImg.getHeight(); y++)
1190*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < clearedImg.getWidth(); x++)
1191*35238bceSAndroid Build Coastguard Worker             {
1192*35238bceSAndroid Build Coastguard Worker                 const tcu::RGBA &clr = clearedImg.getPixel(x, y);
1193*35238bceSAndroid Build Coastguard Worker                 if (clr != tcu::RGBA::black())
1194*35238bceSAndroid Build Coastguard Worker                 {
1195*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "Failure: first non-black pixel, color " << clr
1196*35238bceSAndroid Build Coastguard Worker                         << ", detected at coordinates (" << x << ", " << y << ")" << TestLog::EndMessage;
1197*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Image("ClearedImg", "Image after clearing, erroneously non-black", clearedImg);
1198*35238bceSAndroid Build Coastguard Worker                     m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
1199*35238bceSAndroid Build Coastguard Worker                     return STOP;
1200*35238bceSAndroid Build Coastguard Worker                 }
1201*35238bceSAndroid Build Coastguard Worker             }
1202*35238bceSAndroid Build Coastguard Worker     }
1203*35238bceSAndroid Build Coastguard Worker 
1204*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message
1205*35238bceSAndroid Build Coastguard Worker         << "Drawing a viewport-sized quad with glStencilFunc(GL_EQUAL, 1, 1) and glStencilOp(GL_KEEP, GL_KEEP, "
1206*35238bceSAndroid Build Coastguard Worker            "GL_KEEP) - should result in same image as the first"
1207*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1208*35238bceSAndroid Build Coastguard Worker 
1209*35238bceSAndroid Build Coastguard Worker     renderQuad(Vec2(-1.0f, -1.0f), Vec2(1.0f, -1.0f), Vec2(-1.0f, 1.0f), Vec2(1.0f, 1.0f), Vec4(1.0f));
1210*35238bceSAndroid Build Coastguard Worker 
1211*35238bceSAndroid Build Coastguard Worker     readImage(renderedImgSecond);
1212*35238bceSAndroid Build Coastguard Worker     log << TestLog::Image("RenderedImgSecond", "Second image rendered", renderedImgSecond,
1213*35238bceSAndroid Build Coastguard Worker                           QP_IMAGE_COMPRESSION_MODE_PNG);
1214*35238bceSAndroid Build Coastguard Worker 
1215*35238bceSAndroid Build Coastguard Worker     bool passed = tcu::pixelThresholdCompare(log, "ImageCompare", "Image comparison", renderedImgFirst,
1216*35238bceSAndroid Build Coastguard Worker                                              renderedImgSecond, tcu::RGBA(0), tcu::COMPARE_LOG_ON_ERROR);
1217*35238bceSAndroid Build Coastguard Worker 
1218*35238bceSAndroid Build Coastguard Worker     if (passed)
1219*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;
1220*35238bceSAndroid Build Coastguard Worker 
1221*35238bceSAndroid Build Coastguard Worker     m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1222*35238bceSAndroid Build Coastguard Worker                                              passed ? "Passed" : "Failed");
1223*35238bceSAndroid Build Coastguard Worker 
1224*35238bceSAndroid Build Coastguard Worker     return STOP;
1225*35238bceSAndroid Build Coastguard Worker }
1226*35238bceSAndroid Build Coastguard Worker 
1227*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1228*35238bceSAndroid Build Coastguard Worker  * \brief Tests coverage mask generation proportionality property.
1229*35238bceSAndroid Build Coastguard Worker  *
1230*35238bceSAndroid Build Coastguard Worker  * Tests that the number of coverage bits in a coverage mask created by
1231*35238bceSAndroid Build Coastguard Worker  * GL_SAMPLE_ALPHA_TO_COVERAGE or GL_SAMPLE_COVERAGE is, on average,
1232*35238bceSAndroid Build Coastguard Worker  * proportional to the alpha or coverage value, respectively. Draws
1233*35238bceSAndroid Build Coastguard Worker  * multiple frames, each time increasing the alpha or coverage value used,
1234*35238bceSAndroid Build Coastguard Worker  * and checks that the average color is changing appropriately.
1235*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
1236*35238bceSAndroid Build Coastguard Worker class MaskProportionalityCase : public MultisampleCase
1237*35238bceSAndroid Build Coastguard Worker {
1238*35238bceSAndroid Build Coastguard Worker public:
1239*35238bceSAndroid Build Coastguard Worker     enum CaseType
1240*35238bceSAndroid Build Coastguard Worker     {
1241*35238bceSAndroid Build Coastguard Worker         CASETYPE_ALPHA_TO_COVERAGE = 0,
1242*35238bceSAndroid Build Coastguard Worker         CASETYPE_SAMPLE_COVERAGE,
1243*35238bceSAndroid Build Coastguard Worker         CASETYPE_SAMPLE_COVERAGE_INVERTED,
1244*35238bceSAndroid Build Coastguard Worker 
1245*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
1246*35238bceSAndroid Build Coastguard Worker     };
1247*35238bceSAndroid Build Coastguard Worker 
1248*35238bceSAndroid Build Coastguard Worker     MaskProportionalityCase(Context &context, const char *name, const char *description, CaseType type,
1249*35238bceSAndroid Build Coastguard Worker                             int numFboSamples = 0);
~MaskProportionalityCase(void)1250*35238bceSAndroid Build Coastguard Worker     ~MaskProportionalityCase(void)
1251*35238bceSAndroid Build Coastguard Worker     {
1252*35238bceSAndroid Build Coastguard Worker     }
1253*35238bceSAndroid Build Coastguard Worker 
1254*35238bceSAndroid Build Coastguard Worker     void init(void);
1255*35238bceSAndroid Build Coastguard Worker 
1256*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1257*35238bceSAndroid Build Coastguard Worker 
1258*35238bceSAndroid Build Coastguard Worker private:
1259*35238bceSAndroid Build Coastguard Worker     const CaseType m_type;
1260*35238bceSAndroid Build Coastguard Worker 
1261*35238bceSAndroid Build Coastguard Worker     int m_numIterations;
1262*35238bceSAndroid Build Coastguard Worker     int m_currentIteration;
1263*35238bceSAndroid Build Coastguard Worker 
1264*35238bceSAndroid Build Coastguard Worker     int32_t m_previousIterationColorSum;
1265*35238bceSAndroid Build Coastguard Worker };
1266*35238bceSAndroid Build Coastguard Worker 
MaskProportionalityCase(Context & context,const char * name,const char * description,CaseType type,int numFboSamples)1267*35238bceSAndroid Build Coastguard Worker MaskProportionalityCase::MaskProportionalityCase(Context &context, const char *name, const char *description,
1268*35238bceSAndroid Build Coastguard Worker                                                  CaseType type, int numFboSamples)
1269*35238bceSAndroid Build Coastguard Worker     : MultisampleCase(context, name, description, 32,
1270*35238bceSAndroid Build Coastguard Worker                       numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
1271*35238bceSAndroid Build Coastguard Worker     , m_type(type)
1272*35238bceSAndroid Build Coastguard Worker     , m_numIterations(0)
1273*35238bceSAndroid Build Coastguard Worker     , m_currentIteration(0)
1274*35238bceSAndroid Build Coastguard Worker     , m_previousIterationColorSum(-1)
1275*35238bceSAndroid Build Coastguard Worker {
1276*35238bceSAndroid Build Coastguard Worker }
1277*35238bceSAndroid Build Coastguard Worker 
init(void)1278*35238bceSAndroid Build Coastguard Worker void MaskProportionalityCase::init(void)
1279*35238bceSAndroid Build Coastguard Worker {
1280*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1281*35238bceSAndroid Build Coastguard Worker 
1282*35238bceSAndroid Build Coastguard Worker     MultisampleCase::init();
1283*35238bceSAndroid Build Coastguard Worker 
1284*35238bceSAndroid Build Coastguard Worker     if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
1285*35238bceSAndroid Build Coastguard Worker     {
1286*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE));
1287*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
1288*35238bceSAndroid Build Coastguard Worker     }
1289*35238bceSAndroid Build Coastguard Worker     else
1290*35238bceSAndroid Build Coastguard Worker     {
1291*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_type == CASETYPE_SAMPLE_COVERAGE || m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED);
1292*35238bceSAndroid Build Coastguard Worker 
1293*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
1294*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
1295*35238bceSAndroid Build Coastguard Worker     }
1296*35238bceSAndroid Build Coastguard Worker 
1297*35238bceSAndroid Build Coastguard Worker     m_numIterations = de::max(2, getIterationCount(m_testCtx, m_numSamples * 5));
1298*35238bceSAndroid Build Coastguard Worker 
1299*35238bceSAndroid Build Coastguard Worker     randomizeViewport(); // \note Using the same viewport for every iteration since coverage mask may depend on window-relative pixel coordinate.
1300*35238bceSAndroid Build Coastguard Worker }
1301*35238bceSAndroid Build Coastguard Worker 
iterate(void)1302*35238bceSAndroid Build Coastguard Worker MaskProportionalityCase::IterateResult MaskProportionalityCase::iterate(void)
1303*35238bceSAndroid Build Coastguard Worker {
1304*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1305*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImg(m_viewportSize, m_viewportSize);
1306*35238bceSAndroid Build Coastguard Worker     int32_t numPixels = (int32_t)renderedImg.getWidth() * (int32_t)renderedImg.getHeight();
1307*35238bceSAndroid Build Coastguard Worker 
1308*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
1309*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
1310*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
1311*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
1312*35238bceSAndroid Build Coastguard Worker 
1313*35238bceSAndroid Build Coastguard Worker     if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
1314*35238bceSAndroid Build Coastguard Worker     {
1315*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE));
1316*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Using color mask TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
1317*35238bceSAndroid Build Coastguard Worker     }
1318*35238bceSAndroid Build Coastguard Worker 
1319*35238bceSAndroid Build Coastguard Worker     // Draw quad.
1320*35238bceSAndroid Build Coastguard Worker 
1321*35238bceSAndroid Build Coastguard Worker     {
1322*35238bceSAndroid Build Coastguard Worker         const Vec2 pt0(-1.0f, -1.0f);
1323*35238bceSAndroid Build Coastguard Worker         const Vec2 pt1(1.0f, -1.0f);
1324*35238bceSAndroid Build Coastguard Worker         const Vec2 pt2(-1.0f, 1.0f);
1325*35238bceSAndroid Build Coastguard Worker         const Vec2 pt3(1.0f, 1.0f);
1326*35238bceSAndroid Build Coastguard Worker         Vec4 quadColor(1.0f, 0.0f, 0.0f, 1.0f);
1327*35238bceSAndroid Build Coastguard Worker         float alphaOrCoverageValue = (float)m_currentIteration / (float)(m_numIterations - 1);
1328*35238bceSAndroid Build Coastguard Worker 
1329*35238bceSAndroid Build Coastguard Worker         if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
1330*35238bceSAndroid Build Coastguard Worker         {
1331*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message
1332*35238bceSAndroid Build Coastguard Worker                 << "Drawing a red quad using alpha value " + de::floatToString(alphaOrCoverageValue, 2)
1333*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
1334*35238bceSAndroid Build Coastguard Worker             quadColor.w() = alphaOrCoverageValue;
1335*35238bceSAndroid Build Coastguard Worker         }
1336*35238bceSAndroid Build Coastguard Worker         else
1337*35238bceSAndroid Build Coastguard Worker         {
1338*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(m_type == CASETYPE_SAMPLE_COVERAGE || m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED);
1339*35238bceSAndroid Build Coastguard Worker 
1340*35238bceSAndroid Build Coastguard Worker             bool isInverted     = m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED;
1341*35238bceSAndroid Build Coastguard Worker             float coverageValue = isInverted ? 1.0f - alphaOrCoverageValue : alphaOrCoverageValue;
1342*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message
1343*35238bceSAndroid Build Coastguard Worker                 << "Drawing a red quad using sample coverage value " + de::floatToString(coverageValue, 2)
1344*35238bceSAndroid Build Coastguard Worker                 << (isInverted ? " (inverted)" : "") << TestLog::EndMessage;
1345*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glSampleCoverage(coverageValue, isInverted ? GL_TRUE : GL_FALSE));
1346*35238bceSAndroid Build Coastguard Worker         }
1347*35238bceSAndroid Build Coastguard Worker 
1348*35238bceSAndroid Build Coastguard Worker         renderQuad(pt0, pt1, pt2, pt3, quadColor);
1349*35238bceSAndroid Build Coastguard Worker     }
1350*35238bceSAndroid Build Coastguard Worker 
1351*35238bceSAndroid Build Coastguard Worker     // Read ang log image.
1352*35238bceSAndroid Build Coastguard Worker 
1353*35238bceSAndroid Build Coastguard Worker     readImage(renderedImg);
1354*35238bceSAndroid Build Coastguard Worker 
1355*35238bceSAndroid Build Coastguard Worker     log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
1356*35238bceSAndroid Build Coastguard Worker 
1357*35238bceSAndroid Build Coastguard Worker     // Compute average red component in rendered image.
1358*35238bceSAndroid Build Coastguard Worker 
1359*35238bceSAndroid Build Coastguard Worker     int32_t sumRed = 0;
1360*35238bceSAndroid Build Coastguard Worker 
1361*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < renderedImg.getHeight(); y++)
1362*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < renderedImg.getWidth(); x++)
1363*35238bceSAndroid Build Coastguard Worker             sumRed += renderedImg.getPixel(x, y).getRed();
1364*35238bceSAndroid Build Coastguard Worker 
1365*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message
1366*35238bceSAndroid Build Coastguard Worker         << "Average red color component: " << de::floatToString((float)sumRed / 255.0f / (float)numPixels, 2)
1367*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1368*35238bceSAndroid Build Coastguard Worker 
1369*35238bceSAndroid Build Coastguard Worker     // Check if average color has decreased from previous frame's color.
1370*35238bceSAndroid Build Coastguard Worker 
1371*35238bceSAndroid Build Coastguard Worker     if (sumRed < m_previousIterationColorSum)
1372*35238bceSAndroid Build Coastguard Worker     {
1373*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Failure: Current average red color component is lower than previous"
1374*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
1375*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
1376*35238bceSAndroid Build Coastguard Worker         return STOP;
1377*35238bceSAndroid Build Coastguard Worker     }
1378*35238bceSAndroid Build Coastguard Worker 
1379*35238bceSAndroid Build Coastguard Worker     // Check if coverage mask is not all-zeros if alpha or coverage value is 0 (or 1, if inverted).
1380*35238bceSAndroid Build Coastguard Worker 
1381*35238bceSAndroid Build Coastguard Worker     if (m_currentIteration == 0 && sumRed != 0)
1382*35238bceSAndroid Build Coastguard Worker     {
1383*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Failure: Image should be completely black" << TestLog::EndMessage;
1384*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
1385*35238bceSAndroid Build Coastguard Worker         return STOP;
1386*35238bceSAndroid Build Coastguard Worker     }
1387*35238bceSAndroid Build Coastguard Worker 
1388*35238bceSAndroid Build Coastguard Worker     if (m_currentIteration == m_numIterations - 1 && sumRed != 0xff * numPixels)
1389*35238bceSAndroid Build Coastguard Worker     {
1390*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Failure: Image should be completely red" << TestLog::EndMessage;
1391*35238bceSAndroid Build Coastguard Worker 
1392*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
1393*35238bceSAndroid Build Coastguard Worker         return STOP;
1394*35238bceSAndroid Build Coastguard Worker     }
1395*35238bceSAndroid Build Coastguard Worker 
1396*35238bceSAndroid Build Coastguard Worker     m_previousIterationColorSum = sumRed;
1397*35238bceSAndroid Build Coastguard Worker 
1398*35238bceSAndroid Build Coastguard Worker     m_currentIteration++;
1399*35238bceSAndroid Build Coastguard Worker 
1400*35238bceSAndroid Build Coastguard Worker     if (m_currentIteration >= m_numIterations)
1401*35238bceSAndroid Build Coastguard Worker     {
1402*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message
1403*35238bceSAndroid Build Coastguard Worker             << "Success: Number of coverage mask bits set appears to be, on average, proportional to "
1404*35238bceSAndroid Build Coastguard Worker             << (m_type == CASETYPE_ALPHA_TO_COVERAGE ? "alpha" :
1405*35238bceSAndroid Build Coastguard Worker                 m_type == CASETYPE_SAMPLE_COVERAGE   ? "sample coverage value" :
1406*35238bceSAndroid Build Coastguard Worker                                                        "inverted sample coverage value")
1407*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
1408*35238bceSAndroid Build Coastguard Worker 
1409*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
1410*35238bceSAndroid Build Coastguard Worker         return STOP;
1411*35238bceSAndroid Build Coastguard Worker     }
1412*35238bceSAndroid Build Coastguard Worker     else
1413*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
1414*35238bceSAndroid Build Coastguard Worker }
1415*35238bceSAndroid Build Coastguard Worker 
1416*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1417*35238bceSAndroid Build Coastguard Worker  * \brief Tests coverage mask generation constancy property.
1418*35238bceSAndroid Build Coastguard Worker  *
1419*35238bceSAndroid Build Coastguard Worker  * Tests that the coverage mask created by GL_SAMPLE_ALPHA_TO_COVERAGE or
1420*35238bceSAndroid Build Coastguard Worker  * GL_SAMPLE_COVERAGE is constant at given pixel coordinates, with a given
1421*35238bceSAndroid Build Coastguard Worker  * alpha component or coverage value, respectively. Draws two quads, with
1422*35238bceSAndroid Build Coastguard Worker  * the second one fully overlapping the first one such that at any given
1423*35238bceSAndroid Build Coastguard Worker  * pixel, both quads have the same alpha or coverage value. This way, if
1424*35238bceSAndroid Build Coastguard Worker  * the constancy property is fulfilled, only the second quad should be
1425*35238bceSAndroid Build Coastguard Worker  * visible.
1426*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
1427*35238bceSAndroid Build Coastguard Worker class MaskConstancyCase : public MultisampleCase
1428*35238bceSAndroid Build Coastguard Worker {
1429*35238bceSAndroid Build Coastguard Worker public:
1430*35238bceSAndroid Build Coastguard Worker     enum CaseType
1431*35238bceSAndroid Build Coastguard Worker     {
1432*35238bceSAndroid Build Coastguard Worker         CASETYPE_ALPHA_TO_COVERAGE = 0,    //!< Use only alpha-to-coverage.
1433*35238bceSAndroid Build Coastguard Worker         CASETYPE_SAMPLE_COVERAGE,          //!< Use only sample coverage.
1434*35238bceSAndroid Build Coastguard Worker         CASETYPE_SAMPLE_COVERAGE_INVERTED, //!< Use only inverted sample coverage.
1435*35238bceSAndroid Build Coastguard Worker         CASETYPE_BOTH,                     //!< Use both alpha-to-coverage and sample coverage.
1436*35238bceSAndroid Build Coastguard Worker         CASETYPE_BOTH_INVERTED,            //!< Use both alpha-to-coverage and inverted sample coverage.
1437*35238bceSAndroid Build Coastguard Worker 
1438*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
1439*35238bceSAndroid Build Coastguard Worker     };
1440*35238bceSAndroid Build Coastguard Worker 
1441*35238bceSAndroid Build Coastguard Worker     MaskConstancyCase(Context &context, const char *name, const char *description, CaseType type,
1442*35238bceSAndroid Build Coastguard Worker                       int numFboSamples = 0);
~MaskConstancyCase(void)1443*35238bceSAndroid Build Coastguard Worker     ~MaskConstancyCase(void)
1444*35238bceSAndroid Build Coastguard Worker     {
1445*35238bceSAndroid Build Coastguard Worker     }
1446*35238bceSAndroid Build Coastguard Worker 
1447*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1448*35238bceSAndroid Build Coastguard Worker 
1449*35238bceSAndroid Build Coastguard Worker private:
1450*35238bceSAndroid Build Coastguard Worker     const bool m_isAlphaToCoverageCase;
1451*35238bceSAndroid Build Coastguard Worker     const bool m_isSampleCoverageCase;
1452*35238bceSAndroid Build Coastguard Worker     const bool m_isInvertedSampleCoverageCase;
1453*35238bceSAndroid Build Coastguard Worker };
1454*35238bceSAndroid Build Coastguard Worker 
MaskConstancyCase(Context & context,const char * name,const char * description,CaseType type,int numFboSamples)1455*35238bceSAndroid Build Coastguard Worker MaskConstancyCase::MaskConstancyCase(Context &context, const char *name, const char *description, CaseType type,
1456*35238bceSAndroid Build Coastguard Worker                                      int numFboSamples)
1457*35238bceSAndroid Build Coastguard Worker     : MultisampleCase(context, name, description, 256,
1458*35238bceSAndroid Build Coastguard Worker                       numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
1459*35238bceSAndroid Build Coastguard Worker     , m_isAlphaToCoverageCase(type == CASETYPE_ALPHA_TO_COVERAGE || type == CASETYPE_BOTH ||
1460*35238bceSAndroid Build Coastguard Worker                               type == CASETYPE_BOTH_INVERTED)
1461*35238bceSAndroid Build Coastguard Worker     , m_isSampleCoverageCase(type == CASETYPE_SAMPLE_COVERAGE || type == CASETYPE_SAMPLE_COVERAGE_INVERTED ||
1462*35238bceSAndroid Build Coastguard Worker                              type == CASETYPE_BOTH || type == CASETYPE_BOTH_INVERTED)
1463*35238bceSAndroid Build Coastguard Worker     , m_isInvertedSampleCoverageCase(type == CASETYPE_SAMPLE_COVERAGE_INVERTED || type == CASETYPE_BOTH_INVERTED)
1464*35238bceSAndroid Build Coastguard Worker {
1465*35238bceSAndroid Build Coastguard Worker }
1466*35238bceSAndroid Build Coastguard Worker 
iterate(void)1467*35238bceSAndroid Build Coastguard Worker MaskConstancyCase::IterateResult MaskConstancyCase::iterate(void)
1468*35238bceSAndroid Build Coastguard Worker {
1469*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1470*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImg(m_viewportSize, m_viewportSize);
1471*35238bceSAndroid Build Coastguard Worker 
1472*35238bceSAndroid Build Coastguard Worker     randomizeViewport();
1473*35238bceSAndroid Build Coastguard Worker 
1474*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
1475*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
1476*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
1477*35238bceSAndroid Build Coastguard Worker 
1478*35238bceSAndroid Build Coastguard Worker     if (m_isAlphaToCoverageCase)
1479*35238bceSAndroid Build Coastguard Worker     {
1480*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE));
1481*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE));
1482*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
1483*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Color mask is TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
1484*35238bceSAndroid Build Coastguard Worker     }
1485*35238bceSAndroid Build Coastguard Worker 
1486*35238bceSAndroid Build Coastguard Worker     if (m_isSampleCoverageCase)
1487*35238bceSAndroid Build Coastguard Worker     {
1488*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
1489*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
1490*35238bceSAndroid Build Coastguard Worker     }
1491*35238bceSAndroid Build Coastguard Worker 
1492*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Drawing several green quads, each fully overlapped by a red quad with the same "
1493*35238bceSAndroid Build Coastguard Worker         << (m_isAlphaToCoverageCase ? "alpha" : "")
1494*35238bceSAndroid Build Coastguard Worker         << (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
1495*35238bceSAndroid Build Coastguard Worker         << (m_isInvertedSampleCoverageCase ? "inverted " : "") << (m_isSampleCoverageCase ? "sample coverage" : "")
1496*35238bceSAndroid Build Coastguard Worker         << " values" << TestLog::EndMessage;
1497*35238bceSAndroid Build Coastguard Worker 
1498*35238bceSAndroid Build Coastguard Worker     const int numQuadRowsCols = m_numSamples * 4;
1499*35238bceSAndroid Build Coastguard Worker 
1500*35238bceSAndroid Build Coastguard Worker     for (int row = 0; row < numQuadRowsCols; row++)
1501*35238bceSAndroid Build Coastguard Worker     {
1502*35238bceSAndroid Build Coastguard Worker         for (int col = 0; col < numQuadRowsCols; col++)
1503*35238bceSAndroid Build Coastguard Worker         {
1504*35238bceSAndroid Build Coastguard Worker             float x0 = (float)(col + 0) / (float)numQuadRowsCols * 2.0f - 1.0f;
1505*35238bceSAndroid Build Coastguard Worker             float x1 = (float)(col + 1) / (float)numQuadRowsCols * 2.0f - 1.0f;
1506*35238bceSAndroid Build Coastguard Worker             float y0 = (float)(row + 0) / (float)numQuadRowsCols * 2.0f - 1.0f;
1507*35238bceSAndroid Build Coastguard Worker             float y1 = (float)(row + 1) / (float)numQuadRowsCols * 2.0f - 1.0f;
1508*35238bceSAndroid Build Coastguard Worker             const Vec4 baseGreen(0.0f, 1.0f, 0.0f, 0.0f);
1509*35238bceSAndroid Build Coastguard Worker             const Vec4 baseRed(1.0f, 0.0f, 0.0f, 0.0f);
1510*35238bceSAndroid Build Coastguard Worker             Vec4 alpha0(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)col / (float)(numQuadRowsCols - 1) : 1.0f);
1511*35238bceSAndroid Build Coastguard Worker             Vec4 alpha1(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)row / (float)(numQuadRowsCols - 1) : 1.0f);
1512*35238bceSAndroid Build Coastguard Worker 
1513*35238bceSAndroid Build Coastguard Worker             if (m_isSampleCoverageCase)
1514*35238bceSAndroid Build Coastguard Worker             {
1515*35238bceSAndroid Build Coastguard Worker                 float value = (float)(row * numQuadRowsCols + col) / (float)(numQuadRowsCols * numQuadRowsCols - 1);
1516*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glSampleCoverage(m_isInvertedSampleCoverageCase ? 1.0f - value : value,
1517*35238bceSAndroid Build Coastguard Worker                                                 m_isInvertedSampleCoverageCase ? GL_TRUE : GL_FALSE));
1518*35238bceSAndroid Build Coastguard Worker             }
1519*35238bceSAndroid Build Coastguard Worker 
1520*35238bceSAndroid Build Coastguard Worker             renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseGreen + alpha0, baseGreen + alpha1,
1521*35238bceSAndroid Build Coastguard Worker                        baseGreen + alpha0, baseGreen + alpha1);
1522*35238bceSAndroid Build Coastguard Worker             renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseRed + alpha0, baseRed + alpha1,
1523*35238bceSAndroid Build Coastguard Worker                        baseRed + alpha0, baseRed + alpha1);
1524*35238bceSAndroid Build Coastguard Worker         }
1525*35238bceSAndroid Build Coastguard Worker     }
1526*35238bceSAndroid Build Coastguard Worker 
1527*35238bceSAndroid Build Coastguard Worker     readImage(renderedImg);
1528*35238bceSAndroid Build Coastguard Worker 
1529*35238bceSAndroid Build Coastguard Worker     log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);
1530*35238bceSAndroid Build Coastguard Worker 
1531*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < renderedImg.getHeight(); y++)
1532*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < renderedImg.getWidth(); x++)
1533*35238bceSAndroid Build Coastguard Worker         {
1534*35238bceSAndroid Build Coastguard Worker             if (renderedImg.getPixel(x, y).getGreen() > 0)
1535*35238bceSAndroid Build Coastguard Worker             {
1536*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
1537*35238bceSAndroid Build Coastguard Worker                     << "Failure: Non-zero green color component detected - should have been completely overwritten by "
1538*35238bceSAndroid Build Coastguard Worker                        "red quad"
1539*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
1540*35238bceSAndroid Build Coastguard Worker                 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
1541*35238bceSAndroid Build Coastguard Worker                 return STOP;
1542*35238bceSAndroid Build Coastguard Worker             }
1543*35238bceSAndroid Build Coastguard Worker         }
1544*35238bceSAndroid Build Coastguard Worker 
1545*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Success: Coverage mask appears to be constant at a given pixel coordinate with a given "
1546*35238bceSAndroid Build Coastguard Worker         << (m_isAlphaToCoverageCase ? "alpha" : "")
1547*35238bceSAndroid Build Coastguard Worker         << (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
1548*35238bceSAndroid Build Coastguard Worker         << (m_isSampleCoverageCase ? "coverage value" : "") << TestLog::EndMessage;
1549*35238bceSAndroid Build Coastguard Worker 
1550*35238bceSAndroid Build Coastguard Worker     m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
1551*35238bceSAndroid Build Coastguard Worker 
1552*35238bceSAndroid Build Coastguard Worker     return STOP;
1553*35238bceSAndroid Build Coastguard Worker }
1554*35238bceSAndroid Build Coastguard Worker 
1555*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1556*35238bceSAndroid Build Coastguard Worker  * \brief Tests coverage mask inversion validity.
1557*35238bceSAndroid Build Coastguard Worker  *
1558*35238bceSAndroid Build Coastguard Worker  * Tests that the coverage masks obtained by glSampleCoverage(..., GL_TRUE)
1559*35238bceSAndroid Build Coastguard Worker  * and glSampleCoverage(..., GL_FALSE) are indeed each others' inverses.
1560*35238bceSAndroid Build Coastguard Worker  * This is done by drawing a pattern, with varying coverage values,
1561*35238bceSAndroid Build Coastguard Worker  * overlapped by a pattern that has inverted masks and is otherwise
1562*35238bceSAndroid Build Coastguard Worker  * identical. The resulting image is compared to one obtained by drawing
1563*35238bceSAndroid Build Coastguard Worker  * the same pattern but with all-ones coverage masks.
1564*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
1565*35238bceSAndroid Build Coastguard Worker class CoverageMaskInvertCase : public MultisampleCase
1566*35238bceSAndroid Build Coastguard Worker {
1567*35238bceSAndroid Build Coastguard Worker public:
1568*35238bceSAndroid Build Coastguard Worker     CoverageMaskInvertCase(Context &context, const char *name, const char *description, int numFboSamples = 0);
~CoverageMaskInvertCase(void)1569*35238bceSAndroid Build Coastguard Worker     ~CoverageMaskInvertCase(void)
1570*35238bceSAndroid Build Coastguard Worker     {
1571*35238bceSAndroid Build Coastguard Worker     }
1572*35238bceSAndroid Build Coastguard Worker 
1573*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1574*35238bceSAndroid Build Coastguard Worker 
1575*35238bceSAndroid Build Coastguard Worker private:
1576*35238bceSAndroid Build Coastguard Worker     void drawPattern(bool invertSampleCoverage) const;
1577*35238bceSAndroid Build Coastguard Worker };
1578*35238bceSAndroid Build Coastguard Worker 
CoverageMaskInvertCase(Context & context,const char * name,const char * description,int numFboSamples)1579*35238bceSAndroid Build Coastguard Worker CoverageMaskInvertCase::CoverageMaskInvertCase(Context &context, const char *name, const char *description,
1580*35238bceSAndroid Build Coastguard Worker                                                int numFboSamples)
1581*35238bceSAndroid Build Coastguard Worker     : MultisampleCase(context, name, description, 256,
1582*35238bceSAndroid Build Coastguard Worker                       numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
1583*35238bceSAndroid Build Coastguard Worker {
1584*35238bceSAndroid Build Coastguard Worker }
1585*35238bceSAndroid Build Coastguard Worker 
drawPattern(bool invertSampleCoverage) const1586*35238bceSAndroid Build Coastguard Worker void CoverageMaskInvertCase::drawPattern(bool invertSampleCoverage) const
1587*35238bceSAndroid Build Coastguard Worker {
1588*35238bceSAndroid Build Coastguard Worker     const int numTriangles = 25;
1589*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numTriangles; i++)
1590*35238bceSAndroid Build Coastguard Worker     {
1591*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(
1592*35238bceSAndroid Build Coastguard Worker             glSampleCoverage((float)i / (float)(numTriangles - 1), invertSampleCoverage ? GL_TRUE : GL_FALSE));
1593*35238bceSAndroid Build Coastguard Worker 
1594*35238bceSAndroid Build Coastguard Worker         float angle0 = 2.0f * DE_PI * (float)i / (float)numTriangles;
1595*35238bceSAndroid Build Coastguard Worker         float angle1 = 2.0f * DE_PI * ((float)i + 0.5f) / (float)numTriangles;
1596*35238bceSAndroid Build Coastguard Worker 
1597*35238bceSAndroid Build Coastguard Worker         renderTriangle(Vec2(0.0f, 0.0f), Vec2(deFloatCos(angle0) * 0.95f, deFloatSin(angle0) * 0.95f),
1598*35238bceSAndroid Build Coastguard Worker                        Vec2(deFloatCos(angle1) * 0.95f, deFloatSin(angle1) * 0.95f),
1599*35238bceSAndroid Build Coastguard Worker                        Vec4(0.4f + (float)i / (float)numTriangles * 0.6f, 0.5f + (float)i / (float)numTriangles * 0.3f,
1600*35238bceSAndroid Build Coastguard Worker                             0.6f - (float)i / (float)numTriangles * 0.5f,
1601*35238bceSAndroid Build Coastguard Worker                             0.7f - (float)i / (float)numTriangles * 0.7f));
1602*35238bceSAndroid Build Coastguard Worker     }
1603*35238bceSAndroid Build Coastguard Worker }
1604*35238bceSAndroid Build Coastguard Worker 
iterate(void)1605*35238bceSAndroid Build Coastguard Worker CoverageMaskInvertCase::IterateResult CoverageMaskInvertCase::iterate(void)
1606*35238bceSAndroid Build Coastguard Worker {
1607*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1608*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImgNoSampleCoverage(m_viewportSize, m_viewportSize);
1609*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImgSampleCoverage(m_viewportSize, m_viewportSize);
1610*35238bceSAndroid Build Coastguard Worker 
1611*35238bceSAndroid Build Coastguard Worker     randomizeViewport();
1612*35238bceSAndroid Build Coastguard Worker 
1613*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnable(GL_BLEND));
1614*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glBlendEquation(GL_FUNC_ADD));
1615*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glBlendFunc(GL_ONE, GL_ONE));
1616*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples"
1617*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1618*35238bceSAndroid Build Coastguard Worker 
1619*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
1620*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
1621*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
1622*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE disabled" << TestLog::EndMessage;
1623*35238bceSAndroid Build Coastguard Worker     drawPattern(false);
1624*35238bceSAndroid Build Coastguard Worker     readImage(renderedImgNoSampleCoverage);
1625*35238bceSAndroid Build Coastguard Worker 
1626*35238bceSAndroid Build Coastguard Worker     log << TestLog::Image("RenderedImageNoSampleCoverage", "Rendered image with GL_SAMPLE_COVERAGE disabled",
1627*35238bceSAndroid Build Coastguard Worker                           renderedImgNoSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);
1628*35238bceSAndroid Build Coastguard Worker 
1629*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
1630*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
1631*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
1632*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE enabled, using non-inverted masks"
1633*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1634*35238bceSAndroid Build Coastguard Worker     drawPattern(false);
1635*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message
1636*35238bceSAndroid Build Coastguard Worker         << "Drawing the pattern with GL_SAMPLE_COVERAGE enabled, using same sample coverage values but inverted masks"
1637*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1638*35238bceSAndroid Build Coastguard Worker     drawPattern(true);
1639*35238bceSAndroid Build Coastguard Worker     readImage(renderedImgSampleCoverage);
1640*35238bceSAndroid Build Coastguard Worker 
1641*35238bceSAndroid Build Coastguard Worker     log << TestLog::Image("RenderedImageSampleCoverage", "Rendered image with GL_SAMPLE_COVERAGE enabled",
1642*35238bceSAndroid Build Coastguard Worker                           renderedImgSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);
1643*35238bceSAndroid Build Coastguard Worker 
1644*35238bceSAndroid Build Coastguard Worker     bool passed = tcu::pixelThresholdCompare(
1645*35238bceSAndroid Build Coastguard Worker         log, "CoverageVsNoCoverage", "Comparison of same pattern with GL_SAMPLE_COVERAGE disabled and enabled",
1646*35238bceSAndroid Build Coastguard Worker         renderedImgNoSampleCoverage, renderedImgSampleCoverage, tcu::RGBA(0), tcu::COMPARE_LOG_ON_ERROR);
1647*35238bceSAndroid Build Coastguard Worker 
1648*35238bceSAndroid Build Coastguard Worker     if (passed)
1649*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;
1650*35238bceSAndroid Build Coastguard Worker 
1651*35238bceSAndroid Build Coastguard Worker     m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1652*35238bceSAndroid Build Coastguard Worker                                              passed ? "Passed" : "Failed");
1653*35238bceSAndroid Build Coastguard Worker 
1654*35238bceSAndroid Build Coastguard Worker     return STOP;
1655*35238bceSAndroid Build Coastguard Worker }
1656*35238bceSAndroid Build Coastguard Worker 
MultisampleTests(Context & context)1657*35238bceSAndroid Build Coastguard Worker MultisampleTests::MultisampleTests(Context &context) : TestCaseGroup(context, "multisample", "Multisampling tests")
1658*35238bceSAndroid Build Coastguard Worker {
1659*35238bceSAndroid Build Coastguard Worker }
1660*35238bceSAndroid Build Coastguard Worker 
~MultisampleTests(void)1661*35238bceSAndroid Build Coastguard Worker MultisampleTests::~MultisampleTests(void)
1662*35238bceSAndroid Build Coastguard Worker {
1663*35238bceSAndroid Build Coastguard Worker }
1664*35238bceSAndroid Build Coastguard Worker 
init(void)1665*35238bceSAndroid Build Coastguard Worker void MultisampleTests::init(void)
1666*35238bceSAndroid Build Coastguard Worker {
1667*35238bceSAndroid Build Coastguard Worker     enum CaseType
1668*35238bceSAndroid Build Coastguard Worker     {
1669*35238bceSAndroid Build Coastguard Worker         CASETYPE_DEFAULT_FRAMEBUFFER = 0,
1670*35238bceSAndroid Build Coastguard Worker         CASETYPE_FBO_4_SAMPLES,
1671*35238bceSAndroid Build Coastguard Worker         CASETYPE_FBO_8_SAMPLES,
1672*35238bceSAndroid Build Coastguard Worker         CASETYPE_FBO_MAX_SAMPLES,
1673*35238bceSAndroid Build Coastguard Worker 
1674*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
1675*35238bceSAndroid Build Coastguard Worker     };
1676*35238bceSAndroid Build Coastguard Worker 
1677*35238bceSAndroid Build Coastguard Worker     for (int caseTypeI = 0; caseTypeI < (int)CASETYPE_LAST; caseTypeI++)
1678*35238bceSAndroid Build Coastguard Worker     {
1679*35238bceSAndroid Build Coastguard Worker         CaseType caseType = (CaseType)caseTypeI;
1680*35238bceSAndroid Build Coastguard Worker         int numFboSamples = caseType == CASETYPE_DEFAULT_FRAMEBUFFER ? -1 :
1681*35238bceSAndroid Build Coastguard Worker                             caseType == CASETYPE_FBO_4_SAMPLES       ? 4 :
1682*35238bceSAndroid Build Coastguard Worker                             caseType == CASETYPE_FBO_8_SAMPLES       ? 8 :
1683*35238bceSAndroid Build Coastguard Worker                             caseType == CASETYPE_FBO_MAX_SAMPLES     ? 0 :
1684*35238bceSAndroid Build Coastguard Worker                                                                        -2;
1685*35238bceSAndroid Build Coastguard Worker 
1686*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *group = new TestCaseGroup(
1687*35238bceSAndroid Build Coastguard Worker             m_context,
1688*35238bceSAndroid Build Coastguard Worker             caseType == CASETYPE_DEFAULT_FRAMEBUFFER ? "default_framebuffer" :
1689*35238bceSAndroid Build Coastguard Worker             caseType == CASETYPE_FBO_4_SAMPLES       ? "fbo_4_samples" :
1690*35238bceSAndroid Build Coastguard Worker             caseType == CASETYPE_FBO_8_SAMPLES       ? "fbo_8_samples" :
1691*35238bceSAndroid Build Coastguard Worker             caseType == CASETYPE_FBO_MAX_SAMPLES     ? "fbo_max_samples" :
1692*35238bceSAndroid Build Coastguard Worker                                                        DE_NULL,
1693*35238bceSAndroid Build Coastguard Worker             caseType == CASETYPE_DEFAULT_FRAMEBUFFER ? "Render into default framebuffer" :
1694*35238bceSAndroid Build Coastguard Worker             caseType == CASETYPE_FBO_4_SAMPLES       ? "Render into a framebuffer object with 4 samples" :
1695*35238bceSAndroid Build Coastguard Worker             caseType == CASETYPE_FBO_8_SAMPLES       ? "Render into a framebuffer object with 8 samples" :
1696*35238bceSAndroid Build Coastguard Worker             caseType == CASETYPE_FBO_MAX_SAMPLES ?
1697*35238bceSAndroid Build Coastguard Worker                                                  "Render into a framebuffer object with the maximum number of samples" :
1698*35238bceSAndroid Build Coastguard Worker                                                  DE_NULL);
1699*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(group->getName() != DE_NULL);
1700*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numFboSamples >= -1);
1701*35238bceSAndroid Build Coastguard Worker         addChild(group);
1702*35238bceSAndroid Build Coastguard Worker 
1703*35238bceSAndroid Build Coastguard Worker         group->addChild(new PolygonNumSamplesCase(m_context, "num_samples_polygon",
1704*35238bceSAndroid Build Coastguard Worker                                                   "Test sanity of the sample count, with polygons", numFboSamples));
1705*35238bceSAndroid Build Coastguard Worker         group->addChild(new LineNumSamplesCase(m_context, "num_samples_line",
1706*35238bceSAndroid Build Coastguard Worker                                                "Test sanity of the sample count, with lines", numFboSamples));
1707*35238bceSAndroid Build Coastguard Worker         group->addChild(new CommonEdgeCase(m_context, "common_edge_small_quads",
1708*35238bceSAndroid Build Coastguard Worker                                            "Test polygons' common edges with small quads",
1709*35238bceSAndroid Build Coastguard Worker                                            CommonEdgeCase::CASETYPE_SMALL_QUADS, numFboSamples));
1710*35238bceSAndroid Build Coastguard Worker         group->addChild(new CommonEdgeCase(m_context, "common_edge_big_quad",
1711*35238bceSAndroid Build Coastguard Worker                                            "Test polygons' common edges with bigger-than-viewport quads",
1712*35238bceSAndroid Build Coastguard Worker                                            CommonEdgeCase::CASETYPE_BIGGER_THAN_VIEWPORT_QUAD, numFboSamples));
1713*35238bceSAndroid Build Coastguard Worker         group->addChild(new CommonEdgeCase(m_context, "common_edge_viewport_quad",
1714*35238bceSAndroid Build Coastguard Worker                                            "Test polygons' common edges with exactly viewport-sized quads",
1715*35238bceSAndroid Build Coastguard Worker                                            CommonEdgeCase::CASETYPE_FIT_VIEWPORT_QUAD, numFboSamples));
1716*35238bceSAndroid Build Coastguard Worker         group->addChild(
1717*35238bceSAndroid Build Coastguard Worker             new SampleDepthCase(m_context, "depth", "Test that depth values are per-sample", numFboSamples));
1718*35238bceSAndroid Build Coastguard Worker         group->addChild(
1719*35238bceSAndroid Build Coastguard Worker             new SampleStencilCase(m_context, "stencil", "Test that stencil values are per-sample", numFboSamples));
1720*35238bceSAndroid Build Coastguard Worker         group->addChild(new CoverageMaskInvertCase(
1721*35238bceSAndroid Build Coastguard Worker             m_context, "sample_coverage_invert",
1722*35238bceSAndroid Build Coastguard Worker             "Test that non-inverted and inverted sample coverage masks are each other's negations", numFboSamples));
1723*35238bceSAndroid Build Coastguard Worker 
1724*35238bceSAndroid Build Coastguard Worker         group->addChild(new MaskProportionalityCase(m_context, "proportionality_alpha_to_coverage",
1725*35238bceSAndroid Build Coastguard Worker                                                     "Test the proportionality property of GL_SAMPLE_ALPHA_TO_COVERAGE",
1726*35238bceSAndroid Build Coastguard Worker                                                     MaskProportionalityCase::CASETYPE_ALPHA_TO_COVERAGE,
1727*35238bceSAndroid Build Coastguard Worker                                                     numFboSamples));
1728*35238bceSAndroid Build Coastguard Worker         group->addChild(new MaskProportionalityCase(m_context, "proportionality_sample_coverage",
1729*35238bceSAndroid Build Coastguard Worker                                                     "Test the proportionality property of GL_SAMPLE_COVERAGE",
1730*35238bceSAndroid Build Coastguard Worker                                                     MaskProportionalityCase::CASETYPE_SAMPLE_COVERAGE, numFboSamples));
1731*35238bceSAndroid Build Coastguard Worker         group->addChild(
1732*35238bceSAndroid Build Coastguard Worker             new MaskProportionalityCase(m_context, "proportionality_sample_coverage_inverted",
1733*35238bceSAndroid Build Coastguard Worker                                         "Test the proportionality property of inverted-mask GL_SAMPLE_COVERAGE",
1734*35238bceSAndroid Build Coastguard Worker                                         MaskProportionalityCase::CASETYPE_SAMPLE_COVERAGE_INVERTED, numFboSamples));
1735*35238bceSAndroid Build Coastguard Worker 
1736*35238bceSAndroid Build Coastguard Worker         group->addChild(new MaskConstancyCase(m_context, "constancy_alpha_to_coverage",
1737*35238bceSAndroid Build Coastguard Worker                                               "Test that coverage mask is constant at given coordinates with a given "
1738*35238bceSAndroid Build Coastguard Worker                                               "alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE",
1739*35238bceSAndroid Build Coastguard Worker                                               MaskConstancyCase::CASETYPE_ALPHA_TO_COVERAGE, numFboSamples));
1740*35238bceSAndroid Build Coastguard Worker         group->addChild(new MaskConstancyCase(m_context, "constancy_sample_coverage",
1741*35238bceSAndroid Build Coastguard Worker                                               "Test that coverage mask is constant at given coordinates with a given "
1742*35238bceSAndroid Build Coastguard Worker                                               "alpha or coverage value, using GL_SAMPLE_COVERAGE",
1743*35238bceSAndroid Build Coastguard Worker                                               MaskConstancyCase::CASETYPE_SAMPLE_COVERAGE, numFboSamples));
1744*35238bceSAndroid Build Coastguard Worker         group->addChild(new MaskConstancyCase(m_context, "constancy_sample_coverage_inverted",
1745*35238bceSAndroid Build Coastguard Worker                                               "Test that coverage mask is constant at given coordinates with a given "
1746*35238bceSAndroid Build Coastguard Worker                                               "alpha or coverage value, using inverted-mask GL_SAMPLE_COVERAGE",
1747*35238bceSAndroid Build Coastguard Worker                                               MaskConstancyCase::CASETYPE_SAMPLE_COVERAGE_INVERTED, numFboSamples));
1748*35238bceSAndroid Build Coastguard Worker         group->addChild(
1749*35238bceSAndroid Build Coastguard Worker             new MaskConstancyCase(m_context, "constancy_both",
1750*35238bceSAndroid Build Coastguard Worker                                   "Test that coverage mask is constant at given coordinates with a given alpha or "
1751*35238bceSAndroid Build Coastguard Worker                                   "coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and GL_SAMPLE_COVERAGE",
1752*35238bceSAndroid Build Coastguard Worker                                   MaskConstancyCase::CASETYPE_BOTH, numFboSamples));
1753*35238bceSAndroid Build Coastguard Worker         group->addChild(new MaskConstancyCase(
1754*35238bceSAndroid Build Coastguard Worker             m_context, "constancy_both_inverted",
1755*35238bceSAndroid Build Coastguard Worker             "Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using "
1756*35238bceSAndroid Build Coastguard Worker             "GL_SAMPLE_ALPHA_TO_COVERAGE and inverted-mask GL_SAMPLE_COVERAGE",
1757*35238bceSAndroid Build Coastguard Worker             MaskConstancyCase::CASETYPE_BOTH_INVERTED, numFboSamples));
1758*35238bceSAndroid Build Coastguard Worker     }
1759*35238bceSAndroid Build Coastguard Worker }
1760*35238bceSAndroid Build Coastguard Worker 
1761*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1762*35238bceSAndroid Build Coastguard Worker } // namespace gles3
1763*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1764