xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fSampleVariableTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.1 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 Sample variable tests
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es31fSampleVariableTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "es31fMultisampleShaderRenderCase.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuFormatUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker namespace deqp
41*35238bceSAndroid Build Coastguard Worker {
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker using std::map;
44*35238bceSAndroid Build Coastguard Worker using std::string;
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker namespace gles31
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker namespace Functional
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker namespace
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker 
53*35238bceSAndroid Build Coastguard Worker class Verifier
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker public:
56*35238bceSAndroid Build Coastguard Worker     virtual bool verify(const tcu::RGBA &testColor, const tcu::IVec2 &position) const = 0;
57*35238bceSAndroid Build Coastguard Worker     virtual void logInfo(tcu::TestLog &log) const                                     = 0;
58*35238bceSAndroid Build Coastguard Worker };
59*35238bceSAndroid Build Coastguard Worker 
60*35238bceSAndroid Build Coastguard Worker class ColorVerifier : public Verifier
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker public:
ColorVerifier(const tcu::Vec3 & _color,int _threshold=8)63*35238bceSAndroid Build Coastguard Worker     ColorVerifier(const tcu::Vec3 &_color, int _threshold = 8)
64*35238bceSAndroid Build Coastguard Worker         : m_color(tcu::Vec4(_color.x(), _color.y(), _color.z(), 1.0f))
65*35238bceSAndroid Build Coastguard Worker         , m_threshold(tcu::IVec3(_threshold))
66*35238bceSAndroid Build Coastguard Worker     {
67*35238bceSAndroid Build Coastguard Worker     }
68*35238bceSAndroid Build Coastguard Worker 
ColorVerifier(const tcu::Vec3 & _color,tcu::IVec3 _threshold)69*35238bceSAndroid Build Coastguard Worker     ColorVerifier(const tcu::Vec3 &_color, tcu::IVec3 _threshold)
70*35238bceSAndroid Build Coastguard Worker         : m_color(tcu::Vec4(_color.x(), _color.y(), _color.z(), 1.0f))
71*35238bceSAndroid Build Coastguard Worker         , m_threshold(_threshold)
72*35238bceSAndroid Build Coastguard Worker     {
73*35238bceSAndroid Build Coastguard Worker     }
74*35238bceSAndroid Build Coastguard Worker 
verify(const tcu::RGBA & testColor,const tcu::IVec2 & position) const75*35238bceSAndroid Build Coastguard Worker     bool verify(const tcu::RGBA &testColor, const tcu::IVec2 &position) const
76*35238bceSAndroid Build Coastguard Worker     {
77*35238bceSAndroid Build Coastguard Worker         DE_UNREF(position);
78*35238bceSAndroid Build Coastguard Worker         return !tcu::boolAny(
79*35238bceSAndroid Build Coastguard Worker             tcu::greaterThan(tcu::abs(m_color.toIVec().swizzle(0, 1, 2) - testColor.toIVec().swizzle(0, 1, 2)),
80*35238bceSAndroid Build Coastguard Worker                              tcu::IVec3(m_threshold)));
81*35238bceSAndroid Build Coastguard Worker     }
82*35238bceSAndroid Build Coastguard Worker 
logInfo(tcu::TestLog & log) const83*35238bceSAndroid Build Coastguard Worker     void logInfo(tcu::TestLog &log) const
84*35238bceSAndroid Build Coastguard Worker     {
85*35238bceSAndroid Build Coastguard Worker         // full threshold? print * for clarity
86*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "Expecting unicolored image, color = RGB("
87*35238bceSAndroid Build Coastguard Worker             << ((m_threshold[0] >= 255) ? ("*") : (de::toString(m_color.getRed()))) << ", "
88*35238bceSAndroid Build Coastguard Worker             << ((m_threshold[1] >= 255) ? ("*") : (de::toString(m_color.getGreen()))) << ", "
89*35238bceSAndroid Build Coastguard Worker             << ((m_threshold[2] >= 255) ? ("*") : (de::toString(m_color.getBlue()))) << ")" << tcu::TestLog::EndMessage;
90*35238bceSAndroid Build Coastguard Worker     }
91*35238bceSAndroid Build Coastguard Worker 
92*35238bceSAndroid Build Coastguard Worker     const tcu::RGBA m_color;
93*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_threshold;
94*35238bceSAndroid Build Coastguard Worker };
95*35238bceSAndroid Build Coastguard Worker 
96*35238bceSAndroid Build Coastguard Worker class FullBlueSomeGreenVerifier : public Verifier
97*35238bceSAndroid Build Coastguard Worker {
98*35238bceSAndroid Build Coastguard Worker public:
FullBlueSomeGreenVerifier(void)99*35238bceSAndroid Build Coastguard Worker     FullBlueSomeGreenVerifier(void)
100*35238bceSAndroid Build Coastguard Worker     {
101*35238bceSAndroid Build Coastguard Worker     }
102*35238bceSAndroid Build Coastguard Worker 
verify(const tcu::RGBA & testColor,const tcu::IVec2 & position) const103*35238bceSAndroid Build Coastguard Worker     bool verify(const tcu::RGBA &testColor, const tcu::IVec2 &position) const
104*35238bceSAndroid Build Coastguard Worker     {
105*35238bceSAndroid Build Coastguard Worker         DE_UNREF(position);
106*35238bceSAndroid Build Coastguard Worker 
107*35238bceSAndroid Build Coastguard Worker         // Values from 0.0 and 1.0 are accurate
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker         if (testColor.getRed() != 0)
110*35238bceSAndroid Build Coastguard Worker             return false;
111*35238bceSAndroid Build Coastguard Worker         if (testColor.getGreen() == 0)
112*35238bceSAndroid Build Coastguard Worker             return false;
113*35238bceSAndroid Build Coastguard Worker         if (testColor.getBlue() != 255)
114*35238bceSAndroid Build Coastguard Worker             return false;
115*35238bceSAndroid Build Coastguard Worker         return true;
116*35238bceSAndroid Build Coastguard Worker     }
117*35238bceSAndroid Build Coastguard Worker 
logInfo(tcu::TestLog & log) const118*35238bceSAndroid Build Coastguard Worker     void logInfo(tcu::TestLog &log) const
119*35238bceSAndroid Build Coastguard Worker     {
120*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "Expecting color c = (0.0, x, 1.0), x > 0.0" << tcu::TestLog::EndMessage;
121*35238bceSAndroid Build Coastguard Worker     }
122*35238bceSAndroid Build Coastguard Worker };
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker class NoRedVerifier : public Verifier
125*35238bceSAndroid Build Coastguard Worker {
126*35238bceSAndroid Build Coastguard Worker public:
NoRedVerifier(void)127*35238bceSAndroid Build Coastguard Worker     NoRedVerifier(void)
128*35238bceSAndroid Build Coastguard Worker     {
129*35238bceSAndroid Build Coastguard Worker     }
130*35238bceSAndroid Build Coastguard Worker 
verify(const tcu::RGBA & testColor,const tcu::IVec2 & position) const131*35238bceSAndroid Build Coastguard Worker     bool verify(const tcu::RGBA &testColor, const tcu::IVec2 &position) const
132*35238bceSAndroid Build Coastguard Worker     {
133*35238bceSAndroid Build Coastguard Worker         DE_UNREF(position);
134*35238bceSAndroid Build Coastguard Worker         return testColor.getRed() == 0;
135*35238bceSAndroid Build Coastguard Worker     }
136*35238bceSAndroid Build Coastguard Worker 
logInfo(tcu::TestLog & log) const137*35238bceSAndroid Build Coastguard Worker     void logInfo(tcu::TestLog &log) const
138*35238bceSAndroid Build Coastguard Worker     {
139*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "Expecting zero-valued red channel." << tcu::TestLog::EndMessage;
140*35238bceSAndroid Build Coastguard Worker     }
141*35238bceSAndroid Build Coastguard Worker };
142*35238bceSAndroid Build Coastguard Worker 
143*35238bceSAndroid Build Coastguard Worker class SampleAverageVerifier : public Verifier
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker public:
146*35238bceSAndroid Build Coastguard Worker     SampleAverageVerifier(int _numSamples);
147*35238bceSAndroid Build Coastguard Worker 
148*35238bceSAndroid Build Coastguard Worker     bool verify(const tcu::RGBA &testColor, const tcu::IVec2 &position) const;
149*35238bceSAndroid Build Coastguard Worker     void logInfo(tcu::TestLog &log) const;
150*35238bceSAndroid Build Coastguard Worker 
151*35238bceSAndroid Build Coastguard Worker     const int m_numSamples;
152*35238bceSAndroid Build Coastguard Worker     const bool m_isStatisticallySignificant;
153*35238bceSAndroid Build Coastguard Worker     float m_distanceThreshold;
154*35238bceSAndroid Build Coastguard Worker };
155*35238bceSAndroid Build Coastguard Worker 
SampleAverageVerifier(int _numSamples)156*35238bceSAndroid Build Coastguard Worker SampleAverageVerifier::SampleAverageVerifier(int _numSamples)
157*35238bceSAndroid Build Coastguard Worker     : m_numSamples(_numSamples)
158*35238bceSAndroid Build Coastguard Worker     , m_isStatisticallySignificant(_numSamples >= 4)
159*35238bceSAndroid Build Coastguard Worker     , m_distanceThreshold(0.0f)
160*35238bceSAndroid Build Coastguard Worker {
161*35238bceSAndroid Build Coastguard Worker     // approximate Bates distribution as normal
162*35238bceSAndroid Build Coastguard Worker     const float variance          = (1.0f / (12.0f * (float)m_numSamples));
163*35238bceSAndroid Build Coastguard Worker     const float standardDeviation = deFloatSqrt(variance);
164*35238bceSAndroid Build Coastguard Worker 
165*35238bceSAndroid Build Coastguard Worker     // 95% of means of sample positions are within 2 standard deviations if
166*35238bceSAndroid Build Coastguard Worker     // they were randomly assigned. Sample patterns are expected to be more
167*35238bceSAndroid Build Coastguard Worker     // uniform than a random pattern.
168*35238bceSAndroid Build Coastguard Worker     m_distanceThreshold = 2 * standardDeviation;
169*35238bceSAndroid Build Coastguard Worker }
170*35238bceSAndroid Build Coastguard Worker 
verify(const tcu::RGBA & testColor,const tcu::IVec2 & position) const171*35238bceSAndroid Build Coastguard Worker bool SampleAverageVerifier::verify(const tcu::RGBA &testColor, const tcu::IVec2 &position) const
172*35238bceSAndroid Build Coastguard Worker {
173*35238bceSAndroid Build Coastguard Worker     DE_UNREF(position);
174*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_isStatisticallySignificant);
175*35238bceSAndroid Build Coastguard Worker 
176*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 avgPosition((float)testColor.getGreen() / 255.0f, (float)testColor.getBlue() / 255.0f);
177*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 distanceFromCenter = tcu::abs(avgPosition - tcu::Vec2(0.5f, 0.5f));
178*35238bceSAndroid Build Coastguard Worker 
179*35238bceSAndroid Build Coastguard Worker     return distanceFromCenter.x() < m_distanceThreshold && distanceFromCenter.y() < m_distanceThreshold;
180*35238bceSAndroid Build Coastguard Worker }
181*35238bceSAndroid Build Coastguard Worker 
logInfo(tcu::TestLog & log) const182*35238bceSAndroid Build Coastguard Worker void SampleAverageVerifier::logInfo(tcu::TestLog &log) const
183*35238bceSAndroid Build Coastguard Worker {
184*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::Message
185*35238bceSAndroid Build Coastguard Worker         << "Expecting average sample position to be near the pixel center. Maximum per-axis distance "
186*35238bceSAndroid Build Coastguard Worker         << m_distanceThreshold << tcu::TestLog::EndMessage;
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker 
189*35238bceSAndroid Build Coastguard Worker class PartialDiscardVerifier : public Verifier
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker public:
PartialDiscardVerifier(void)192*35238bceSAndroid Build Coastguard Worker     PartialDiscardVerifier(void)
193*35238bceSAndroid Build Coastguard Worker     {
194*35238bceSAndroid Build Coastguard Worker     }
195*35238bceSAndroid Build Coastguard Worker 
verify(const tcu::RGBA & testColor,const tcu::IVec2 & position) const196*35238bceSAndroid Build Coastguard Worker     bool verify(const tcu::RGBA &testColor, const tcu::IVec2 &position) const
197*35238bceSAndroid Build Coastguard Worker     {
198*35238bceSAndroid Build Coastguard Worker         DE_UNREF(position);
199*35238bceSAndroid Build Coastguard Worker 
200*35238bceSAndroid Build Coastguard Worker         return (testColor.getGreen() != 0) && (testColor.getGreen() != 255);
201*35238bceSAndroid Build Coastguard Worker     }
202*35238bceSAndroid Build Coastguard Worker 
logInfo(tcu::TestLog & log) const203*35238bceSAndroid Build Coastguard Worker     void logInfo(tcu::TestLog &log) const
204*35238bceSAndroid Build Coastguard Worker     {
205*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "Expecting color non-zero and non-saturated green channel"
206*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::EndMessage;
207*35238bceSAndroid Build Coastguard Worker     }
208*35238bceSAndroid Build Coastguard Worker };
209*35238bceSAndroid Build Coastguard Worker 
verifyImageWithVerifier(const tcu::Surface & resultImage,tcu::TestLog & log,const Verifier & verifier,bool logOnSuccess=true)210*35238bceSAndroid Build Coastguard Worker static bool verifyImageWithVerifier(const tcu::Surface &resultImage, tcu::TestLog &log, const Verifier &verifier,
211*35238bceSAndroid Build Coastguard Worker                                     bool logOnSuccess = true)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(resultImage.getWidth(), resultImage.getHeight());
214*35238bceSAndroid Build Coastguard Worker     bool error = false;
215*35238bceSAndroid Build Coastguard Worker 
216*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
217*35238bceSAndroid Build Coastguard Worker 
218*35238bceSAndroid Build Coastguard Worker     if (logOnSuccess)
219*35238bceSAndroid Build Coastguard Worker     {
220*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "Verifying image." << tcu::TestLog::EndMessage;
221*35238bceSAndroid Build Coastguard Worker         verifier.logInfo(log);
222*35238bceSAndroid Build Coastguard Worker     }
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < resultImage.getHeight(); ++y)
225*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < resultImage.getWidth(); ++x)
226*35238bceSAndroid Build Coastguard Worker         {
227*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA color = resultImage.getPixel(x, y);
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker             // verify color value is valid for this pixel position
230*35238bceSAndroid Build Coastguard Worker             if (!verifier.verify(color, tcu::IVec2(x, y)))
231*35238bceSAndroid Build Coastguard Worker             {
232*35238bceSAndroid Build Coastguard Worker                 error = true;
233*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(x, y, tcu::RGBA::red());
234*35238bceSAndroid Build Coastguard Worker             }
235*35238bceSAndroid Build Coastguard Worker         }
236*35238bceSAndroid Build Coastguard Worker 
237*35238bceSAndroid Build Coastguard Worker     if (error)
238*35238bceSAndroid Build Coastguard Worker     {
239*35238bceSAndroid Build Coastguard Worker         // describe the verification logic if we haven't already
240*35238bceSAndroid Build Coastguard Worker         if (!logOnSuccess)
241*35238bceSAndroid Build Coastguard Worker             verifier.logInfo(log);
242*35238bceSAndroid Build Coastguard Worker 
243*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
244*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::ImageSet("Verification", "Image Verification")
245*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("Result", "Result image", resultImage.getAccess())
246*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("ErrorMask", "Error Mask", errorMask.getAccess()) << tcu::TestLog::EndImageSet;
247*35238bceSAndroid Build Coastguard Worker     }
248*35238bceSAndroid Build Coastguard Worker     else if (logOnSuccess)
249*35238bceSAndroid Build Coastguard Worker     {
250*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "Image verification passed." << tcu::TestLog::EndMessage
251*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::ImageSet("Verification", "Image Verification")
252*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("Result", "Result image", resultImage.getAccess()) << tcu::TestLog::EndImageSet;
253*35238bceSAndroid Build Coastguard Worker     }
254*35238bceSAndroid Build Coastguard Worker 
255*35238bceSAndroid Build Coastguard Worker     return !error;
256*35238bceSAndroid Build Coastguard Worker }
257*35238bceSAndroid Build Coastguard Worker 
258*35238bceSAndroid Build Coastguard Worker class MultisampleRenderCase : public MultisampleShaderRenderUtil::MultisampleRenderCase
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker public:
261*35238bceSAndroid Build Coastguard Worker     MultisampleRenderCase(Context &context, const char *name, const char *desc, int numSamples, RenderTarget target,
262*35238bceSAndroid Build Coastguard Worker                           int renderSize, int flags = 0);
263*35238bceSAndroid Build Coastguard Worker     virtual ~MultisampleRenderCase(void);
264*35238bceSAndroid Build Coastguard Worker 
265*35238bceSAndroid Build Coastguard Worker     virtual void init(void);
266*35238bceSAndroid Build Coastguard Worker };
267*35238bceSAndroid Build Coastguard Worker 
MultisampleRenderCase(Context & context,const char * name,const char * desc,int numSamples,RenderTarget target,int renderSize,int flags)268*35238bceSAndroid Build Coastguard Worker MultisampleRenderCase::MultisampleRenderCase(Context &context, const char *name, const char *desc, int numSamples,
269*35238bceSAndroid Build Coastguard Worker                                              RenderTarget target, int renderSize, int flags)
270*35238bceSAndroid Build Coastguard Worker     : MultisampleShaderRenderUtil::MultisampleRenderCase(context, name, desc, numSamples, target, renderSize, flags)
271*35238bceSAndroid Build Coastguard Worker {
272*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(target < TARGET_LAST);
273*35238bceSAndroid Build Coastguard Worker }
274*35238bceSAndroid Build Coastguard Worker 
~MultisampleRenderCase(void)275*35238bceSAndroid Build Coastguard Worker MultisampleRenderCase::~MultisampleRenderCase(void)
276*35238bceSAndroid Build Coastguard Worker {
277*35238bceSAndroid Build Coastguard Worker     MultisampleRenderCase::deinit();
278*35238bceSAndroid Build Coastguard Worker }
279*35238bceSAndroid Build Coastguard Worker 
init(void)280*35238bceSAndroid Build Coastguard Worker void MultisampleRenderCase::init(void)
281*35238bceSAndroid Build Coastguard Worker {
282*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
283*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
284*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
285*35238bceSAndroid Build Coastguard Worker     if (!supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_variables"))
286*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError,
287*35238bceSAndroid Build Coastguard Worker                   "Test requires GL_OES_sample_variables extension or a context version 3.2 or higher.");
288*35238bceSAndroid Build Coastguard Worker 
289*35238bceSAndroid Build Coastguard Worker     MultisampleShaderRenderUtil::MultisampleRenderCase::init();
290*35238bceSAndroid Build Coastguard Worker }
291*35238bceSAndroid Build Coastguard Worker 
292*35238bceSAndroid Build Coastguard Worker class NumSamplesCase : public MultisampleRenderCase
293*35238bceSAndroid Build Coastguard Worker {
294*35238bceSAndroid Build Coastguard Worker public:
295*35238bceSAndroid Build Coastguard Worker     NumSamplesCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target);
296*35238bceSAndroid Build Coastguard Worker     ~NumSamplesCase(void);
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
299*35238bceSAndroid Build Coastguard Worker     bool verifyImage(const tcu::Surface &resultImage);
300*35238bceSAndroid Build Coastguard Worker 
301*35238bceSAndroid Build Coastguard Worker private:
302*35238bceSAndroid Build Coastguard Worker     enum
303*35238bceSAndroid Build Coastguard Worker     {
304*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
305*35238bceSAndroid Build Coastguard Worker     };
306*35238bceSAndroid Build Coastguard Worker };
307*35238bceSAndroid Build Coastguard Worker 
NumSamplesCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target)308*35238bceSAndroid Build Coastguard Worker NumSamplesCase::NumSamplesCase(Context &context, const char *name, const char *desc, int sampleCount,
309*35238bceSAndroid Build Coastguard Worker                                RenderTarget target)
310*35238bceSAndroid Build Coastguard Worker     : MultisampleRenderCase(context, name, desc, sampleCount, target, RENDER_SIZE)
311*35238bceSAndroid Build Coastguard Worker {
312*35238bceSAndroid Build Coastguard Worker }
313*35238bceSAndroid Build Coastguard Worker 
~NumSamplesCase(void)314*35238bceSAndroid Build Coastguard Worker NumSamplesCase::~NumSamplesCase(void)
315*35238bceSAndroid Build Coastguard Worker {
316*35238bceSAndroid Build Coastguard Worker }
317*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const318*35238bceSAndroid Build Coastguard Worker std::string NumSamplesCase::genFragmentSource(int numTargetSamples) const
319*35238bceSAndroid Build Coastguard Worker {
320*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
321*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
322*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
323*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
324*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
325*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = (supportsES32orGL45) ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
326*35238bceSAndroid Build Coastguard Worker                                                        getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
327*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = (supportsES32orGL45) ? "" : "#extension GL_OES_sample_variables : require";
328*35238bceSAndroid Build Coastguard Worker 
329*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
330*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXTENSION}\n"
331*35238bceSAndroid Build Coastguard Worker            "layout(location = 0) out mediump vec4 fragColor;\n"
332*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
333*35238bceSAndroid Build Coastguard Worker            "{\n"
334*35238bceSAndroid Build Coastguard Worker            "    fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
335*35238bceSAndroid Build Coastguard Worker            "    if (gl_NumSamples == "
336*35238bceSAndroid Build Coastguard Worker         << numTargetSamples
337*35238bceSAndroid Build Coastguard Worker         << ")\n"
338*35238bceSAndroid Build Coastguard Worker            "        fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
339*35238bceSAndroid Build Coastguard Worker            "}\n";
340*35238bceSAndroid Build Coastguard Worker 
341*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
342*35238bceSAndroid Build Coastguard Worker }
343*35238bceSAndroid Build Coastguard Worker 
verifyImage(const tcu::Surface & resultImage)344*35238bceSAndroid Build Coastguard Worker bool NumSamplesCase::verifyImage(const tcu::Surface &resultImage)
345*35238bceSAndroid Build Coastguard Worker {
346*35238bceSAndroid Build Coastguard Worker     return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), NoRedVerifier());
347*35238bceSAndroid Build Coastguard Worker }
348*35238bceSAndroid Build Coastguard Worker 
349*35238bceSAndroid Build Coastguard Worker class MaxSamplesCase : public MultisampleRenderCase
350*35238bceSAndroid Build Coastguard Worker {
351*35238bceSAndroid Build Coastguard Worker public:
352*35238bceSAndroid Build Coastguard Worker     MaxSamplesCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target);
353*35238bceSAndroid Build Coastguard Worker     ~MaxSamplesCase(void);
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker private:
356*35238bceSAndroid Build Coastguard Worker     void preDraw(void);
357*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
358*35238bceSAndroid Build Coastguard Worker     bool verifyImage(const tcu::Surface &resultImage);
359*35238bceSAndroid Build Coastguard Worker 
360*35238bceSAndroid Build Coastguard Worker     enum
361*35238bceSAndroid Build Coastguard Worker     {
362*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
363*35238bceSAndroid Build Coastguard Worker     };
364*35238bceSAndroid Build Coastguard Worker };
365*35238bceSAndroid Build Coastguard Worker 
MaxSamplesCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target)366*35238bceSAndroid Build Coastguard Worker MaxSamplesCase::MaxSamplesCase(Context &context, const char *name, const char *desc, int sampleCount,
367*35238bceSAndroid Build Coastguard Worker                                RenderTarget target)
368*35238bceSAndroid Build Coastguard Worker     : MultisampleRenderCase(context, name, desc, sampleCount, target, RENDER_SIZE)
369*35238bceSAndroid Build Coastguard Worker {
370*35238bceSAndroid Build Coastguard Worker }
371*35238bceSAndroid Build Coastguard Worker 
~MaxSamplesCase(void)372*35238bceSAndroid Build Coastguard Worker MaxSamplesCase::~MaxSamplesCase(void)
373*35238bceSAndroid Build Coastguard Worker {
374*35238bceSAndroid Build Coastguard Worker }
375*35238bceSAndroid Build Coastguard Worker 
preDraw(void)376*35238bceSAndroid Build Coastguard Worker void MaxSamplesCase::preDraw(void)
377*35238bceSAndroid Build Coastguard Worker {
378*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
379*35238bceSAndroid Build Coastguard Worker     int32_t maxSamples       = -1;
380*35238bceSAndroid Build Coastguard Worker 
381*35238bceSAndroid Build Coastguard Worker     // query samples
382*35238bceSAndroid Build Coastguard Worker     {
383*35238bceSAndroid Build Coastguard Worker         gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples);
384*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_MAX_SAMPLES");
385*35238bceSAndroid Build Coastguard Worker 
386*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_SAMPLES = " << maxSamples << tcu::TestLog::EndMessage;
387*35238bceSAndroid Build Coastguard Worker     }
388*35238bceSAndroid Build Coastguard Worker 
389*35238bceSAndroid Build Coastguard Worker     // set samples
390*35238bceSAndroid Build Coastguard Worker     {
391*35238bceSAndroid Build Coastguard Worker         const int maxSampleLoc = gl.getUniformLocation(m_program->getProgram(), "u_maxSamples");
392*35238bceSAndroid Build Coastguard Worker         if (maxSampleLoc == -1)
393*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Location of u_maxSamples was -1");
394*35238bceSAndroid Build Coastguard Worker 
395*35238bceSAndroid Build Coastguard Worker         gl.uniform1i(maxSampleLoc, maxSamples);
396*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set u_maxSamples uniform");
397*35238bceSAndroid Build Coastguard Worker 
398*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Set u_maxSamples = " << maxSamples << tcu::TestLog::EndMessage;
399*35238bceSAndroid Build Coastguard Worker     }
400*35238bceSAndroid Build Coastguard Worker }
401*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const402*35238bceSAndroid Build Coastguard Worker std::string MaxSamplesCase::genFragmentSource(int numTargetSamples) const
403*35238bceSAndroid Build Coastguard Worker {
404*35238bceSAndroid Build Coastguard Worker     DE_UNREF(numTargetSamples);
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
407*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
408*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
409*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
410*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
411*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = (supportsES32orGL45) ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
412*35238bceSAndroid Build Coastguard Worker                                                        getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
413*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = (supportsES32orGL45) ? "" : "#extension GL_OES_sample_variables : require";
414*35238bceSAndroid Build Coastguard Worker 
415*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
416*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXTENSION}\n"
417*35238bceSAndroid Build Coastguard Worker            "layout(location = 0) out mediump vec4 fragColor;\n"
418*35238bceSAndroid Build Coastguard Worker            "uniform mediump int u_maxSamples;\n"
419*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
420*35238bceSAndroid Build Coastguard Worker            "{\n"
421*35238bceSAndroid Build Coastguard Worker            "    fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
422*35238bceSAndroid Build Coastguard Worker            "    if (gl_MaxSamples == u_maxSamples)\n"
423*35238bceSAndroid Build Coastguard Worker            "        fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
424*35238bceSAndroid Build Coastguard Worker            "}\n";
425*35238bceSAndroid Build Coastguard Worker 
426*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
427*35238bceSAndroid Build Coastguard Worker }
428*35238bceSAndroid Build Coastguard Worker 
verifyImage(const tcu::Surface & resultImage)429*35238bceSAndroid Build Coastguard Worker bool MaxSamplesCase::verifyImage(const tcu::Surface &resultImage)
430*35238bceSAndroid Build Coastguard Worker {
431*35238bceSAndroid Build Coastguard Worker     return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), NoRedVerifier());
432*35238bceSAndroid Build Coastguard Worker }
433*35238bceSAndroid Build Coastguard Worker 
434*35238bceSAndroid Build Coastguard Worker class SampleIDCase : public MultisampleRenderCase
435*35238bceSAndroid Build Coastguard Worker {
436*35238bceSAndroid Build Coastguard Worker public:
437*35238bceSAndroid Build Coastguard Worker     SampleIDCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target);
438*35238bceSAndroid Build Coastguard Worker     ~SampleIDCase(void);
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker     void init(void);
441*35238bceSAndroid Build Coastguard Worker 
442*35238bceSAndroid Build Coastguard Worker private:
443*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
444*35238bceSAndroid Build Coastguard Worker     bool verifyImage(const tcu::Surface &resultImage);
445*35238bceSAndroid Build Coastguard Worker     bool verifySampleBuffers(const std::vector<tcu::Surface> &resultBuffers);
446*35238bceSAndroid Build Coastguard Worker 
447*35238bceSAndroid Build Coastguard Worker     enum
448*35238bceSAndroid Build Coastguard Worker     {
449*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
450*35238bceSAndroid Build Coastguard Worker     };
451*35238bceSAndroid Build Coastguard Worker     enum VerificationMode
452*35238bceSAndroid Build Coastguard Worker     {
453*35238bceSAndroid Build Coastguard Worker         VERIFY_USING_SAMPLES,
454*35238bceSAndroid Build Coastguard Worker         VERIFY_USING_SELECTION,
455*35238bceSAndroid Build Coastguard Worker     };
456*35238bceSAndroid Build Coastguard Worker 
457*35238bceSAndroid Build Coastguard Worker     const VerificationMode m_vericationMode;
458*35238bceSAndroid Build Coastguard Worker };
459*35238bceSAndroid Build Coastguard Worker 
SampleIDCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target)460*35238bceSAndroid Build Coastguard Worker SampleIDCase::SampleIDCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target)
461*35238bceSAndroid Build Coastguard Worker     : MultisampleRenderCase(context, name, desc, sampleCount, target, RENDER_SIZE,
462*35238bceSAndroid Build Coastguard Worker                             MultisampleShaderRenderUtil::MultisampleRenderCase::FLAG_VERIFY_MSAA_TEXTURE_SAMPLE_BUFFERS)
463*35238bceSAndroid Build Coastguard Worker     , m_vericationMode((target == TARGET_TEXTURE) ? (VERIFY_USING_SAMPLES) : (VERIFY_USING_SELECTION))
464*35238bceSAndroid Build Coastguard Worker {
465*35238bceSAndroid Build Coastguard Worker }
466*35238bceSAndroid Build Coastguard Worker 
~SampleIDCase(void)467*35238bceSAndroid Build Coastguard Worker SampleIDCase::~SampleIDCase(void)
468*35238bceSAndroid Build Coastguard Worker {
469*35238bceSAndroid Build Coastguard Worker }
470*35238bceSAndroid Build Coastguard Worker 
init(void)471*35238bceSAndroid Build Coastguard Worker void SampleIDCase::init(void)
472*35238bceSAndroid Build Coastguard Worker {
473*35238bceSAndroid Build Coastguard Worker     // log the test method and expectations
474*35238bceSAndroid Build Coastguard Worker     if (m_vericationMode == VERIFY_USING_SAMPLES)
475*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog()
476*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Message
477*35238bceSAndroid Build Coastguard Worker             << "Writing gl_SampleID to the green channel of the texture and verifying texture values, expecting:\n"
478*35238bceSAndroid Build Coastguard Worker             << "    1) 0 with non-multisample targets.\n"
479*35238bceSAndroid Build Coastguard Worker             << "    2) value N at sample index N of a multisample texture\n"
480*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::EndMessage;
481*35238bceSAndroid Build Coastguard Worker     else if (m_vericationMode == VERIFY_USING_SELECTION)
482*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog()
483*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Message
484*35238bceSAndroid Build Coastguard Worker             << "Selecting a single sample id for each pixel and writing color only if gl_SampleID == selected.\n"
485*35238bceSAndroid Build Coastguard Worker             << "Expecting all output pixels to be partially (multisample) or fully (singlesample) colored.\n"
486*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::EndMessage;
487*35238bceSAndroid Build Coastguard Worker     else
488*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
489*35238bceSAndroid Build Coastguard Worker 
490*35238bceSAndroid Build Coastguard Worker     MultisampleRenderCase::init();
491*35238bceSAndroid Build Coastguard Worker }
492*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const493*35238bceSAndroid Build Coastguard Worker std::string SampleIDCase::genFragmentSource(int numTargetSamples) const
494*35238bceSAndroid Build Coastguard Worker {
495*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numTargetSamples != 0);
496*35238bceSAndroid Build Coastguard Worker 
497*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
498*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
499*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
500*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
501*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
502*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = (supportsES32orGL45) ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
503*35238bceSAndroid Build Coastguard Worker                                                        getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
504*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = (supportsES32orGL45) ? "" : "#extension GL_OES_sample_variables : require";
505*35238bceSAndroid Build Coastguard Worker 
506*35238bceSAndroid Build Coastguard Worker     if (m_vericationMode == VERIFY_USING_SAMPLES)
507*35238bceSAndroid Build Coastguard Worker     {
508*35238bceSAndroid Build Coastguard Worker         // encode the id to the output, and then verify it during sampling
509*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_VERSION_DECL}\n"
510*35238bceSAndroid Build Coastguard Worker                "${GLSL_EXTENSION}\n"
511*35238bceSAndroid Build Coastguard Worker                "layout(location = 0) out mediump vec4 fragColor;\n"
512*35238bceSAndroid Build Coastguard Worker                "void main (void)\n"
513*35238bceSAndroid Build Coastguard Worker                "{\n"
514*35238bceSAndroid Build Coastguard Worker                "    highp float normalizedSample = float(gl_SampleID) / float("
515*35238bceSAndroid Build Coastguard Worker             << numTargetSamples
516*35238bceSAndroid Build Coastguard Worker             << ");\n"
517*35238bceSAndroid Build Coastguard Worker                "    fragColor = vec4(0.0, normalizedSample, 1.0, 1.0);\n"
518*35238bceSAndroid Build Coastguard Worker                "}\n";
519*35238bceSAndroid Build Coastguard Worker     }
520*35238bceSAndroid Build Coastguard Worker     else if (m_vericationMode == VERIFY_USING_SELECTION)
521*35238bceSAndroid Build Coastguard Worker     {
522*35238bceSAndroid Build Coastguard Worker         if (numTargetSamples == 1)
523*35238bceSAndroid Build Coastguard Worker         {
524*35238bceSAndroid Build Coastguard Worker             // single sample, just verify value is 0
525*35238bceSAndroid Build Coastguard Worker             buf << "${GLSL_VERSION_DECL}\n"
526*35238bceSAndroid Build Coastguard Worker                    "${GLSL_EXTENSION}\n"
527*35238bceSAndroid Build Coastguard Worker                    "layout(location = 0) out mediump vec4 fragColor;\n"
528*35238bceSAndroid Build Coastguard Worker                    "void main (void)\n"
529*35238bceSAndroid Build Coastguard Worker                    "{\n"
530*35238bceSAndroid Build Coastguard Worker                    "    if (gl_SampleID == 0)\n"
531*35238bceSAndroid Build Coastguard Worker                    "        fragColor = vec4(0.0, 1.0, 1.0, 1.0);\n"
532*35238bceSAndroid Build Coastguard Worker                    "    else\n"
533*35238bceSAndroid Build Coastguard Worker                    "        fragColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
534*35238bceSAndroid Build Coastguard Worker                    "}\n";
535*35238bceSAndroid Build Coastguard Worker         }
536*35238bceSAndroid Build Coastguard Worker         else
537*35238bceSAndroid Build Coastguard Worker         {
538*35238bceSAndroid Build Coastguard Worker             // select only one sample per PIXEL
539*35238bceSAndroid Build Coastguard Worker             buf << "${GLSL_VERSION_DECL}\n"
540*35238bceSAndroid Build Coastguard Worker                    "${GLSL_EXTENSION}\n"
541*35238bceSAndroid Build Coastguard Worker                    "in highp vec4 v_position;\n"
542*35238bceSAndroid Build Coastguard Worker                    "layout(location = 0) out mediump vec4 fragColor;\n"
543*35238bceSAndroid Build Coastguard Worker                    "void main (void)\n"
544*35238bceSAndroid Build Coastguard Worker                    "{\n"
545*35238bceSAndroid Build Coastguard Worker                    "    highp vec2 relPosition = (v_position.xy + vec2(1.0, 1.0)) / 2.0;\n"
546*35238bceSAndroid Build Coastguard Worker                    "    highp ivec2 pixelPos = ivec2(floor(relPosition * "
547*35238bceSAndroid Build Coastguard Worker                 << (int)RENDER_SIZE
548*35238bceSAndroid Build Coastguard Worker                 << ".0));\n"
549*35238bceSAndroid Build Coastguard Worker                    "    highp int selectedID = abs(pixelPos.x + 17 * pixelPos.y) % "
550*35238bceSAndroid Build Coastguard Worker                 << numTargetSamples
551*35238bceSAndroid Build Coastguard Worker                 << ";\n"
552*35238bceSAndroid Build Coastguard Worker                    "\n"
553*35238bceSAndroid Build Coastguard Worker                    "    if (gl_SampleID == selectedID)\n"
554*35238bceSAndroid Build Coastguard Worker                    "        fragColor = vec4(0.0, 1.0, 1.0, 1.0);\n"
555*35238bceSAndroid Build Coastguard Worker                    "    else\n"
556*35238bceSAndroid Build Coastguard Worker                    "        fragColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
557*35238bceSAndroid Build Coastguard Worker                    "}\n";
558*35238bceSAndroid Build Coastguard Worker         }
559*35238bceSAndroid Build Coastguard Worker     }
560*35238bceSAndroid Build Coastguard Worker     else
561*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
562*35238bceSAndroid Build Coastguard Worker 
563*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
564*35238bceSAndroid Build Coastguard Worker }
565*35238bceSAndroid Build Coastguard Worker 
verifyImage(const tcu::Surface & resultImage)566*35238bceSAndroid Build Coastguard Worker bool SampleIDCase::verifyImage(const tcu::Surface &resultImage)
567*35238bceSAndroid Build Coastguard Worker {
568*35238bceSAndroid Build Coastguard Worker     if (m_vericationMode == VERIFY_USING_SAMPLES)
569*35238bceSAndroid Build Coastguard Worker     {
570*35238bceSAndroid Build Coastguard Worker         // never happens
571*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
572*35238bceSAndroid Build Coastguard Worker         return false;
573*35238bceSAndroid Build Coastguard Worker     }
574*35238bceSAndroid Build Coastguard Worker     else if (m_vericationMode == VERIFY_USING_SELECTION)
575*35238bceSAndroid Build Coastguard Worker     {
576*35238bceSAndroid Build Coastguard Worker         // should result in full blue and some green everywhere
577*35238bceSAndroid Build Coastguard Worker         return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), FullBlueSomeGreenVerifier());
578*35238bceSAndroid Build Coastguard Worker     }
579*35238bceSAndroid Build Coastguard Worker     else
580*35238bceSAndroid Build Coastguard Worker     {
581*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
582*35238bceSAndroid Build Coastguard Worker         return false;
583*35238bceSAndroid Build Coastguard Worker     }
584*35238bceSAndroid Build Coastguard Worker }
585*35238bceSAndroid Build Coastguard Worker 
verifySampleBuffers(const std::vector<tcu::Surface> & resultBuffers)586*35238bceSAndroid Build Coastguard Worker bool SampleIDCase::verifySampleBuffers(const std::vector<tcu::Surface> &resultBuffers)
587*35238bceSAndroid Build Coastguard Worker {
588*35238bceSAndroid Build Coastguard Worker     // Verify all sample buffers
589*35238bceSAndroid Build Coastguard Worker     bool allOk = true;
590*35238bceSAndroid Build Coastguard Worker 
591*35238bceSAndroid Build Coastguard Worker     // Log layers
592*35238bceSAndroid Build Coastguard Worker     {
593*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::ImageSet("SampleBuffers", "Image sample buffers");
594*35238bceSAndroid Build Coastguard Worker         for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
595*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Image("Buffer" + de::toString(sampleNdx),
596*35238bceSAndroid Build Coastguard Worker                                                       "Sample " + de::toString(sampleNdx),
597*35238bceSAndroid Build Coastguard Worker                                                       resultBuffers[sampleNdx].getAccess());
598*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::EndImageSet;
599*35238bceSAndroid Build Coastguard Worker     }
600*35238bceSAndroid Build Coastguard Worker 
601*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Verifying sample buffers" << tcu::TestLog::EndMessage;
602*35238bceSAndroid Build Coastguard Worker     for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
603*35238bceSAndroid Build Coastguard Worker     {
604*35238bceSAndroid Build Coastguard Worker         // sample id should be sample index
605*35238bceSAndroid Build Coastguard Worker         const int threshold       = 255 / 4 / m_numTargetSamples + 1;
606*35238bceSAndroid Build Coastguard Worker         const float sampleIdColor = (float)sampleNdx / (float)m_numTargetSamples;
607*35238bceSAndroid Build Coastguard Worker 
608*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying sample " << (sampleNdx + 1) << "/"
609*35238bceSAndroid Build Coastguard Worker                            << (int)resultBuffers.size() << tcu::TestLog::EndMessage;
610*35238bceSAndroid Build Coastguard Worker         allOk &= verifyImageWithVerifier(
611*35238bceSAndroid Build Coastguard Worker             resultBuffers[sampleNdx], m_testCtx.getLog(),
612*35238bceSAndroid Build Coastguard Worker             ColorVerifier(tcu::Vec3(0.0f, sampleIdColor, 1.0f), tcu::IVec3(1, threshold, 1)), false);
613*35238bceSAndroid Build Coastguard Worker     }
614*35238bceSAndroid Build Coastguard Worker 
615*35238bceSAndroid Build Coastguard Worker     if (!allOk)
616*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Sample buffer verification failed" << tcu::TestLog::EndMessage;
617*35238bceSAndroid Build Coastguard Worker 
618*35238bceSAndroid Build Coastguard Worker     return allOk;
619*35238bceSAndroid Build Coastguard Worker }
620*35238bceSAndroid Build Coastguard Worker 
621*35238bceSAndroid Build Coastguard Worker class SamplePosDistributionCase : public MultisampleRenderCase
622*35238bceSAndroid Build Coastguard Worker {
623*35238bceSAndroid Build Coastguard Worker public:
624*35238bceSAndroid Build Coastguard Worker     SamplePosDistributionCase(Context &context, const char *name, const char *desc, int sampleCount,
625*35238bceSAndroid Build Coastguard Worker                               RenderTarget target);
626*35238bceSAndroid Build Coastguard Worker     ~SamplePosDistributionCase(void);
627*35238bceSAndroid Build Coastguard Worker 
628*35238bceSAndroid Build Coastguard Worker     void init(void);
629*35238bceSAndroid Build Coastguard Worker 
630*35238bceSAndroid Build Coastguard Worker private:
631*35238bceSAndroid Build Coastguard Worker     enum
632*35238bceSAndroid Build Coastguard Worker     {
633*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
634*35238bceSAndroid Build Coastguard Worker     };
635*35238bceSAndroid Build Coastguard Worker 
636*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
637*35238bceSAndroid Build Coastguard Worker     bool verifyImage(const tcu::Surface &resultImage);
638*35238bceSAndroid Build Coastguard Worker     bool verifySampleBuffers(const std::vector<tcu::Surface> &resultBuffers);
639*35238bceSAndroid Build Coastguard Worker };
640*35238bceSAndroid Build Coastguard Worker 
SamplePosDistributionCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target)641*35238bceSAndroid Build Coastguard Worker SamplePosDistributionCase::SamplePosDistributionCase(Context &context, const char *name, const char *desc,
642*35238bceSAndroid Build Coastguard Worker                                                      int sampleCount, RenderTarget target)
643*35238bceSAndroid Build Coastguard Worker     : MultisampleRenderCase(context, name, desc, sampleCount, target, RENDER_SIZE,
644*35238bceSAndroid Build Coastguard Worker                             MultisampleShaderRenderUtil::MultisampleRenderCase::FLAG_VERIFY_MSAA_TEXTURE_SAMPLE_BUFFERS)
645*35238bceSAndroid Build Coastguard Worker {
646*35238bceSAndroid Build Coastguard Worker }
647*35238bceSAndroid Build Coastguard Worker 
~SamplePosDistributionCase(void)648*35238bceSAndroid Build Coastguard Worker SamplePosDistributionCase::~SamplePosDistributionCase(void)
649*35238bceSAndroid Build Coastguard Worker {
650*35238bceSAndroid Build Coastguard Worker }
651*35238bceSAndroid Build Coastguard Worker 
init(void)652*35238bceSAndroid Build Coastguard Worker void SamplePosDistributionCase::init(void)
653*35238bceSAndroid Build Coastguard Worker {
654*35238bceSAndroid Build Coastguard Worker     // log the test method and expectations
655*35238bceSAndroid Build Coastguard Worker     if (m_renderTarget == TARGET_TEXTURE)
656*35238bceSAndroid Build Coastguard Worker     {
657*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog()
658*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Message << "Verifying gl_SamplePosition value:\n"
659*35238bceSAndroid Build Coastguard Worker             << "    1) With non-multisample targets: Expect the center of the pixel.\n"
660*35238bceSAndroid Build Coastguard Worker             << "    2) With multisample targets:\n"
661*35238bceSAndroid Build Coastguard Worker             << "        a) Expect legal sample position.\n"
662*35238bceSAndroid Build Coastguard Worker             << "        b) Sample position is unique within the set of all sample positions of a pixel.\n"
663*35238bceSAndroid Build Coastguard Worker             << "        c) Sample position distribution is uniform or almost uniform.\n"
664*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::EndMessage;
665*35238bceSAndroid Build Coastguard Worker     }
666*35238bceSAndroid Build Coastguard Worker     else
667*35238bceSAndroid Build Coastguard Worker     {
668*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying gl_SamplePosition value:\n"
669*35238bceSAndroid Build Coastguard Worker                            << "    1) With non-multisample targets: Expect the center of the pixel.\n"
670*35238bceSAndroid Build Coastguard Worker                            << "    2) With multisample targets:\n"
671*35238bceSAndroid Build Coastguard Worker                            << "        a) Expect legal sample position.\n"
672*35238bceSAndroid Build Coastguard Worker                            << "        b) Sample position distribution is uniform or almost uniform.\n"
673*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
674*35238bceSAndroid Build Coastguard Worker     }
675*35238bceSAndroid Build Coastguard Worker 
676*35238bceSAndroid Build Coastguard Worker     MultisampleRenderCase::init();
677*35238bceSAndroid Build Coastguard Worker }
678*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const679*35238bceSAndroid Build Coastguard Worker std::string SamplePosDistributionCase::genFragmentSource(int numTargetSamples) const
680*35238bceSAndroid Build Coastguard Worker {
681*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numTargetSamples != 0);
682*35238bceSAndroid Build Coastguard Worker     DE_UNREF(numTargetSamples);
683*35238bceSAndroid Build Coastguard Worker 
684*35238bceSAndroid Build Coastguard Worker     const bool multisampleTarget = (m_numRequestedSamples > 0) || (m_renderTarget == TARGET_DEFAULT &&
685*35238bceSAndroid Build Coastguard Worker                                                                    m_context.getRenderTarget().getNumSamples() > 1);
686*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
687*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
688*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
689*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
690*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
691*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = (supportsES32orGL45) ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
692*35238bceSAndroid Build Coastguard Worker                                                        getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
693*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = (supportsES32orGL45) ? "\n" : "#extension GL_OES_sample_variables : require\n";
694*35238bceSAndroid Build Coastguard Worker 
695*35238bceSAndroid Build Coastguard Worker     if (multisampleTarget)
696*35238bceSAndroid Build Coastguard Worker     {
697*35238bceSAndroid Build Coastguard Worker         // encode the position to the output, use red channel as error channel
698*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_VERSION_DECL}\n"
699*35238bceSAndroid Build Coastguard Worker                "${GLSL_EXTENSION}\n"
700*35238bceSAndroid Build Coastguard Worker                "layout(location = 0) out mediump vec4 fragColor;\n"
701*35238bceSAndroid Build Coastguard Worker                "void main (void)\n"
702*35238bceSAndroid Build Coastguard Worker                "{\n"
703*35238bceSAndroid Build Coastguard Worker                "    if (gl_SamplePosition.x < 0.0 || gl_SamplePosition.x > 1.0 || gl_SamplePosition.y < 0.0 || "
704*35238bceSAndroid Build Coastguard Worker                "gl_SamplePosition.y > 1.0)\n"
705*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
706*35238bceSAndroid Build Coastguard Worker                "    else\n"
707*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(0.0, gl_SamplePosition.x, gl_SamplePosition.y, 1.0);\n"
708*35238bceSAndroid Build Coastguard Worker                "}\n";
709*35238bceSAndroid Build Coastguard Worker     }
710*35238bceSAndroid Build Coastguard Worker     else
711*35238bceSAndroid Build Coastguard Worker     {
712*35238bceSAndroid Build Coastguard Worker         // verify value is ok
713*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_VERSION_DECL}\n"
714*35238bceSAndroid Build Coastguard Worker                "${GLSL_EXTENSION}\n"
715*35238bceSAndroid Build Coastguard Worker                "layout(location = 0) out mediump vec4 fragColor;\n"
716*35238bceSAndroid Build Coastguard Worker                "void main (void)\n"
717*35238bceSAndroid Build Coastguard Worker                "{\n"
718*35238bceSAndroid Build Coastguard Worker                "    if (gl_SamplePosition.x != 0.5 || gl_SamplePosition.y != 0.5)\n"
719*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
720*35238bceSAndroid Build Coastguard Worker                "    else\n"
721*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(0.0, gl_SamplePosition.x, gl_SamplePosition.y, 1.0);\n"
722*35238bceSAndroid Build Coastguard Worker                "}\n";
723*35238bceSAndroid Build Coastguard Worker     }
724*35238bceSAndroid Build Coastguard Worker 
725*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
726*35238bceSAndroid Build Coastguard Worker }
727*35238bceSAndroid Build Coastguard Worker 
verifyImage(const tcu::Surface & resultImage)728*35238bceSAndroid Build Coastguard Worker bool SamplePosDistributionCase::verifyImage(const tcu::Surface &resultImage)
729*35238bceSAndroid Build Coastguard Worker {
730*35238bceSAndroid Build Coastguard Worker     const int sampleCount =
731*35238bceSAndroid Build Coastguard Worker         (m_renderTarget == TARGET_DEFAULT) ? (m_context.getRenderTarget().getNumSamples()) : (m_numRequestedSamples);
732*35238bceSAndroid Build Coastguard Worker     SampleAverageVerifier verifier(sampleCount);
733*35238bceSAndroid Build Coastguard Worker 
734*35238bceSAndroid Build Coastguard Worker     // check there is nothing in the error channel
735*35238bceSAndroid Build Coastguard Worker     if (!verifyImageWithVerifier(resultImage, m_testCtx.getLog(), NoRedVerifier()))
736*35238bceSAndroid Build Coastguard Worker         return false;
737*35238bceSAndroid Build Coastguard Worker 
738*35238bceSAndroid Build Coastguard Worker     // position average should be around 0.5, 0.5
739*35238bceSAndroid Build Coastguard Worker     if (verifier.m_isStatisticallySignificant && !verifyImageWithVerifier(resultImage, m_testCtx.getLog(), verifier))
740*35238bceSAndroid Build Coastguard Worker         throw MultisampleShaderRenderUtil::QualityWarning(
741*35238bceSAndroid Build Coastguard Worker             "Bias detected, sample positions are not uniformly distributed within the pixel");
742*35238bceSAndroid Build Coastguard Worker 
743*35238bceSAndroid Build Coastguard Worker     return true;
744*35238bceSAndroid Build Coastguard Worker }
745*35238bceSAndroid Build Coastguard Worker 
verifySampleBuffers(const std::vector<tcu::Surface> & resultBuffers)746*35238bceSAndroid Build Coastguard Worker bool SamplePosDistributionCase::verifySampleBuffers(const std::vector<tcu::Surface> &resultBuffers)
747*35238bceSAndroid Build Coastguard Worker {
748*35238bceSAndroid Build Coastguard Worker     const int width       = resultBuffers[0].getWidth();
749*35238bceSAndroid Build Coastguard Worker     const int height      = resultBuffers[0].getHeight();
750*35238bceSAndroid Build Coastguard Worker     bool allOk            = true;
751*35238bceSAndroid Build Coastguard Worker     bool distibutionError = false;
752*35238bceSAndroid Build Coastguard Worker 
753*35238bceSAndroid Build Coastguard Worker     // Check sample range, uniqueness, and distribution, log layers
754*35238bceSAndroid Build Coastguard Worker     {
755*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::ImageSet("SampleBuffers", "Image sample buffers");
756*35238bceSAndroid Build Coastguard Worker         for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
757*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Image("Buffer" + de::toString(sampleNdx),
758*35238bceSAndroid Build Coastguard Worker                                                       "Sample " + de::toString(sampleNdx),
759*35238bceSAndroid Build Coastguard Worker                                                       resultBuffers[sampleNdx].getAccess());
760*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::EndImageSet;
761*35238bceSAndroid Build Coastguard Worker     }
762*35238bceSAndroid Build Coastguard Worker 
763*35238bceSAndroid Build Coastguard Worker     // verify range
764*35238bceSAndroid Build Coastguard Worker     {
765*35238bceSAndroid Build Coastguard Worker         bool rangeOk = true;
766*35238bceSAndroid Build Coastguard Worker 
767*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying sample position range" << tcu::TestLog::EndMessage;
768*35238bceSAndroid Build Coastguard Worker         for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
769*35238bceSAndroid Build Coastguard Worker         {
770*35238bceSAndroid Build Coastguard Worker             // shader does the check, just check the shader error output (red)
771*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Verifying sample " << (sampleNdx + 1) << "/"
772*35238bceSAndroid Build Coastguard Worker                                << (int)resultBuffers.size() << tcu::TestLog::EndMessage;
773*35238bceSAndroid Build Coastguard Worker             rangeOk &= verifyImageWithVerifier(resultBuffers[sampleNdx], m_testCtx.getLog(), NoRedVerifier(), false);
774*35238bceSAndroid Build Coastguard Worker         }
775*35238bceSAndroid Build Coastguard Worker 
776*35238bceSAndroid Build Coastguard Worker         if (!rangeOk)
777*35238bceSAndroid Build Coastguard Worker         {
778*35238bceSAndroid Build Coastguard Worker             allOk = false;
779*35238bceSAndroid Build Coastguard Worker 
780*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Sample position verification failed."
781*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
782*35238bceSAndroid Build Coastguard Worker         }
783*35238bceSAndroid Build Coastguard Worker     }
784*35238bceSAndroid Build Coastguard Worker 
785*35238bceSAndroid Build Coastguard Worker     // Verify uniqueness
786*35238bceSAndroid Build Coastguard Worker     {
787*35238bceSAndroid Build Coastguard Worker         bool uniquenessOk = true;
788*35238bceSAndroid Build Coastguard Worker         tcu::Surface errorMask(width, height);
789*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec2> samplePositions(resultBuffers.size());
790*35238bceSAndroid Build Coastguard Worker         int printCount            = 0;
791*35238bceSAndroid Build Coastguard Worker         const int printFloodLimit = 5;
792*35238bceSAndroid Build Coastguard Worker 
793*35238bceSAndroid Build Coastguard Worker         tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
794*35238bceSAndroid Build Coastguard Worker 
795*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying sample position uniqueness."
796*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
797*35238bceSAndroid Build Coastguard Worker 
798*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < height; ++y)
799*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < width; ++x)
800*35238bceSAndroid Build Coastguard Worker             {
801*35238bceSAndroid Build Coastguard Worker                 bool samplePosNotUnique = false;
802*35238bceSAndroid Build Coastguard Worker 
803*35238bceSAndroid Build Coastguard Worker                 for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
804*35238bceSAndroid Build Coastguard Worker                 {
805*35238bceSAndroid Build Coastguard Worker                     const tcu::RGBA color = resultBuffers[sampleNdx].getPixel(x, y);
806*35238bceSAndroid Build Coastguard Worker                     samplePositions[sampleNdx] =
807*35238bceSAndroid Build Coastguard Worker                         tcu::Vec2((float)color.getGreen() / 255.0f, (float)color.getBlue() / 255.0f);
808*35238bceSAndroid Build Coastguard Worker                 }
809*35238bceSAndroid Build Coastguard Worker 
810*35238bceSAndroid Build Coastguard Worker                 // Just check there are no two samples with same positions
811*35238bceSAndroid Build Coastguard Worker                 for (int sampleNdxA = 0;
812*35238bceSAndroid Build Coastguard Worker                      sampleNdxA < (int)resultBuffers.size() && (!samplePosNotUnique || printCount < printFloodLimit);
813*35238bceSAndroid Build Coastguard Worker                      ++sampleNdxA)
814*35238bceSAndroid Build Coastguard Worker                     for (int sampleNdxB = sampleNdxA + 1; sampleNdxB < (int)resultBuffers.size() &&
815*35238bceSAndroid Build Coastguard Worker                                                           (!samplePosNotUnique || printCount < printFloodLimit);
816*35238bceSAndroid Build Coastguard Worker                          ++sampleNdxB)
817*35238bceSAndroid Build Coastguard Worker                     {
818*35238bceSAndroid Build Coastguard Worker                         if (samplePositions[sampleNdxA] == samplePositions[sampleNdxB])
819*35238bceSAndroid Build Coastguard Worker                         {
820*35238bceSAndroid Build Coastguard Worker                             if (++printCount <= printFloodLimit)
821*35238bceSAndroid Build Coastguard Worker                             {
822*35238bceSAndroid Build Coastguard Worker                                 m_testCtx.getLog() << tcu::TestLog::Message << "Pixel (" << x << ", " << y
823*35238bceSAndroid Build Coastguard Worker                                                    << "): Samples " << sampleNdxA << " and " << sampleNdxB
824*35238bceSAndroid Build Coastguard Worker                                                    << " have the same position." << tcu::TestLog::EndMessage;
825*35238bceSAndroid Build Coastguard Worker                             }
826*35238bceSAndroid Build Coastguard Worker 
827*35238bceSAndroid Build Coastguard Worker                             samplePosNotUnique = true;
828*35238bceSAndroid Build Coastguard Worker                             uniquenessOk       = false;
829*35238bceSAndroid Build Coastguard Worker                             errorMask.setPixel(x, y, tcu::RGBA::red());
830*35238bceSAndroid Build Coastguard Worker                         }
831*35238bceSAndroid Build Coastguard Worker                     }
832*35238bceSAndroid Build Coastguard Worker             }
833*35238bceSAndroid Build Coastguard Worker 
834*35238bceSAndroid Build Coastguard Worker         // end result
835*35238bceSAndroid Build Coastguard Worker         if (!uniquenessOk)
836*35238bceSAndroid Build Coastguard Worker         {
837*35238bceSAndroid Build Coastguard Worker             if (printCount > printFloodLimit)
838*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "...\n"
839*35238bceSAndroid Build Coastguard Worker                                    << "Omitted " << (printCount - printFloodLimit) << " error descriptions."
840*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
841*35238bceSAndroid Build Coastguard Worker 
842*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
843*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::ImageSet("Verification", "Image Verification")
844*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("ErrorMask", "Error Mask", errorMask.getAccess())
845*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndImageSet;
846*35238bceSAndroid Build Coastguard Worker 
847*35238bceSAndroid Build Coastguard Worker             allOk = false;
848*35238bceSAndroid Build Coastguard Worker         }
849*35238bceSAndroid Build Coastguard Worker     }
850*35238bceSAndroid Build Coastguard Worker 
851*35238bceSAndroid Build Coastguard Worker     // check distribution
852*35238bceSAndroid Build Coastguard Worker     {
853*35238bceSAndroid Build Coastguard Worker         const SampleAverageVerifier verifier(m_numTargetSamples);
854*35238bceSAndroid Build Coastguard Worker         tcu::Surface errorMask(width, height);
855*35238bceSAndroid Build Coastguard Worker         int printCount            = 0;
856*35238bceSAndroid Build Coastguard Worker         const int printFloodLimit = 5;
857*35238bceSAndroid Build Coastguard Worker 
858*35238bceSAndroid Build Coastguard Worker         tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
859*35238bceSAndroid Build Coastguard Worker 
860*35238bceSAndroid Build Coastguard Worker         // don't bother with small sample counts
861*35238bceSAndroid Build Coastguard Worker         if (verifier.m_isStatisticallySignificant)
862*35238bceSAndroid Build Coastguard Worker         {
863*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
864*35238bceSAndroid Build Coastguard Worker                                << "Verifying sample position distribution is (nearly) unbiased."
865*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
866*35238bceSAndroid Build Coastguard Worker             verifier.logInfo(m_testCtx.getLog());
867*35238bceSAndroid Build Coastguard Worker 
868*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < height; ++y)
869*35238bceSAndroid Build Coastguard Worker                 for (int x = 0; x < width; ++x)
870*35238bceSAndroid Build Coastguard Worker                 {
871*35238bceSAndroid Build Coastguard Worker                     tcu::IVec3 colorSum(0, 0, 0);
872*35238bceSAndroid Build Coastguard Worker 
873*35238bceSAndroid Build Coastguard Worker                     // color average
874*35238bceSAndroid Build Coastguard Worker 
875*35238bceSAndroid Build Coastguard Worker                     for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
876*35238bceSAndroid Build Coastguard Worker                     {
877*35238bceSAndroid Build Coastguard Worker                         const tcu::RGBA color = resultBuffers[sampleNdx].getPixel(x, y);
878*35238bceSAndroid Build Coastguard Worker                         colorSum.x() += color.getRed();
879*35238bceSAndroid Build Coastguard Worker                         colorSum.y() += color.getBlue();
880*35238bceSAndroid Build Coastguard Worker                         colorSum.z() += color.getGreen();
881*35238bceSAndroid Build Coastguard Worker                     }
882*35238bceSAndroid Build Coastguard Worker 
883*35238bceSAndroid Build Coastguard Worker                     colorSum.x() /= m_numTargetSamples;
884*35238bceSAndroid Build Coastguard Worker                     colorSum.y() /= m_numTargetSamples;
885*35238bceSAndroid Build Coastguard Worker                     colorSum.z() /= m_numTargetSamples;
886*35238bceSAndroid Build Coastguard Worker 
887*35238bceSAndroid Build Coastguard Worker                     // verify average sample position
888*35238bceSAndroid Build Coastguard Worker 
889*35238bceSAndroid Build Coastguard Worker                     if (!verifier.verify(tcu::RGBA(colorSum.x(), colorSum.y(), colorSum.z(), 0), tcu::IVec2(x, y)))
890*35238bceSAndroid Build Coastguard Worker                     {
891*35238bceSAndroid Build Coastguard Worker                         if (++printCount <= printFloodLimit)
892*35238bceSAndroid Build Coastguard Worker                         {
893*35238bceSAndroid Build Coastguard Worker                             m_testCtx.getLog() << tcu::TestLog::Message << "Pixel (" << x << ", " << y
894*35238bceSAndroid Build Coastguard Worker                                                << "): Sample distribution is biased." << tcu::TestLog::EndMessage;
895*35238bceSAndroid Build Coastguard Worker                         }
896*35238bceSAndroid Build Coastguard Worker 
897*35238bceSAndroid Build Coastguard Worker                         distibutionError = true;
898*35238bceSAndroid Build Coastguard Worker                         errorMask.setPixel(x, y, tcu::RGBA::red());
899*35238bceSAndroid Build Coastguard Worker                     }
900*35238bceSAndroid Build Coastguard Worker                 }
901*35238bceSAndroid Build Coastguard Worker 
902*35238bceSAndroid Build Coastguard Worker             // sub-verification result
903*35238bceSAndroid Build Coastguard Worker             if (distibutionError)
904*35238bceSAndroid Build Coastguard Worker             {
905*35238bceSAndroid Build Coastguard Worker                 if (printCount > printFloodLimit)
906*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "...\n"
907*35238bceSAndroid Build Coastguard Worker                                        << "Omitted " << (printCount - printFloodLimit) << " error descriptions."
908*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::EndMessage;
909*35238bceSAndroid Build Coastguard Worker 
910*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
911*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::ImageSet("Verification", "Image Verification")
912*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::Image("ErrorMask", "Error Mask", errorMask.getAccess())
913*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndImageSet;
914*35238bceSAndroid Build Coastguard Worker             }
915*35238bceSAndroid Build Coastguard Worker         }
916*35238bceSAndroid Build Coastguard Worker     }
917*35238bceSAndroid Build Coastguard Worker 
918*35238bceSAndroid Build Coastguard Worker     // results
919*35238bceSAndroid Build Coastguard Worker     if (!allOk)
920*35238bceSAndroid Build Coastguard Worker         return false;
921*35238bceSAndroid Build Coastguard Worker     else if (distibutionError)
922*35238bceSAndroid Build Coastguard Worker         throw MultisampleShaderRenderUtil::QualityWarning(
923*35238bceSAndroid Build Coastguard Worker             "Bias detected, sample positions are not uniformly distributed within the pixel");
924*35238bceSAndroid Build Coastguard Worker     else
925*35238bceSAndroid Build Coastguard Worker     {
926*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verification ok." << tcu::TestLog::EndMessage;
927*35238bceSAndroid Build Coastguard Worker         return true;
928*35238bceSAndroid Build Coastguard Worker     }
929*35238bceSAndroid Build Coastguard Worker }
930*35238bceSAndroid Build Coastguard Worker 
931*35238bceSAndroid Build Coastguard Worker class SamplePosCorrectnessCase : public MultisampleRenderCase
932*35238bceSAndroid Build Coastguard Worker {
933*35238bceSAndroid Build Coastguard Worker public:
934*35238bceSAndroid Build Coastguard Worker     SamplePosCorrectnessCase(Context &context, const char *name, const char *desc, int sampleCount,
935*35238bceSAndroid Build Coastguard Worker                              RenderTarget target);
936*35238bceSAndroid Build Coastguard Worker     ~SamplePosCorrectnessCase(void);
937*35238bceSAndroid Build Coastguard Worker 
938*35238bceSAndroid Build Coastguard Worker     void init(void);
939*35238bceSAndroid Build Coastguard Worker 
940*35238bceSAndroid Build Coastguard Worker private:
941*35238bceSAndroid Build Coastguard Worker     enum
942*35238bceSAndroid Build Coastguard Worker     {
943*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 32
944*35238bceSAndroid Build Coastguard Worker     };
945*35238bceSAndroid Build Coastguard Worker 
946*35238bceSAndroid Build Coastguard Worker     void preDraw(void);
947*35238bceSAndroid Build Coastguard Worker     void postDraw(void);
948*35238bceSAndroid Build Coastguard Worker 
949*35238bceSAndroid Build Coastguard Worker     std::string genVertexSource(int numTargetSamples) const;
950*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
951*35238bceSAndroid Build Coastguard Worker     bool verifyImage(const tcu::Surface &resultImage);
952*35238bceSAndroid Build Coastguard Worker 
953*35238bceSAndroid Build Coastguard Worker     bool m_useSampleQualifier;
954*35238bceSAndroid Build Coastguard Worker };
955*35238bceSAndroid Build Coastguard Worker 
SamplePosCorrectnessCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target)956*35238bceSAndroid Build Coastguard Worker SamplePosCorrectnessCase::SamplePosCorrectnessCase(Context &context, const char *name, const char *desc,
957*35238bceSAndroid Build Coastguard Worker                                                    int sampleCount, RenderTarget target)
958*35238bceSAndroid Build Coastguard Worker     : MultisampleRenderCase(context, name, desc, sampleCount, target, RENDER_SIZE)
959*35238bceSAndroid Build Coastguard Worker     , m_useSampleQualifier(false)
960*35238bceSAndroid Build Coastguard Worker {
961*35238bceSAndroid Build Coastguard Worker }
962*35238bceSAndroid Build Coastguard Worker 
~SamplePosCorrectnessCase(void)963*35238bceSAndroid Build Coastguard Worker SamplePosCorrectnessCase::~SamplePosCorrectnessCase(void)
964*35238bceSAndroid Build Coastguard Worker {
965*35238bceSAndroid Build Coastguard Worker }
966*35238bceSAndroid Build Coastguard Worker 
init(void)967*35238bceSAndroid Build Coastguard Worker void SamplePosCorrectnessCase::init(void)
968*35238bceSAndroid Build Coastguard Worker {
969*35238bceSAndroid Build Coastguard Worker     auto ctxType            = m_context.getRenderContext().getType();
970*35238bceSAndroid Build Coastguard Worker     const bool isES32orGL45 = glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
971*35238bceSAndroid Build Coastguard Worker                               glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
972*35238bceSAndroid Build Coastguard Worker 
973*35238bceSAndroid Build Coastguard Worker     // requirements: per-invocation interpolation required
974*35238bceSAndroid Build Coastguard Worker     if (!isES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation") &&
975*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
976*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation or GL_OES_sample_shading "
977*35238bceSAndroid Build Coastguard Worker                                      "extension or a context version 3.2 or higher.");
978*35238bceSAndroid Build Coastguard Worker 
979*35238bceSAndroid Build Coastguard Worker     // prefer to use the sample qualifier path
980*35238bceSAndroid Build Coastguard Worker     m_useSampleQualifier = m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation");
981*35238bceSAndroid Build Coastguard Worker 
982*35238bceSAndroid Build Coastguard Worker     // log the test method and expectations
983*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Verifying gl_SamplePosition correctness:\n"
984*35238bceSAndroid Build Coastguard Worker                        << "    1) Varying values should be sampled at the sample position.\n"
985*35238bceSAndroid Build Coastguard Worker                        << " => fract(screenSpacePosition) == gl_SamplePosition\n"
986*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
987*35238bceSAndroid Build Coastguard Worker 
988*35238bceSAndroid Build Coastguard Worker     MultisampleRenderCase::init();
989*35238bceSAndroid Build Coastguard Worker }
990*35238bceSAndroid Build Coastguard Worker 
preDraw(void)991*35238bceSAndroid Build Coastguard Worker void SamplePosCorrectnessCase::preDraw(void)
992*35238bceSAndroid Build Coastguard Worker {
993*35238bceSAndroid Build Coastguard Worker     if (!m_useSampleQualifier)
994*35238bceSAndroid Build Coastguard Worker     {
995*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
996*35238bceSAndroid Build Coastguard Worker 
997*35238bceSAndroid Build Coastguard Worker         // use GL_OES_sample_shading to set per fragment sample invocation interpolation
998*35238bceSAndroid Build Coastguard Worker         gl.enable(GL_SAMPLE_SHADING);
999*35238bceSAndroid Build Coastguard Worker         gl.minSampleShading(1.0f);
1000*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set ratio");
1001*35238bceSAndroid Build Coastguard Worker 
1002*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Enabling per-sample interpolation with GL_SAMPLE_SHADING."
1003*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1004*35238bceSAndroid Build Coastguard Worker     }
1005*35238bceSAndroid Build Coastguard Worker }
1006*35238bceSAndroid Build Coastguard Worker 
postDraw(void)1007*35238bceSAndroid Build Coastguard Worker void SamplePosCorrectnessCase::postDraw(void)
1008*35238bceSAndroid Build Coastguard Worker {
1009*35238bceSAndroid Build Coastguard Worker     if (!m_useSampleQualifier)
1010*35238bceSAndroid Build Coastguard Worker     {
1011*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1012*35238bceSAndroid Build Coastguard Worker 
1013*35238bceSAndroid Build Coastguard Worker         gl.disable(GL_SAMPLE_SHADING);
1014*35238bceSAndroid Build Coastguard Worker         gl.minSampleShading(1.0f);
1015*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set ratio");
1016*35238bceSAndroid Build Coastguard Worker     }
1017*35238bceSAndroid Build Coastguard Worker }
1018*35238bceSAndroid Build Coastguard Worker 
genVertexSource(int numTargetSamples) const1019*35238bceSAndroid Build Coastguard Worker std::string SamplePosCorrectnessCase::genVertexSource(int numTargetSamples) const
1020*35238bceSAndroid Build Coastguard Worker {
1021*35238bceSAndroid Build Coastguard Worker     DE_UNREF(numTargetSamples);
1022*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
1023*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
1024*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
1025*35238bceSAndroid Build Coastguard Worker 
1026*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1027*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
1028*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = supportsES32orGL45 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
1029*35238bceSAndroid Build Coastguard Worker                                                      getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1030*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = supportsES32orGL45   ? "" :
1031*35238bceSAndroid Build Coastguard Worker                                 m_useSampleQualifier ? "#extension GL_OES_shader_multisample_interpolation : require" :
1032*35238bceSAndroid Build Coastguard Worker                                                        "";
1033*35238bceSAndroid Build Coastguard Worker 
1034*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1035*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXTENSION}\n"
1036*35238bceSAndroid Build Coastguard Worker         << "in highp vec4 a_position;\n"
1037*35238bceSAndroid Build Coastguard Worker         << ((m_useSampleQualifier) ? ("sample ") : (""))
1038*35238bceSAndroid Build Coastguard Worker         << "out highp vec4 v_position;\n"
1039*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1040*35238bceSAndroid Build Coastguard Worker            "{\n"
1041*35238bceSAndroid Build Coastguard Worker            "    gl_Position = a_position;\n"
1042*35238bceSAndroid Build Coastguard Worker            "    v_position = a_position;\n"
1043*35238bceSAndroid Build Coastguard Worker            "}\n";
1044*35238bceSAndroid Build Coastguard Worker 
1045*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
1046*35238bceSAndroid Build Coastguard Worker }
1047*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const1048*35238bceSAndroid Build Coastguard Worker std::string SamplePosCorrectnessCase::genFragmentSource(int numTargetSamples) const
1049*35238bceSAndroid Build Coastguard Worker {
1050*35238bceSAndroid Build Coastguard Worker     DE_UNREF(numTargetSamples);
1051*35238bceSAndroid Build Coastguard Worker 
1052*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1053*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
1054*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
1055*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
1056*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
1057*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"]     = supportsES32orGL45 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
1058*35238bceSAndroid Build Coastguard Worker                                                          getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1059*35238bceSAndroid Build Coastguard Worker     args["GLSL_SAMPLE_EXTENSION"] = supportsES32orGL45 ? "" : "#extension GL_OES_sample_variables : require";
1060*35238bceSAndroid Build Coastguard Worker     args["GLSL_MULTISAMPLE_EXTENSION"] =
1061*35238bceSAndroid Build Coastguard Worker         supportsES32orGL45   ? "" :
1062*35238bceSAndroid Build Coastguard Worker         m_useSampleQualifier ? "#extension GL_OES_shader_multisample_interpolation : require" :
1063*35238bceSAndroid Build Coastguard Worker                                "";
1064*35238bceSAndroid Build Coastguard Worker 
1065*35238bceSAndroid Build Coastguard Worker     // encode the position to the output, use red channel as error channel
1066*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1067*35238bceSAndroid Build Coastguard Worker            "${GLSL_SAMPLE_EXTENSION}\n"
1068*35238bceSAndroid Build Coastguard Worker            "${GLSL_MULTISAMPLE_EXTENSION}\n"
1069*35238bceSAndroid Build Coastguard Worker         << ((m_useSampleQualifier) ? ("sample ") : (""))
1070*35238bceSAndroid Build Coastguard Worker         << "in highp vec4 v_position;\n"
1071*35238bceSAndroid Build Coastguard Worker            "layout(location = 0) out mediump vec4 fragColor;\n"
1072*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1073*35238bceSAndroid Build Coastguard Worker            "{\n"
1074*35238bceSAndroid Build Coastguard Worker            "    const highp float maxDistance = 0.15625; // 4 subpixel bits. Assume 3 accurate bits + 0.03125 for "
1075*35238bceSAndroid Build Coastguard Worker            "other errors\n" // 0.03125 = mediump epsilon when value = 32 (RENDER_SIZE)
1076*35238bceSAndroid Build Coastguard Worker            "\n"
1077*35238bceSAndroid Build Coastguard Worker            "    highp vec2 screenSpacePosition = (v_position.xy + vec2(1.0, 1.0)) / 2.0 * "
1078*35238bceSAndroid Build Coastguard Worker         << (int)RENDER_SIZE
1079*35238bceSAndroid Build Coastguard Worker         << ".0;\n"
1080*35238bceSAndroid Build Coastguard Worker            "    highp ivec2 nearbyPixel = ivec2(floor(screenSpacePosition));\n"
1081*35238bceSAndroid Build Coastguard Worker            "    bool allOk = false;\n"
1082*35238bceSAndroid Build Coastguard Worker            "\n"
1083*35238bceSAndroid Build Coastguard Worker            "    // sample at edge + inaccuaries may cause us to round to any neighboring pixel\n"
1084*35238bceSAndroid Build Coastguard Worker            "    // check all neighbors for any match\n"
1085*35238bceSAndroid Build Coastguard Worker            "    for (highp int dy = -1; dy <= 1; ++dy)\n"
1086*35238bceSAndroid Build Coastguard Worker            "    for (highp int dx = -1; dx <= 1; ++dx)\n"
1087*35238bceSAndroid Build Coastguard Worker            "    {\n"
1088*35238bceSAndroid Build Coastguard Worker            "        highp ivec2 currentPixel = nearbyPixel + ivec2(dx, dy);\n"
1089*35238bceSAndroid Build Coastguard Worker            "        highp vec2 candidateSamplingPos = vec2(currentPixel) + gl_SamplePosition.xy;\n"
1090*35238bceSAndroid Build Coastguard Worker            "        highp vec2 positionDiff = abs(candidateSamplingPos - screenSpacePosition);\n"
1091*35238bceSAndroid Build Coastguard Worker            "        if (positionDiff.x < maxDistance && positionDiff.y < maxDistance)\n"
1092*35238bceSAndroid Build Coastguard Worker            "            allOk = true;\n"
1093*35238bceSAndroid Build Coastguard Worker            "    }\n"
1094*35238bceSAndroid Build Coastguard Worker            "\n"
1095*35238bceSAndroid Build Coastguard Worker            "    if (allOk)\n"
1096*35238bceSAndroid Build Coastguard Worker            "        fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
1097*35238bceSAndroid Build Coastguard Worker            "    else\n"
1098*35238bceSAndroid Build Coastguard Worker            "        fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
1099*35238bceSAndroid Build Coastguard Worker            "}\n";
1100*35238bceSAndroid Build Coastguard Worker 
1101*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
1102*35238bceSAndroid Build Coastguard Worker }
1103*35238bceSAndroid Build Coastguard Worker 
verifyImage(const tcu::Surface & resultImage)1104*35238bceSAndroid Build Coastguard Worker bool SamplePosCorrectnessCase::verifyImage(const tcu::Surface &resultImage)
1105*35238bceSAndroid Build Coastguard Worker {
1106*35238bceSAndroid Build Coastguard Worker     return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), NoRedVerifier());
1107*35238bceSAndroid Build Coastguard Worker }
1108*35238bceSAndroid Build Coastguard Worker 
1109*35238bceSAndroid Build Coastguard Worker class SampleMaskBaseCase : public MultisampleRenderCase
1110*35238bceSAndroid Build Coastguard Worker {
1111*35238bceSAndroid Build Coastguard Worker public:
1112*35238bceSAndroid Build Coastguard Worker     enum ShaderRunMode
1113*35238bceSAndroid Build Coastguard Worker     {
1114*35238bceSAndroid Build Coastguard Worker         RUN_PER_PIXEL = 0,
1115*35238bceSAndroid Build Coastguard Worker         RUN_PER_SAMPLE,
1116*35238bceSAndroid Build Coastguard Worker         RUN_PER_TWO_SAMPLES,
1117*35238bceSAndroid Build Coastguard Worker 
1118*35238bceSAndroid Build Coastguard Worker         RUN_LAST
1119*35238bceSAndroid Build Coastguard Worker     };
1120*35238bceSAndroid Build Coastguard Worker 
1121*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target,
1122*35238bceSAndroid Build Coastguard Worker                        int renderSize, ShaderRunMode runMode, int flags = 0);
1123*35238bceSAndroid Build Coastguard Worker     virtual ~SampleMaskBaseCase(void);
1124*35238bceSAndroid Build Coastguard Worker 
1125*35238bceSAndroid Build Coastguard Worker protected:
1126*35238bceSAndroid Build Coastguard Worker     virtual void init(void);
1127*35238bceSAndroid Build Coastguard Worker     virtual void preDraw(void);
1128*35238bceSAndroid Build Coastguard Worker     virtual void postDraw(void);
1129*35238bceSAndroid Build Coastguard Worker     virtual bool verifyImage(const tcu::Surface &resultImage);
1130*35238bceSAndroid Build Coastguard Worker 
1131*35238bceSAndroid Build Coastguard Worker     const ShaderRunMode m_runMode;
1132*35238bceSAndroid Build Coastguard Worker };
1133*35238bceSAndroid Build Coastguard Worker 
SampleMaskBaseCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target,int renderSize,ShaderRunMode runMode,int flags)1134*35238bceSAndroid Build Coastguard Worker SampleMaskBaseCase::SampleMaskBaseCase(Context &context, const char *name, const char *desc, int sampleCount,
1135*35238bceSAndroid Build Coastguard Worker                                        RenderTarget target, int renderSize, ShaderRunMode runMode, int flags)
1136*35238bceSAndroid Build Coastguard Worker     : MultisampleRenderCase(context, name, desc, sampleCount, target, renderSize, flags)
1137*35238bceSAndroid Build Coastguard Worker     , m_runMode(runMode)
1138*35238bceSAndroid Build Coastguard Worker {
1139*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(runMode < RUN_LAST);
1140*35238bceSAndroid Build Coastguard Worker }
1141*35238bceSAndroid Build Coastguard Worker 
~SampleMaskBaseCase(void)1142*35238bceSAndroid Build Coastguard Worker SampleMaskBaseCase::~SampleMaskBaseCase(void)
1143*35238bceSAndroid Build Coastguard Worker {
1144*35238bceSAndroid Build Coastguard Worker }
1145*35238bceSAndroid Build Coastguard Worker 
init(void)1146*35238bceSAndroid Build Coastguard Worker void SampleMaskBaseCase::init(void)
1147*35238bceSAndroid Build Coastguard Worker {
1148*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
1149*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
1150*35238bceSAndroid Build Coastguard Worker         contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
1151*35238bceSAndroid Build Coastguard Worker     // required extra extension
1152*35238bceSAndroid Build Coastguard Worker     if (m_runMode == RUN_PER_TWO_SAMPLES && !supportsES32orGL45 &&
1153*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
1154*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError,
1155*35238bceSAndroid Build Coastguard Worker                   "Test requires GL_OES_sample_shading extension or a context version 3.2 or higher.");
1156*35238bceSAndroid Build Coastguard Worker 
1157*35238bceSAndroid Build Coastguard Worker     MultisampleRenderCase::init();
1158*35238bceSAndroid Build Coastguard Worker }
1159*35238bceSAndroid Build Coastguard Worker 
preDraw(void)1160*35238bceSAndroid Build Coastguard Worker void SampleMaskBaseCase::preDraw(void)
1161*35238bceSAndroid Build Coastguard Worker {
1162*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1163*35238bceSAndroid Build Coastguard Worker 
1164*35238bceSAndroid Build Coastguard Worker     if (m_runMode == RUN_PER_TWO_SAMPLES)
1165*35238bceSAndroid Build Coastguard Worker     {
1166*35238bceSAndroid Build Coastguard Worker         gl.enable(GL_SAMPLE_SHADING);
1167*35238bceSAndroid Build Coastguard Worker         gl.minSampleShading(0.5f);
1168*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "enable sample shading");
1169*35238bceSAndroid Build Coastguard Worker 
1170*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Enabled GL_SAMPLE_SHADING, value = 0.5"
1171*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1172*35238bceSAndroid Build Coastguard Worker     }
1173*35238bceSAndroid Build Coastguard Worker }
1174*35238bceSAndroid Build Coastguard Worker 
postDraw(void)1175*35238bceSAndroid Build Coastguard Worker void SampleMaskBaseCase::postDraw(void)
1176*35238bceSAndroid Build Coastguard Worker {
1177*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1178*35238bceSAndroid Build Coastguard Worker 
1179*35238bceSAndroid Build Coastguard Worker     if (m_runMode == RUN_PER_TWO_SAMPLES)
1180*35238bceSAndroid Build Coastguard Worker     {
1181*35238bceSAndroid Build Coastguard Worker         gl.disable(GL_SAMPLE_SHADING);
1182*35238bceSAndroid Build Coastguard Worker         gl.minSampleShading(1.0f);
1183*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "disable sample shading");
1184*35238bceSAndroid Build Coastguard Worker     }
1185*35238bceSAndroid Build Coastguard Worker }
1186*35238bceSAndroid Build Coastguard Worker 
verifyImage(const tcu::Surface & resultImage)1187*35238bceSAndroid Build Coastguard Worker bool SampleMaskBaseCase::verifyImage(const tcu::Surface &resultImage)
1188*35238bceSAndroid Build Coastguard Worker {
1189*35238bceSAndroid Build Coastguard Worker     // shader does the verification
1190*35238bceSAndroid Build Coastguard Worker     return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), NoRedVerifier());
1191*35238bceSAndroid Build Coastguard Worker }
1192*35238bceSAndroid Build Coastguard Worker 
1193*35238bceSAndroid Build Coastguard Worker class SampleMaskCase : public SampleMaskBaseCase
1194*35238bceSAndroid Build Coastguard Worker {
1195*35238bceSAndroid Build Coastguard Worker public:
1196*35238bceSAndroid Build Coastguard Worker     SampleMaskCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target);
1197*35238bceSAndroid Build Coastguard Worker     ~SampleMaskCase(void);
1198*35238bceSAndroid Build Coastguard Worker 
1199*35238bceSAndroid Build Coastguard Worker     void init(void);
1200*35238bceSAndroid Build Coastguard Worker     void preDraw(void);
1201*35238bceSAndroid Build Coastguard Worker     void postDraw(void);
1202*35238bceSAndroid Build Coastguard Worker 
1203*35238bceSAndroid Build Coastguard Worker private:
1204*35238bceSAndroid Build Coastguard Worker     enum
1205*35238bceSAndroid Build Coastguard Worker     {
1206*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
1207*35238bceSAndroid Build Coastguard Worker     };
1208*35238bceSAndroid Build Coastguard Worker 
1209*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
1210*35238bceSAndroid Build Coastguard Worker };
1211*35238bceSAndroid Build Coastguard Worker 
SampleMaskCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target)1212*35238bceSAndroid Build Coastguard Worker SampleMaskCase::SampleMaskCase(Context &context, const char *name, const char *desc, int sampleCount,
1213*35238bceSAndroid Build Coastguard Worker                                RenderTarget target)
1214*35238bceSAndroid Build Coastguard Worker     : SampleMaskBaseCase(context, name, desc, sampleCount, target, RENDER_SIZE, RUN_PER_PIXEL)
1215*35238bceSAndroid Build Coastguard Worker {
1216*35238bceSAndroid Build Coastguard Worker }
1217*35238bceSAndroid Build Coastguard Worker 
~SampleMaskCase(void)1218*35238bceSAndroid Build Coastguard Worker SampleMaskCase::~SampleMaskCase(void)
1219*35238bceSAndroid Build Coastguard Worker {
1220*35238bceSAndroid Build Coastguard Worker }
1221*35238bceSAndroid Build Coastguard Worker 
init(void)1222*35238bceSAndroid Build Coastguard Worker void SampleMaskCase::init(void)
1223*35238bceSAndroid Build Coastguard Worker {
1224*35238bceSAndroid Build Coastguard Worker     // log the test method and expectations
1225*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog()
1226*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Message
1227*35238bceSAndroid Build Coastguard Worker         << "Verifying gl_SampleMaskIn value with SAMPLE_MASK state. gl_SampleMaskIn does not contain any bits set that "
1228*35238bceSAndroid Build Coastguard Worker            "are have been killed by SAMPLE_MASK state. Expecting:\n"
1229*35238bceSAndroid Build Coastguard Worker         << "    1) With multisample targets: gl_SampleMaskIn AND ~(SAMPLE_MASK) should be zero.\n"
1230*35238bceSAndroid Build Coastguard Worker         << "    2) With non-multisample targets: SAMPLE_MASK state is only ANDed as a multisample operation. "
1231*35238bceSAndroid Build Coastguard Worker            "gl_SampleMaskIn should only have its last bit set regardless of SAMPLE_MASK state.\n"
1232*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::EndMessage;
1233*35238bceSAndroid Build Coastguard Worker 
1234*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::init();
1235*35238bceSAndroid Build Coastguard Worker }
1236*35238bceSAndroid Build Coastguard Worker 
preDraw(void)1237*35238bceSAndroid Build Coastguard Worker void SampleMaskCase::preDraw(void)
1238*35238bceSAndroid Build Coastguard Worker {
1239*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl     = m_context.getRenderContext().getFunctions();
1240*35238bceSAndroid Build Coastguard Worker     const bool multisampleTarget = (m_numRequestedSamples > 0) || (m_renderTarget == TARGET_DEFAULT &&
1241*35238bceSAndroid Build Coastguard Worker                                                                    m_context.getRenderTarget().getNumSamples() > 1);
1242*35238bceSAndroid Build Coastguard Worker     const uint32_t fullMask      = (uint32_t)0xAAAAAAAAUL;
1243*35238bceSAndroid Build Coastguard Worker     const uint32_t maskMask      = (1U << m_numTargetSamples) - 1;
1244*35238bceSAndroid Build Coastguard Worker     const uint32_t effectiveMask = fullMask & maskMask;
1245*35238bceSAndroid Build Coastguard Worker 
1246*35238bceSAndroid Build Coastguard Worker     // set test mask
1247*35238bceSAndroid Build Coastguard Worker     gl.enable(GL_SAMPLE_MASK);
1248*35238bceSAndroid Build Coastguard Worker     gl.sampleMaski(0, effectiveMask);
1249*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "set mask");
1250*35238bceSAndroid Build Coastguard Worker 
1251*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Setting sample mask " << tcu::Format::Hex<4>(effectiveMask)
1252*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
1253*35238bceSAndroid Build Coastguard Worker 
1254*35238bceSAndroid Build Coastguard Worker     // set multisample case uniforms
1255*35238bceSAndroid Build Coastguard Worker     if (multisampleTarget)
1256*35238bceSAndroid Build Coastguard Worker     {
1257*35238bceSAndroid Build Coastguard Worker         const int maskLoc = gl.getUniformLocation(m_program->getProgram(), "u_sampleMask");
1258*35238bceSAndroid Build Coastguard Worker         if (maskLoc == -1)
1259*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Location of u_mask was -1");
1260*35238bceSAndroid Build Coastguard Worker 
1261*35238bceSAndroid Build Coastguard Worker         gl.uniform1ui(maskLoc, effectiveMask);
1262*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set mask uniform");
1263*35238bceSAndroid Build Coastguard Worker     }
1264*35238bceSAndroid Build Coastguard Worker 
1265*35238bceSAndroid Build Coastguard Worker     // base class logic
1266*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::preDraw();
1267*35238bceSAndroid Build Coastguard Worker }
1268*35238bceSAndroid Build Coastguard Worker 
postDraw(void)1269*35238bceSAndroid Build Coastguard Worker void SampleMaskCase::postDraw(void)
1270*35238bceSAndroid Build Coastguard Worker {
1271*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1272*35238bceSAndroid Build Coastguard Worker     const uint32_t fullMask  = (1U << m_numTargetSamples) - 1;
1273*35238bceSAndroid Build Coastguard Worker 
1274*35238bceSAndroid Build Coastguard Worker     gl.disable(GL_SAMPLE_MASK);
1275*35238bceSAndroid Build Coastguard Worker     gl.sampleMaski(0, fullMask);
1276*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "set mask");
1277*35238bceSAndroid Build Coastguard Worker 
1278*35238bceSAndroid Build Coastguard Worker     // base class logic
1279*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::postDraw();
1280*35238bceSAndroid Build Coastguard Worker }
1281*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const1282*35238bceSAndroid Build Coastguard Worker std::string SampleMaskCase::genFragmentSource(int numTargetSamples) const
1283*35238bceSAndroid Build Coastguard Worker {
1284*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numTargetSamples != 0);
1285*35238bceSAndroid Build Coastguard Worker 
1286*35238bceSAndroid Build Coastguard Worker     const bool multisampleTarget = (m_numRequestedSamples > 0) || (m_renderTarget == TARGET_DEFAULT &&
1287*35238bceSAndroid Build Coastguard Worker                                                                    m_context.getRenderTarget().getNumSamples() > 1);
1288*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1289*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
1290*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
1291*35238bceSAndroid Build Coastguard Worker         contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
1292*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
1293*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = supportsES32orGL45 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
1294*35238bceSAndroid Build Coastguard Worker                                                      getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1295*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = supportsES32orGL45 ? "" : "#extension GL_OES_sample_variables : require";
1296*35238bceSAndroid Build Coastguard Worker 
1297*35238bceSAndroid Build Coastguard Worker     // test supports only one sample mask word
1298*35238bceSAndroid Build Coastguard Worker     if (numTargetSamples > 32)
1299*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Sample count larger than 32 is not supported.");
1300*35238bceSAndroid Build Coastguard Worker 
1301*35238bceSAndroid Build Coastguard Worker     if (multisampleTarget)
1302*35238bceSAndroid Build Coastguard Worker     {
1303*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_VERSION_DECL}\n"
1304*35238bceSAndroid Build Coastguard Worker                "${GLSL_EXTENSION}\n"
1305*35238bceSAndroid Build Coastguard Worker                "layout(location = 0) out mediump vec4 fragColor;\n"
1306*35238bceSAndroid Build Coastguard Worker                "uniform highp uint u_sampleMask;\n"
1307*35238bceSAndroid Build Coastguard Worker                "void main (void)\n"
1308*35238bceSAndroid Build Coastguard Worker                "{\n"
1309*35238bceSAndroid Build Coastguard Worker                "    if ((uint(gl_SampleMaskIn[0]) & (~u_sampleMask)) != 0u)\n"
1310*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
1311*35238bceSAndroid Build Coastguard Worker                "    else\n"
1312*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
1313*35238bceSAndroid Build Coastguard Worker                "}\n";
1314*35238bceSAndroid Build Coastguard Worker     }
1315*35238bceSAndroid Build Coastguard Worker     else
1316*35238bceSAndroid Build Coastguard Worker     {
1317*35238bceSAndroid Build Coastguard Worker         // non-multisample targets don't get multisample operations like ANDing with mask
1318*35238bceSAndroid Build Coastguard Worker 
1319*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_VERSION_DECL}\n"
1320*35238bceSAndroid Build Coastguard Worker                "${GLSL_EXTENSION}\n"
1321*35238bceSAndroid Build Coastguard Worker                "layout(location = 0) out mediump vec4 fragColor;\n"
1322*35238bceSAndroid Build Coastguard Worker                "uniform highp uint u_sampleMask;\n"
1323*35238bceSAndroid Build Coastguard Worker                "void main (void)\n"
1324*35238bceSAndroid Build Coastguard Worker                "{\n"
1325*35238bceSAndroid Build Coastguard Worker                "    if (gl_SampleMaskIn[0] != 1)\n"
1326*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
1327*35238bceSAndroid Build Coastguard Worker                "    else\n"
1328*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
1329*35238bceSAndroid Build Coastguard Worker                "}\n";
1330*35238bceSAndroid Build Coastguard Worker     }
1331*35238bceSAndroid Build Coastguard Worker 
1332*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
1333*35238bceSAndroid Build Coastguard Worker }
1334*35238bceSAndroid Build Coastguard Worker 
1335*35238bceSAndroid Build Coastguard Worker class SampleMaskCountCase : public SampleMaskBaseCase
1336*35238bceSAndroid Build Coastguard Worker {
1337*35238bceSAndroid Build Coastguard Worker public:
1338*35238bceSAndroid Build Coastguard Worker     SampleMaskCountCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target,
1339*35238bceSAndroid Build Coastguard Worker                         ShaderRunMode runMode);
1340*35238bceSAndroid Build Coastguard Worker     ~SampleMaskCountCase(void);
1341*35238bceSAndroid Build Coastguard Worker 
1342*35238bceSAndroid Build Coastguard Worker     void init(void);
1343*35238bceSAndroid Build Coastguard Worker     void preDraw(void);
1344*35238bceSAndroid Build Coastguard Worker     void postDraw(void);
1345*35238bceSAndroid Build Coastguard Worker 
1346*35238bceSAndroid Build Coastguard Worker private:
1347*35238bceSAndroid Build Coastguard Worker     enum
1348*35238bceSAndroid Build Coastguard Worker     {
1349*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
1350*35238bceSAndroid Build Coastguard Worker     };
1351*35238bceSAndroid Build Coastguard Worker 
1352*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
1353*35238bceSAndroid Build Coastguard Worker };
1354*35238bceSAndroid Build Coastguard Worker 
SampleMaskCountCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target,ShaderRunMode runMode)1355*35238bceSAndroid Build Coastguard Worker SampleMaskCountCase::SampleMaskCountCase(Context &context, const char *name, const char *desc, int sampleCount,
1356*35238bceSAndroid Build Coastguard Worker                                          RenderTarget target, ShaderRunMode runMode)
1357*35238bceSAndroid Build Coastguard Worker     : SampleMaskBaseCase(context, name, desc, sampleCount, target, RENDER_SIZE, runMode)
1358*35238bceSAndroid Build Coastguard Worker {
1359*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(runMode < RUN_LAST);
1360*35238bceSAndroid Build Coastguard Worker }
1361*35238bceSAndroid Build Coastguard Worker 
~SampleMaskCountCase(void)1362*35238bceSAndroid Build Coastguard Worker SampleMaskCountCase::~SampleMaskCountCase(void)
1363*35238bceSAndroid Build Coastguard Worker {
1364*35238bceSAndroid Build Coastguard Worker }
1365*35238bceSAndroid Build Coastguard Worker 
init(void)1366*35238bceSAndroid Build Coastguard Worker void SampleMaskCountCase::init(void)
1367*35238bceSAndroid Build Coastguard Worker {
1368*35238bceSAndroid Build Coastguard Worker     // log the test method and expectations
1369*35238bceSAndroid Build Coastguard Worker     if (m_runMode == RUN_PER_PIXEL)
1370*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying gl_SampleMaskIn.\n"
1371*35238bceSAndroid Build Coastguard Worker                            << "    Fragment shader may be invoked [1, numSamples] times.\n"
1372*35238bceSAndroid Build Coastguard Worker                            << " => gl_SampleMaskIn should have the number of bits set in range [1, numSamples]\n"
1373*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1374*35238bceSAndroid Build Coastguard Worker     else if (m_runMode == RUN_PER_SAMPLE)
1375*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying gl_SampleMaskIn.\n"
1376*35238bceSAndroid Build Coastguard Worker                            << "    Fragment will be invoked numSamples times.\n"
1377*35238bceSAndroid Build Coastguard Worker                            << " => gl_SampleMaskIn should have only one bit set.\n"
1378*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1379*35238bceSAndroid Build Coastguard Worker     else if (m_runMode == RUN_PER_TWO_SAMPLES)
1380*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying gl_SampleMaskIn.\n"
1381*35238bceSAndroid Build Coastguard Worker                            << "    Fragment shader may be invoked [ceil(numSamples/2), numSamples] times.\n"
1382*35238bceSAndroid Build Coastguard Worker                            << " => gl_SampleMaskIn should have the number of bits set in range [1, numSamples - "
1383*35238bceSAndroid Build Coastguard Worker                               "ceil(numSamples/2) + 1]:\n"
1384*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1385*35238bceSAndroid Build Coastguard Worker     else
1386*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1387*35238bceSAndroid Build Coastguard Worker 
1388*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::init();
1389*35238bceSAndroid Build Coastguard Worker }
1390*35238bceSAndroid Build Coastguard Worker 
preDraw(void)1391*35238bceSAndroid Build Coastguard Worker void SampleMaskCountCase::preDraw(void)
1392*35238bceSAndroid Build Coastguard Worker {
1393*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1394*35238bceSAndroid Build Coastguard Worker 
1395*35238bceSAndroid Build Coastguard Worker     if (m_runMode == RUN_PER_PIXEL)
1396*35238bceSAndroid Build Coastguard Worker     {
1397*35238bceSAndroid Build Coastguard Worker         const int maxLoc      = gl.getUniformLocation(m_program->getProgram(), "u_maxBitCount");
1398*35238bceSAndroid Build Coastguard Worker         const int minLoc      = gl.getUniformLocation(m_program->getProgram(), "u_minBitCount");
1399*35238bceSAndroid Build Coastguard Worker         const int minBitCount = 1;
1400*35238bceSAndroid Build Coastguard Worker         const int maxBitCount = m_numTargetSamples;
1401*35238bceSAndroid Build Coastguard Worker 
1402*35238bceSAndroid Build Coastguard Worker         if (maxLoc == -1)
1403*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Location of u_maxBitCount was -1");
1404*35238bceSAndroid Build Coastguard Worker         if (minLoc == -1)
1405*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Location of u_minBitCount was -1");
1406*35238bceSAndroid Build Coastguard Worker 
1407*35238bceSAndroid Build Coastguard Worker         gl.uniform1i(minLoc, minBitCount);
1408*35238bceSAndroid Build Coastguard Worker         gl.uniform1i(maxLoc, maxBitCount);
1409*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set limits");
1410*35238bceSAndroid Build Coastguard Worker 
1411*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Setting minBitCount = " << minBitCount
1412*35238bceSAndroid Build Coastguard Worker                            << ", maxBitCount = " << maxBitCount << tcu::TestLog::EndMessage;
1413*35238bceSAndroid Build Coastguard Worker     }
1414*35238bceSAndroid Build Coastguard Worker     else if (m_runMode == RUN_PER_TWO_SAMPLES)
1415*35238bceSAndroid Build Coastguard Worker     {
1416*35238bceSAndroid Build Coastguard Worker         const int maxLoc = gl.getUniformLocation(m_program->getProgram(), "u_maxBitCount");
1417*35238bceSAndroid Build Coastguard Worker         const int minLoc = gl.getUniformLocation(m_program->getProgram(), "u_minBitCount");
1418*35238bceSAndroid Build Coastguard Worker 
1419*35238bceSAndroid Build Coastguard Worker         // Worst case: all but one shader invocations get one sample, one shader invocation the rest of the samples
1420*35238bceSAndroid Build Coastguard Worker         const int minInvocationCount = ((m_numTargetSamples + 1) / 2);
1421*35238bceSAndroid Build Coastguard Worker         const int minBitCount        = 1;
1422*35238bceSAndroid Build Coastguard Worker         const int maxBitCount        = m_numTargetSamples - ((minInvocationCount - 1) * minBitCount);
1423*35238bceSAndroid Build Coastguard Worker 
1424*35238bceSAndroid Build Coastguard Worker         if (maxLoc == -1)
1425*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Location of u_maxBitCount was -1");
1426*35238bceSAndroid Build Coastguard Worker         if (minLoc == -1)
1427*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Location of u_minBitCount was -1");
1428*35238bceSAndroid Build Coastguard Worker 
1429*35238bceSAndroid Build Coastguard Worker         gl.uniform1i(minLoc, minBitCount);
1430*35238bceSAndroid Build Coastguard Worker         gl.uniform1i(maxLoc, maxBitCount);
1431*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set limits");
1432*35238bceSAndroid Build Coastguard Worker 
1433*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Setting minBitCount = " << minBitCount
1434*35238bceSAndroid Build Coastguard Worker                            << ", maxBitCount = " << maxBitCount << tcu::TestLog::EndMessage;
1435*35238bceSAndroid Build Coastguard Worker     }
1436*35238bceSAndroid Build Coastguard Worker 
1437*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::preDraw();
1438*35238bceSAndroid Build Coastguard Worker }
1439*35238bceSAndroid Build Coastguard Worker 
postDraw(void)1440*35238bceSAndroid Build Coastguard Worker void SampleMaskCountCase::postDraw(void)
1441*35238bceSAndroid Build Coastguard Worker {
1442*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::postDraw();
1443*35238bceSAndroid Build Coastguard Worker }
1444*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const1445*35238bceSAndroid Build Coastguard Worker std::string SampleMaskCountCase::genFragmentSource(int numTargetSamples) const
1446*35238bceSAndroid Build Coastguard Worker {
1447*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numTargetSamples != 0);
1448*35238bceSAndroid Build Coastguard Worker 
1449*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1450*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
1451*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
1452*35238bceSAndroid Build Coastguard Worker         contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
1453*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
1454*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = supportsES32orGL45 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
1455*35238bceSAndroid Build Coastguard Worker                                                      getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1456*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = supportsES32orGL45 ? "" : "#extension GL_OES_sample_variables : require";
1457*35238bceSAndroid Build Coastguard Worker 
1458*35238bceSAndroid Build Coastguard Worker     // test supports only one sample mask word
1459*35238bceSAndroid Build Coastguard Worker     if (numTargetSamples > 32)
1460*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Sample count larger than 32 is not supported.");
1461*35238bceSAndroid Build Coastguard Worker 
1462*35238bceSAndroid Build Coastguard Worker     // count the number of the bits in gl_SampleMask
1463*35238bceSAndroid Build Coastguard Worker 
1464*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1465*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXTENSION}\n"
1466*35238bceSAndroid Build Coastguard Worker            "layout(location = 0) out mediump vec4 fragColor;\n";
1467*35238bceSAndroid Build Coastguard Worker 
1468*35238bceSAndroid Build Coastguard Worker     if (m_runMode != RUN_PER_SAMPLE)
1469*35238bceSAndroid Build Coastguard Worker         buf << "uniform highp int u_minBitCount;\n"
1470*35238bceSAndroid Build Coastguard Worker                "uniform highp int u_maxBitCount;\n";
1471*35238bceSAndroid Build Coastguard Worker 
1472*35238bceSAndroid Build Coastguard Worker     buf << "void main (void)\n"
1473*35238bceSAndroid Build Coastguard Worker            "{\n"
1474*35238bceSAndroid Build Coastguard Worker            "    mediump int maskBitCount = 0;\n"
1475*35238bceSAndroid Build Coastguard Worker            "    for (int i = 0; i < 32; ++i)\n"
1476*35238bceSAndroid Build Coastguard Worker            "        if (((gl_SampleMaskIn[0] >> i) & 0x01) == 0x01)\n"
1477*35238bceSAndroid Build Coastguard Worker            "            ++maskBitCount;\n"
1478*35238bceSAndroid Build Coastguard Worker            "\n";
1479*35238bceSAndroid Build Coastguard Worker 
1480*35238bceSAndroid Build Coastguard Worker     if (m_runMode == RUN_PER_SAMPLE)
1481*35238bceSAndroid Build Coastguard Worker     {
1482*35238bceSAndroid Build Coastguard Worker         // check the validity here
1483*35238bceSAndroid Build Coastguard Worker         buf << "    // force per-sample shading\n"
1484*35238bceSAndroid Build Coastguard Worker                "    highp float blue = float(gl_SampleID);\n"
1485*35238bceSAndroid Build Coastguard Worker                "\n"
1486*35238bceSAndroid Build Coastguard Worker                "    if (maskBitCount != 1)\n"
1487*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(1.0, 0.0, blue, 1.0);\n"
1488*35238bceSAndroid Build Coastguard Worker                "    else\n"
1489*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(0.0, 1.0, blue, 1.0);\n"
1490*35238bceSAndroid Build Coastguard Worker                "}\n";
1491*35238bceSAndroid Build Coastguard Worker     }
1492*35238bceSAndroid Build Coastguard Worker     else
1493*35238bceSAndroid Build Coastguard Worker     {
1494*35238bceSAndroid Build Coastguard Worker         // check the validity here
1495*35238bceSAndroid Build Coastguard Worker         buf << "    if (maskBitCount < u_minBitCount || maskBitCount > u_maxBitCount)\n"
1496*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
1497*35238bceSAndroid Build Coastguard Worker                "    else\n"
1498*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
1499*35238bceSAndroid Build Coastguard Worker                "}\n";
1500*35238bceSAndroid Build Coastguard Worker     }
1501*35238bceSAndroid Build Coastguard Worker 
1502*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
1503*35238bceSAndroid Build Coastguard Worker }
1504*35238bceSAndroid Build Coastguard Worker 
1505*35238bceSAndroid Build Coastguard Worker class SampleMaskUniqueCase : public SampleMaskBaseCase
1506*35238bceSAndroid Build Coastguard Worker {
1507*35238bceSAndroid Build Coastguard Worker public:
1508*35238bceSAndroid Build Coastguard Worker     SampleMaskUniqueCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target,
1509*35238bceSAndroid Build Coastguard Worker                          ShaderRunMode runMode);
1510*35238bceSAndroid Build Coastguard Worker     ~SampleMaskUniqueCase(void);
1511*35238bceSAndroid Build Coastguard Worker 
1512*35238bceSAndroid Build Coastguard Worker     void init(void);
1513*35238bceSAndroid Build Coastguard Worker 
1514*35238bceSAndroid Build Coastguard Worker private:
1515*35238bceSAndroid Build Coastguard Worker     enum
1516*35238bceSAndroid Build Coastguard Worker     {
1517*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
1518*35238bceSAndroid Build Coastguard Worker     };
1519*35238bceSAndroid Build Coastguard Worker 
1520*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
1521*35238bceSAndroid Build Coastguard Worker     bool verifySampleBuffers(const std::vector<tcu::Surface> &resultBuffers);
1522*35238bceSAndroid Build Coastguard Worker };
1523*35238bceSAndroid Build Coastguard Worker 
SampleMaskUniqueCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target,ShaderRunMode runMode)1524*35238bceSAndroid Build Coastguard Worker SampleMaskUniqueCase::SampleMaskUniqueCase(Context &context, const char *name, const char *desc, int sampleCount,
1525*35238bceSAndroid Build Coastguard Worker                                            RenderTarget target, ShaderRunMode runMode)
1526*35238bceSAndroid Build Coastguard Worker     : SampleMaskBaseCase(context, name, desc, sampleCount, target, RENDER_SIZE, runMode,
1527*35238bceSAndroid Build Coastguard Worker                          MultisampleShaderRenderUtil::MultisampleRenderCase::FLAG_VERIFY_MSAA_TEXTURE_SAMPLE_BUFFERS)
1528*35238bceSAndroid Build Coastguard Worker {
1529*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(runMode == RUN_PER_SAMPLE);
1530*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(target == TARGET_TEXTURE);
1531*35238bceSAndroid Build Coastguard Worker }
1532*35238bceSAndroid Build Coastguard Worker 
~SampleMaskUniqueCase(void)1533*35238bceSAndroid Build Coastguard Worker SampleMaskUniqueCase::~SampleMaskUniqueCase(void)
1534*35238bceSAndroid Build Coastguard Worker {
1535*35238bceSAndroid Build Coastguard Worker }
1536*35238bceSAndroid Build Coastguard Worker 
init(void)1537*35238bceSAndroid Build Coastguard Worker void SampleMaskUniqueCase::init(void)
1538*35238bceSAndroid Build Coastguard Worker {
1539*35238bceSAndroid Build Coastguard Worker     // log the test method and expectations
1540*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog()
1541*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Message << "Verifying gl_SampleMaskIn.\n"
1542*35238bceSAndroid Build Coastguard Worker         << "    Fragment will be invoked numSamples times.\n"
1543*35238bceSAndroid Build Coastguard Worker         << " => gl_SampleMaskIn should have only one bit set\n"
1544*35238bceSAndroid Build Coastguard Worker         << " => and that bit index should be unique within other fragment shader invocations of that pixel.\n"
1545*35238bceSAndroid Build Coastguard Worker         << "    Writing sampleMask bit index to green channel in render shader. Verifying uniqueness in sampler "
1546*35238bceSAndroid Build Coastguard Worker            "shader.\n"
1547*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::EndMessage;
1548*35238bceSAndroid Build Coastguard Worker 
1549*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::init();
1550*35238bceSAndroid Build Coastguard Worker }
1551*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const1552*35238bceSAndroid Build Coastguard Worker std::string SampleMaskUniqueCase::genFragmentSource(int numTargetSamples) const
1553*35238bceSAndroid Build Coastguard Worker {
1554*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numTargetSamples != 0);
1555*35238bceSAndroid Build Coastguard Worker 
1556*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1557*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
1558*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
1559*35238bceSAndroid Build Coastguard Worker         contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
1560*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
1561*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = supportsES32orGL45 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
1562*35238bceSAndroid Build Coastguard Worker                                                      getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1563*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = supportsES32orGL45 ? "" : "#extension GL_OES_sample_variables : require";
1564*35238bceSAndroid Build Coastguard Worker 
1565*35238bceSAndroid Build Coastguard Worker     // test supports only one sample mask word
1566*35238bceSAndroid Build Coastguard Worker     if (numTargetSamples > 32)
1567*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Sample count larger than 32 is not supported.");
1568*35238bceSAndroid Build Coastguard Worker 
1569*35238bceSAndroid Build Coastguard Worker     // find our sampleID by searching for unique bit.
1570*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1571*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXTENSION}\n"
1572*35238bceSAndroid Build Coastguard Worker            "layout(location = 0) out mediump vec4 fragColor;\n"
1573*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1574*35238bceSAndroid Build Coastguard Worker            "{\n"
1575*35238bceSAndroid Build Coastguard Worker            "    mediump int firstIndex = -1;\n"
1576*35238bceSAndroid Build Coastguard Worker            "    for (int i = 0; i < 32; ++i)\n"
1577*35238bceSAndroid Build Coastguard Worker            "    {\n"
1578*35238bceSAndroid Build Coastguard Worker            "        if (((gl_SampleMaskIn[0] >> i) & 0x01) == 0x01)\n"
1579*35238bceSAndroid Build Coastguard Worker            "        {\n"
1580*35238bceSAndroid Build Coastguard Worker            "            firstIndex = i;\n"
1581*35238bceSAndroid Build Coastguard Worker            "            break;\n"
1582*35238bceSAndroid Build Coastguard Worker            "        }\n"
1583*35238bceSAndroid Build Coastguard Worker            "    }\n"
1584*35238bceSAndroid Build Coastguard Worker            "\n"
1585*35238bceSAndroid Build Coastguard Worker            "    bool notUniqueError = false;\n"
1586*35238bceSAndroid Build Coastguard Worker            "    for (int i = firstIndex + 1; i < 32; ++i)\n"
1587*35238bceSAndroid Build Coastguard Worker            "        if (((gl_SampleMaskIn[0] >> i) & 0x01) == 0x01)\n"
1588*35238bceSAndroid Build Coastguard Worker            "            notUniqueError = true;\n"
1589*35238bceSAndroid Build Coastguard Worker            "\n"
1590*35238bceSAndroid Build Coastguard Worker            "    highp float encodedSampleId = float(firstIndex) / "
1591*35238bceSAndroid Build Coastguard Worker         << numTargetSamples
1592*35238bceSAndroid Build Coastguard Worker         << ".0;\n"
1593*35238bceSAndroid Build Coastguard Worker            "\n"
1594*35238bceSAndroid Build Coastguard Worker            "    // force per-sample shading\n"
1595*35238bceSAndroid Build Coastguard Worker            "    highp float blue = float(gl_SampleID);\n"
1596*35238bceSAndroid Build Coastguard Worker            "\n"
1597*35238bceSAndroid Build Coastguard Worker            "    if (notUniqueError)\n"
1598*35238bceSAndroid Build Coastguard Worker            "        fragColor = vec4(1.0, 0.0, blue, 1.0);\n"
1599*35238bceSAndroid Build Coastguard Worker            "    else\n"
1600*35238bceSAndroid Build Coastguard Worker            "        fragColor = vec4(0.0, encodedSampleId, blue, 1.0);\n"
1601*35238bceSAndroid Build Coastguard Worker            "}\n";
1602*35238bceSAndroid Build Coastguard Worker 
1603*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
1604*35238bceSAndroid Build Coastguard Worker }
1605*35238bceSAndroid Build Coastguard Worker 
verifySampleBuffers(const std::vector<tcu::Surface> & resultBuffers)1606*35238bceSAndroid Build Coastguard Worker bool SampleMaskUniqueCase::verifySampleBuffers(const std::vector<tcu::Surface> &resultBuffers)
1607*35238bceSAndroid Build Coastguard Worker {
1608*35238bceSAndroid Build Coastguard Worker     const int width  = resultBuffers[0].getWidth();
1609*35238bceSAndroid Build Coastguard Worker     const int height = resultBuffers[0].getHeight();
1610*35238bceSAndroid Build Coastguard Worker     bool allOk       = true;
1611*35238bceSAndroid Build Coastguard Worker 
1612*35238bceSAndroid Build Coastguard Worker     // Log samples
1613*35238bceSAndroid Build Coastguard Worker     {
1614*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::ImageSet("SampleBuffers", "Image sample buffers");
1615*35238bceSAndroid Build Coastguard Worker         for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
1616*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Image("Buffer" + de::toString(sampleNdx),
1617*35238bceSAndroid Build Coastguard Worker                                                       "Sample " + de::toString(sampleNdx),
1618*35238bceSAndroid Build Coastguard Worker                                                       resultBuffers[sampleNdx].getAccess());
1619*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1620*35238bceSAndroid Build Coastguard Worker     }
1621*35238bceSAndroid Build Coastguard Worker 
1622*35238bceSAndroid Build Coastguard Worker     // check for earlier errors (in fragment shader)
1623*35238bceSAndroid Build Coastguard Worker     {
1624*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
1625*35238bceSAndroid Build Coastguard Worker                            << "Verifying fragment shader invocation found only one set sample mask bit."
1626*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1627*35238bceSAndroid Build Coastguard Worker 
1628*35238bceSAndroid Build Coastguard Worker         for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
1629*35238bceSAndroid Build Coastguard Worker         {
1630*35238bceSAndroid Build Coastguard Worker             // shader does the check, just check the shader error output (red)
1631*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Verifying sample " << (sampleNdx + 1) << "/"
1632*35238bceSAndroid Build Coastguard Worker                                << (int)resultBuffers.size() << tcu::TestLog::EndMessage;
1633*35238bceSAndroid Build Coastguard Worker             allOk &= verifyImageWithVerifier(resultBuffers[sampleNdx], m_testCtx.getLog(), NoRedVerifier(), false);
1634*35238bceSAndroid Build Coastguard Worker         }
1635*35238bceSAndroid Build Coastguard Worker 
1636*35238bceSAndroid Build Coastguard Worker         if (!allOk)
1637*35238bceSAndroid Build Coastguard Worker         {
1638*35238bceSAndroid Build Coastguard Worker             // can't check the uniqueness if the masks don't work at all
1639*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog()
1640*35238bceSAndroid Build Coastguard Worker                 << tcu::TestLog::Message
1641*35238bceSAndroid Build Coastguard Worker                 << "Could not get mask information from the rendered image, cannot continue verification."
1642*35238bceSAndroid Build Coastguard Worker                 << tcu::TestLog::EndMessage;
1643*35238bceSAndroid Build Coastguard Worker             return false;
1644*35238bceSAndroid Build Coastguard Worker         }
1645*35238bceSAndroid Build Coastguard Worker     }
1646*35238bceSAndroid Build Coastguard Worker 
1647*35238bceSAndroid Build Coastguard Worker     // verify index / index ranges
1648*35238bceSAndroid Build Coastguard Worker 
1649*35238bceSAndroid Build Coastguard Worker     if (m_numRequestedSamples == 0)
1650*35238bceSAndroid Build Coastguard Worker     {
1651*35238bceSAndroid Build Coastguard Worker         // single sample target, expect index=0
1652*35238bceSAndroid Build Coastguard Worker 
1653*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying sample mask bit index is 0."
1654*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1655*35238bceSAndroid Build Coastguard Worker 
1656*35238bceSAndroid Build Coastguard Worker         // only check the mask index
1657*35238bceSAndroid Build Coastguard Worker         allOk &= verifyImageWithVerifier(resultBuffers[0], m_testCtx.getLog(),
1658*35238bceSAndroid Build Coastguard Worker                                          ColorVerifier(tcu::Vec3(0.0f, 0.0f, 0.0f), tcu::IVec3(255, 8, 255)), false);
1659*35238bceSAndroid Build Coastguard Worker     }
1660*35238bceSAndroid Build Coastguard Worker     else
1661*35238bceSAndroid Build Coastguard Worker     {
1662*35238bceSAndroid Build Coastguard Worker         // check uniqueness
1663*35238bceSAndroid Build Coastguard Worker 
1664*35238bceSAndroid Build Coastguard Worker         tcu::Surface errorMask(width, height);
1665*35238bceSAndroid Build Coastguard Worker         bool uniquenessOk         = true;
1666*35238bceSAndroid Build Coastguard Worker         int printCount            = 0;
1667*35238bceSAndroid Build Coastguard Worker         const int printFloodLimit = 5;
1668*35238bceSAndroid Build Coastguard Worker         std::vector<int> maskBitIndices(resultBuffers.size());
1669*35238bceSAndroid Build Coastguard Worker 
1670*35238bceSAndroid Build Coastguard Worker         tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
1671*35238bceSAndroid Build Coastguard Worker 
1672*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying per-invocation sample mask bit is unique."
1673*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1674*35238bceSAndroid Build Coastguard Worker 
1675*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < height; ++y)
1676*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < width; ++x)
1677*35238bceSAndroid Build Coastguard Worker             {
1678*35238bceSAndroid Build Coastguard Worker                 bool maskNdxNotUnique = false;
1679*35238bceSAndroid Build Coastguard Worker 
1680*35238bceSAndroid Build Coastguard Worker                 // decode index
1681*35238bceSAndroid Build Coastguard Worker                 for (int sampleNdx = 0; sampleNdx < (int)resultBuffers.size(); ++sampleNdx)
1682*35238bceSAndroid Build Coastguard Worker                 {
1683*35238bceSAndroid Build Coastguard Worker                     const tcu::RGBA color = resultBuffers[sampleNdx].getPixel(x, y);
1684*35238bceSAndroid Build Coastguard Worker                     maskBitIndices[sampleNdx] =
1685*35238bceSAndroid Build Coastguard Worker                         (int)deFloatRound((float)color.getGreen() / 255.0f * (float)m_numTargetSamples);
1686*35238bceSAndroid Build Coastguard Worker                 }
1687*35238bceSAndroid Build Coastguard Worker 
1688*35238bceSAndroid Build Coastguard Worker                 // just check there are no two invocations with the same bit index
1689*35238bceSAndroid Build Coastguard Worker                 for (int sampleNdxA = 0;
1690*35238bceSAndroid Build Coastguard Worker                      sampleNdxA < (int)resultBuffers.size() && (!maskNdxNotUnique || printCount < printFloodLimit);
1691*35238bceSAndroid Build Coastguard Worker                      ++sampleNdxA)
1692*35238bceSAndroid Build Coastguard Worker                     for (int sampleNdxB = sampleNdxA + 1;
1693*35238bceSAndroid Build Coastguard Worker                          sampleNdxB < (int)resultBuffers.size() && (!maskNdxNotUnique || printCount < printFloodLimit);
1694*35238bceSAndroid Build Coastguard Worker                          ++sampleNdxB)
1695*35238bceSAndroid Build Coastguard Worker                     {
1696*35238bceSAndroid Build Coastguard Worker                         if (maskBitIndices[sampleNdxA] == maskBitIndices[sampleNdxB])
1697*35238bceSAndroid Build Coastguard Worker                         {
1698*35238bceSAndroid Build Coastguard Worker                             if (++printCount <= printFloodLimit)
1699*35238bceSAndroid Build Coastguard Worker                             {
1700*35238bceSAndroid Build Coastguard Worker                                 m_testCtx.getLog() << tcu::TestLog::Message << "Pixel (" << x << ", " << y
1701*35238bceSAndroid Build Coastguard Worker                                                    << "): Samples " << sampleNdxA << " and " << sampleNdxB
1702*35238bceSAndroid Build Coastguard Worker                                                    << " have the same sample mask. (Single bit at index "
1703*35238bceSAndroid Build Coastguard Worker                                                    << maskBitIndices[sampleNdxA] << ")" << tcu::TestLog::EndMessage;
1704*35238bceSAndroid Build Coastguard Worker                             }
1705*35238bceSAndroid Build Coastguard Worker 
1706*35238bceSAndroid Build Coastguard Worker                             maskNdxNotUnique = true;
1707*35238bceSAndroid Build Coastguard Worker                             uniquenessOk     = false;
1708*35238bceSAndroid Build Coastguard Worker                             errorMask.setPixel(x, y, tcu::RGBA::red());
1709*35238bceSAndroid Build Coastguard Worker                         }
1710*35238bceSAndroid Build Coastguard Worker                     }
1711*35238bceSAndroid Build Coastguard Worker             }
1712*35238bceSAndroid Build Coastguard Worker 
1713*35238bceSAndroid Build Coastguard Worker         // end result
1714*35238bceSAndroid Build Coastguard Worker         if (!uniquenessOk)
1715*35238bceSAndroid Build Coastguard Worker         {
1716*35238bceSAndroid Build Coastguard Worker             if (printCount > printFloodLimit)
1717*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "...\n"
1718*35238bceSAndroid Build Coastguard Worker                                    << "Omitted " << (printCount - printFloodLimit) << " error descriptions."
1719*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1720*35238bceSAndroid Build Coastguard Worker 
1721*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
1722*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::ImageSet("Verification", "Image Verification")
1723*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("ErrorMask", "Error Mask", errorMask.getAccess())
1724*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndImageSet;
1725*35238bceSAndroid Build Coastguard Worker 
1726*35238bceSAndroid Build Coastguard Worker             allOk = false;
1727*35238bceSAndroid Build Coastguard Worker         }
1728*35238bceSAndroid Build Coastguard Worker     }
1729*35238bceSAndroid Build Coastguard Worker 
1730*35238bceSAndroid Build Coastguard Worker     return allOk;
1731*35238bceSAndroid Build Coastguard Worker }
1732*35238bceSAndroid Build Coastguard Worker 
1733*35238bceSAndroid Build Coastguard Worker class SampleMaskUniqueSetCase : public SampleMaskBaseCase
1734*35238bceSAndroid Build Coastguard Worker {
1735*35238bceSAndroid Build Coastguard Worker public:
1736*35238bceSAndroid Build Coastguard Worker     SampleMaskUniqueSetCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target,
1737*35238bceSAndroid Build Coastguard Worker                             ShaderRunMode runMode);
1738*35238bceSAndroid Build Coastguard Worker     ~SampleMaskUniqueSetCase(void);
1739*35238bceSAndroid Build Coastguard Worker 
1740*35238bceSAndroid Build Coastguard Worker     void init(void);
1741*35238bceSAndroid Build Coastguard Worker     void deinit(void);
1742*35238bceSAndroid Build Coastguard Worker 
1743*35238bceSAndroid Build Coastguard Worker private:
1744*35238bceSAndroid Build Coastguard Worker     enum
1745*35238bceSAndroid Build Coastguard Worker     {
1746*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
1747*35238bceSAndroid Build Coastguard Worker     };
1748*35238bceSAndroid Build Coastguard Worker 
1749*35238bceSAndroid Build Coastguard Worker     void preDraw(void);
1750*35238bceSAndroid Build Coastguard Worker     void postDraw(void);
1751*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
1752*35238bceSAndroid Build Coastguard Worker     bool verifySampleBuffers(const std::vector<tcu::Surface> &resultBuffers);
1753*35238bceSAndroid Build Coastguard Worker     std::string getIterationDescription(int iteration) const;
1754*35238bceSAndroid Build Coastguard Worker 
1755*35238bceSAndroid Build Coastguard Worker     void preTest(void);
1756*35238bceSAndroid Build Coastguard Worker     void postTest(void);
1757*35238bceSAndroid Build Coastguard Worker 
1758*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Surface> m_iterationSampleBuffers;
1759*35238bceSAndroid Build Coastguard Worker };
1760*35238bceSAndroid Build Coastguard Worker 
SampleMaskUniqueSetCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target,ShaderRunMode runMode)1761*35238bceSAndroid Build Coastguard Worker SampleMaskUniqueSetCase::SampleMaskUniqueSetCase(Context &context, const char *name, const char *desc, int sampleCount,
1762*35238bceSAndroid Build Coastguard Worker                                                  RenderTarget target, ShaderRunMode runMode)
1763*35238bceSAndroid Build Coastguard Worker     : SampleMaskBaseCase(context, name, desc, sampleCount, target, RENDER_SIZE, runMode,
1764*35238bceSAndroid Build Coastguard Worker                          MultisampleShaderRenderUtil::MultisampleRenderCase::FLAG_VERIFY_MSAA_TEXTURE_SAMPLE_BUFFERS)
1765*35238bceSAndroid Build Coastguard Worker {
1766*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(runMode == RUN_PER_TWO_SAMPLES);
1767*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(target == TARGET_TEXTURE);
1768*35238bceSAndroid Build Coastguard Worker 
1769*35238bceSAndroid Build Coastguard Worker     // high and low bits
1770*35238bceSAndroid Build Coastguard Worker     m_numIterations = 2;
1771*35238bceSAndroid Build Coastguard Worker }
1772*35238bceSAndroid Build Coastguard Worker 
~SampleMaskUniqueSetCase(void)1773*35238bceSAndroid Build Coastguard Worker SampleMaskUniqueSetCase::~SampleMaskUniqueSetCase(void)
1774*35238bceSAndroid Build Coastguard Worker {
1775*35238bceSAndroid Build Coastguard Worker }
1776*35238bceSAndroid Build Coastguard Worker 
init(void)1777*35238bceSAndroid Build Coastguard Worker void SampleMaskUniqueSetCase::init(void)
1778*35238bceSAndroid Build Coastguard Worker {
1779*35238bceSAndroid Build Coastguard Worker     // log the test method and expectations
1780*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Verifying gl_SampleMaskIn.\n"
1781*35238bceSAndroid Build Coastguard Worker                        << "    Fragment shader may be invoked [ceil(numSamples/2), numSamples] times.\n"
1782*35238bceSAndroid Build Coastguard Worker                        << " => Each invocation should have unique bit set\n"
1783*35238bceSAndroid Build Coastguard Worker                        << "    Writing highest and lowest bit index to color channels in render shader. Verifying:\n"
1784*35238bceSAndroid Build Coastguard Worker                        << "        1) no other invocation contains these bits in sampler shader.\n"
1785*35238bceSAndroid Build Coastguard Worker                        << "        2) number of invocations is at least ceil(numSamples/2).\n"
1786*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
1787*35238bceSAndroid Build Coastguard Worker 
1788*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::init();
1789*35238bceSAndroid Build Coastguard Worker }
1790*35238bceSAndroid Build Coastguard Worker 
deinit(void)1791*35238bceSAndroid Build Coastguard Worker void SampleMaskUniqueSetCase::deinit(void)
1792*35238bceSAndroid Build Coastguard Worker {
1793*35238bceSAndroid Build Coastguard Worker     m_iterationSampleBuffers.clear();
1794*35238bceSAndroid Build Coastguard Worker }
1795*35238bceSAndroid Build Coastguard Worker 
preDraw(void)1796*35238bceSAndroid Build Coastguard Worker void SampleMaskUniqueSetCase::preDraw(void)
1797*35238bceSAndroid Build Coastguard Worker {
1798*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1799*35238bceSAndroid Build Coastguard Worker     const int selectorLoc    = gl.getUniformLocation(m_program->getProgram(), "u_bitSelector");
1800*35238bceSAndroid Build Coastguard Worker 
1801*35238bceSAndroid Build Coastguard Worker     gl.uniform1ui(selectorLoc, (uint32_t)m_iteration);
1802*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "set u_bitSelector");
1803*35238bceSAndroid Build Coastguard Worker 
1804*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Setting u_bitSelector = " << m_iteration
1805*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
1806*35238bceSAndroid Build Coastguard Worker 
1807*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::preDraw();
1808*35238bceSAndroid Build Coastguard Worker }
1809*35238bceSAndroid Build Coastguard Worker 
postDraw(void)1810*35238bceSAndroid Build Coastguard Worker void SampleMaskUniqueSetCase::postDraw(void)
1811*35238bceSAndroid Build Coastguard Worker {
1812*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::postDraw();
1813*35238bceSAndroid Build Coastguard Worker }
1814*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const1815*35238bceSAndroid Build Coastguard Worker std::string SampleMaskUniqueSetCase::genFragmentSource(int numTargetSamples) const
1816*35238bceSAndroid Build Coastguard Worker {
1817*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numTargetSamples != 0);
1818*35238bceSAndroid Build Coastguard Worker 
1819*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1820*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
1821*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
1822*35238bceSAndroid Build Coastguard Worker         contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
1823*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
1824*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = supportsES32orGL45 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
1825*35238bceSAndroid Build Coastguard Worker                                                      getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
1826*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = supportsES32orGL45 ? "" : "#extension GL_OES_sample_variables : require";
1827*35238bceSAndroid Build Coastguard Worker 
1828*35238bceSAndroid Build Coastguard Worker     // test supports only one sample mask word
1829*35238bceSAndroid Build Coastguard Worker     if (numTargetSamples > 32)
1830*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Sample count larger than 32 is not supported.");
1831*35238bceSAndroid Build Coastguard Worker 
1832*35238bceSAndroid Build Coastguard Worker     // output min and max sample id
1833*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1834*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXTENSION}\n"
1835*35238bceSAndroid Build Coastguard Worker            "uniform highp uint u_bitSelector;\n"
1836*35238bceSAndroid Build Coastguard Worker            "layout(location = 0) out mediump vec4 fragColor;\n"
1837*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1838*35238bceSAndroid Build Coastguard Worker            "{\n"
1839*35238bceSAndroid Build Coastguard Worker            "    highp int selectedBits;\n"
1840*35238bceSAndroid Build Coastguard Worker            "    if (u_bitSelector == 0u)\n"
1841*35238bceSAndroid Build Coastguard Worker            "        selectedBits = (gl_SampleMaskIn[0] & 0xFFFF);\n"
1842*35238bceSAndroid Build Coastguard Worker            "    else\n"
1843*35238bceSAndroid Build Coastguard Worker            "        selectedBits = ((gl_SampleMaskIn[0] >> 16) & 0xFFFF);\n"
1844*35238bceSAndroid Build Coastguard Worker            "\n"
1845*35238bceSAndroid Build Coastguard Worker            "    // encode bits to color\n"
1846*35238bceSAndroid Build Coastguard Worker            "    highp int redBits = selectedBits & 31;\n"
1847*35238bceSAndroid Build Coastguard Worker            "    highp int greenBits = (selectedBits >> 5) & 63;\n"
1848*35238bceSAndroid Build Coastguard Worker            "    highp int blueBits = (selectedBits >> 11) & 31;\n"
1849*35238bceSAndroid Build Coastguard Worker            "\n"
1850*35238bceSAndroid Build Coastguard Worker            "    fragColor = vec4(float(redBits) / float(31), float(greenBits) / float(63), float(blueBits) / "
1851*35238bceSAndroid Build Coastguard Worker            "float(31), 1.0);\n"
1852*35238bceSAndroid Build Coastguard Worker            "}\n";
1853*35238bceSAndroid Build Coastguard Worker 
1854*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
1855*35238bceSAndroid Build Coastguard Worker }
1856*35238bceSAndroid Build Coastguard Worker 
verifySampleBuffers(const std::vector<tcu::Surface> & resultBuffers)1857*35238bceSAndroid Build Coastguard Worker bool SampleMaskUniqueSetCase::verifySampleBuffers(const std::vector<tcu::Surface> &resultBuffers)
1858*35238bceSAndroid Build Coastguard Worker {
1859*35238bceSAndroid Build Coastguard Worker     // we need results from all passes to do verification. Store results and verify later (at postTest).
1860*35238bceSAndroid Build Coastguard Worker 
1861*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_numTargetSamples == (int)resultBuffers.size());
1862*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < m_numTargetSamples; ++ndx)
1863*35238bceSAndroid Build Coastguard Worker         m_iterationSampleBuffers[m_iteration * m_numTargetSamples + ndx] = resultBuffers[ndx];
1864*35238bceSAndroid Build Coastguard Worker 
1865*35238bceSAndroid Build Coastguard Worker     return true;
1866*35238bceSAndroid Build Coastguard Worker }
1867*35238bceSAndroid Build Coastguard Worker 
getIterationDescription(int iteration) const1868*35238bceSAndroid Build Coastguard Worker std::string SampleMaskUniqueSetCase::getIterationDescription(int iteration) const
1869*35238bceSAndroid Build Coastguard Worker {
1870*35238bceSAndroid Build Coastguard Worker     if (iteration == 0)
1871*35238bceSAndroid Build Coastguard Worker         return "Reading low bits";
1872*35238bceSAndroid Build Coastguard Worker     else if (iteration == 1)
1873*35238bceSAndroid Build Coastguard Worker         return "Reading high bits";
1874*35238bceSAndroid Build Coastguard Worker     else
1875*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1876*35238bceSAndroid Build Coastguard Worker     return "";
1877*35238bceSAndroid Build Coastguard Worker }
1878*35238bceSAndroid Build Coastguard Worker 
preTest(void)1879*35238bceSAndroid Build Coastguard Worker void SampleMaskUniqueSetCase::preTest(void)
1880*35238bceSAndroid Build Coastguard Worker {
1881*35238bceSAndroid Build Coastguard Worker     m_iterationSampleBuffers.resize(m_numTargetSamples * 2);
1882*35238bceSAndroid Build Coastguard Worker }
1883*35238bceSAndroid Build Coastguard Worker 
postTest(void)1884*35238bceSAndroid Build Coastguard Worker void SampleMaskUniqueSetCase::postTest(void)
1885*35238bceSAndroid Build Coastguard Worker {
1886*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((m_iterationSampleBuffers.size() % 2) == 0);
1887*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((int)m_iterationSampleBuffers.size() / 2 == m_numTargetSamples);
1888*35238bceSAndroid Build Coastguard Worker 
1889*35238bceSAndroid Build Coastguard Worker     const int width  = m_iterationSampleBuffers[0].getWidth();
1890*35238bceSAndroid Build Coastguard Worker     const int height = m_iterationSampleBuffers[0].getHeight();
1891*35238bceSAndroid Build Coastguard Worker     bool allOk       = true;
1892*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::TextureLevel> sampleCoverage(m_numTargetSamples);
1893*35238bceSAndroid Build Coastguard Worker     const tcu::ScopedLogSection section(m_testCtx.getLog(), "Verify", "Verify masks");
1894*35238bceSAndroid Build Coastguard Worker 
1895*35238bceSAndroid Build Coastguard Worker     // convert color layers to 32 bit coverage masks, 2 passes per coverage
1896*35238bceSAndroid Build Coastguard Worker 
1897*35238bceSAndroid Build Coastguard Worker     for (int sampleNdx = 0; sampleNdx < (int)sampleCoverage.size(); ++sampleNdx)
1898*35238bceSAndroid Build Coastguard Worker     {
1899*35238bceSAndroid Build Coastguard Worker         sampleCoverage[sampleNdx].setStorage(
1900*35238bceSAndroid Build Coastguard Worker             tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT32), width, height);
1901*35238bceSAndroid Build Coastguard Worker 
1902*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < height; ++y)
1903*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < width; ++x)
1904*35238bceSAndroid Build Coastguard Worker             {
1905*35238bceSAndroid Build Coastguard Worker                 const tcu::RGBA lowColor = m_iterationSampleBuffers[sampleNdx].getPixel(x, y);
1906*35238bceSAndroid Build Coastguard Worker                 const tcu::RGBA highColor =
1907*35238bceSAndroid Build Coastguard Worker                     m_iterationSampleBuffers[sampleNdx + (int)sampleCoverage.size()].getPixel(x, y);
1908*35238bceSAndroid Build Coastguard Worker                 uint16_t low;
1909*35238bceSAndroid Build Coastguard Worker                 uint16_t high;
1910*35238bceSAndroid Build Coastguard Worker 
1911*35238bceSAndroid Build Coastguard Worker                 {
1912*35238bceSAndroid Build Coastguard Worker                     int redBits   = (int)deFloatRound((float)lowColor.getRed() / 255.0f * 31);
1913*35238bceSAndroid Build Coastguard Worker                     int greenBits = (int)deFloatRound((float)lowColor.getGreen() / 255.0f * 63);
1914*35238bceSAndroid Build Coastguard Worker                     int blueBits  = (int)deFloatRound((float)lowColor.getBlue() / 255.0f * 31);
1915*35238bceSAndroid Build Coastguard Worker 
1916*35238bceSAndroid Build Coastguard Worker                     low = (uint16_t)(redBits | (greenBits << 5) | (blueBits << 11));
1917*35238bceSAndroid Build Coastguard Worker                 }
1918*35238bceSAndroid Build Coastguard Worker                 {
1919*35238bceSAndroid Build Coastguard Worker                     int redBits   = (int)deFloatRound((float)highColor.getRed() / 255.0f * 31);
1920*35238bceSAndroid Build Coastguard Worker                     int greenBits = (int)deFloatRound((float)highColor.getGreen() / 255.0f * 63);
1921*35238bceSAndroid Build Coastguard Worker                     int blueBits  = (int)deFloatRound((float)highColor.getBlue() / 255.0f * 31);
1922*35238bceSAndroid Build Coastguard Worker 
1923*35238bceSAndroid Build Coastguard Worker                     high = (uint16_t)(redBits | (greenBits << 5) | (blueBits << 11));
1924*35238bceSAndroid Build Coastguard Worker                 }
1925*35238bceSAndroid Build Coastguard Worker 
1926*35238bceSAndroid Build Coastguard Worker                 sampleCoverage[sampleNdx].getAccess().setPixel(tcu::UVec4((((uint32_t)high) << 16) | low, 0, 0, 0), x,
1927*35238bceSAndroid Build Coastguard Worker                                                                y);
1928*35238bceSAndroid Build Coastguard Worker             }
1929*35238bceSAndroid Build Coastguard Worker     }
1930*35238bceSAndroid Build Coastguard Worker 
1931*35238bceSAndroid Build Coastguard Worker     // verify masks
1932*35238bceSAndroid Build Coastguard Worker 
1933*35238bceSAndroid Build Coastguard Worker     if (m_numRequestedSamples == 0)
1934*35238bceSAndroid Build Coastguard Worker     {
1935*35238bceSAndroid Build Coastguard Worker         // single sample target, expect mask = 0x01
1936*35238bceSAndroid Build Coastguard Worker         const int printFloodLimit = 5;
1937*35238bceSAndroid Build Coastguard Worker         int printCount            = 0;
1938*35238bceSAndroid Build Coastguard Worker 
1939*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying sample mask is 0x00000001."
1940*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1941*35238bceSAndroid Build Coastguard Worker 
1942*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < height; ++y)
1943*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < width; ++x)
1944*35238bceSAndroid Build Coastguard Worker             {
1945*35238bceSAndroid Build Coastguard Worker                 uint32_t mask = sampleCoverage[0].getAccess().getPixelUint(x, y).x();
1946*35238bceSAndroid Build Coastguard Worker                 if (mask != 0x01)
1947*35238bceSAndroid Build Coastguard Worker                 {
1948*35238bceSAndroid Build Coastguard Worker                     allOk = false;
1949*35238bceSAndroid Build Coastguard Worker 
1950*35238bceSAndroid Build Coastguard Worker                     if (++printCount <= printFloodLimit)
1951*35238bceSAndroid Build Coastguard Worker                     {
1952*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog()
1953*35238bceSAndroid Build Coastguard Worker                             << tcu::TestLog::Message << "Pixel (" << x << ", " << y << "): Invalid mask, got "
1954*35238bceSAndroid Build Coastguard Worker                             << tcu::Format::Hex<8>(mask) << ", expected " << tcu::Format::Hex<8>(0x01) << "\n"
1955*35238bceSAndroid Build Coastguard Worker                             << tcu::TestLog::EndMessage;
1956*35238bceSAndroid Build Coastguard Worker                     }
1957*35238bceSAndroid Build Coastguard Worker                 }
1958*35238bceSAndroid Build Coastguard Worker             }
1959*35238bceSAndroid Build Coastguard Worker 
1960*35238bceSAndroid Build Coastguard Worker         if (!allOk && printCount > printFloodLimit)
1961*35238bceSAndroid Build Coastguard Worker         {
1962*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "...\n"
1963*35238bceSAndroid Build Coastguard Worker                                << "Omitted " << (printCount - printFloodLimit) << " error descriptions."
1964*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1965*35238bceSAndroid Build Coastguard Worker         }
1966*35238bceSAndroid Build Coastguard Worker     }
1967*35238bceSAndroid Build Coastguard Worker     else
1968*35238bceSAndroid Build Coastguard Worker     {
1969*35238bceSAndroid Build Coastguard Worker         // check uniqueness
1970*35238bceSAndroid Build Coastguard Worker         {
1971*35238bceSAndroid Build Coastguard Worker             bool uniquenessOk         = true;
1972*35238bceSAndroid Build Coastguard Worker             int printCount            = 0;
1973*35238bceSAndroid Build Coastguard Worker             const int printFloodLimit = 5;
1974*35238bceSAndroid Build Coastguard Worker 
1975*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Verifying invocation sample masks do not share bits."
1976*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1977*35238bceSAndroid Build Coastguard Worker 
1978*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < height; ++y)
1979*35238bceSAndroid Build Coastguard Worker                 for (int x = 0; x < width; ++x)
1980*35238bceSAndroid Build Coastguard Worker                 {
1981*35238bceSAndroid Build Coastguard Worker                     bool maskBitsNotUnique = false;
1982*35238bceSAndroid Build Coastguard Worker 
1983*35238bceSAndroid Build Coastguard Worker                     for (int sampleNdxA = 0;
1984*35238bceSAndroid Build Coastguard Worker                          sampleNdxA < m_numTargetSamples && (!maskBitsNotUnique || printCount < printFloodLimit);
1985*35238bceSAndroid Build Coastguard Worker                          ++sampleNdxA)
1986*35238bceSAndroid Build Coastguard Worker                         for (int sampleNdxB = sampleNdxA + 1;
1987*35238bceSAndroid Build Coastguard Worker                              sampleNdxB < m_numTargetSamples && (!maskBitsNotUnique || printCount < printFloodLimit);
1988*35238bceSAndroid Build Coastguard Worker                              ++sampleNdxB)
1989*35238bceSAndroid Build Coastguard Worker                         {
1990*35238bceSAndroid Build Coastguard Worker                             const uint32_t maskA = sampleCoverage[sampleNdxA].getAccess().getPixelUint(x, y).x();
1991*35238bceSAndroid Build Coastguard Worker                             const uint32_t maskB = sampleCoverage[sampleNdxB].getAccess().getPixelUint(x, y).x();
1992*35238bceSAndroid Build Coastguard Worker 
1993*35238bceSAndroid Build Coastguard Worker                             // equal mask == emitted by the same invocation
1994*35238bceSAndroid Build Coastguard Worker                             if (maskA != maskB)
1995*35238bceSAndroid Build Coastguard Worker                             {
1996*35238bceSAndroid Build Coastguard Worker                                 // shares samples?
1997*35238bceSAndroid Build Coastguard Worker                                 if (maskA & maskB)
1998*35238bceSAndroid Build Coastguard Worker                                 {
1999*35238bceSAndroid Build Coastguard Worker                                     maskBitsNotUnique = true;
2000*35238bceSAndroid Build Coastguard Worker                                     uniquenessOk      = false;
2001*35238bceSAndroid Build Coastguard Worker 
2002*35238bceSAndroid Build Coastguard Worker                                     if (++printCount <= printFloodLimit)
2003*35238bceSAndroid Build Coastguard Worker                                     {
2004*35238bceSAndroid Build Coastguard Worker                                         m_testCtx.getLog()
2005*35238bceSAndroid Build Coastguard Worker                                             << tcu::TestLog::Message << "Pixel (" << x << ", " << y << "):\n"
2006*35238bceSAndroid Build Coastguard Worker                                             << "\tSamples " << sampleNdxA << " and " << sampleNdxB
2007*35238bceSAndroid Build Coastguard Worker                                             << " share mask bits\n"
2008*35238bceSAndroid Build Coastguard Worker                                             << "\tMask" << sampleNdxA << " = " << tcu::Format::Hex<8>(maskA) << "\n"
2009*35238bceSAndroid Build Coastguard Worker                                             << "\tMask" << sampleNdxB << " = " << tcu::Format::Hex<8>(maskB) << "\n"
2010*35238bceSAndroid Build Coastguard Worker                                             << tcu::TestLog::EndMessage;
2011*35238bceSAndroid Build Coastguard Worker                                     }
2012*35238bceSAndroid Build Coastguard Worker                                 }
2013*35238bceSAndroid Build Coastguard Worker                             }
2014*35238bceSAndroid Build Coastguard Worker                         }
2015*35238bceSAndroid Build Coastguard Worker                 }
2016*35238bceSAndroid Build Coastguard Worker 
2017*35238bceSAndroid Build Coastguard Worker             if (!uniquenessOk)
2018*35238bceSAndroid Build Coastguard Worker             {
2019*35238bceSAndroid Build Coastguard Worker                 allOk = false;
2020*35238bceSAndroid Build Coastguard Worker 
2021*35238bceSAndroid Build Coastguard Worker                 if (printCount > printFloodLimit)
2022*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "...\n"
2023*35238bceSAndroid Build Coastguard Worker                                        << "Omitted " << (printCount - printFloodLimit) << " error descriptions."
2024*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::EndMessage;
2025*35238bceSAndroid Build Coastguard Worker             }
2026*35238bceSAndroid Build Coastguard Worker         }
2027*35238bceSAndroid Build Coastguard Worker 
2028*35238bceSAndroid Build Coastguard Worker         // check number of sample mask bit groups is valid ( == number of invocations )
2029*35238bceSAndroid Build Coastguard Worker         {
2030*35238bceSAndroid Build Coastguard Worker             const uint32_t minNumInvocations = (uint32_t)de::max(1, (m_numTargetSamples + 1) / 2);
2031*35238bceSAndroid Build Coastguard Worker             bool countOk                     = true;
2032*35238bceSAndroid Build Coastguard Worker             int printCount                   = 0;
2033*35238bceSAndroid Build Coastguard Worker             const int printFloodLimit        = 5;
2034*35238bceSAndroid Build Coastguard Worker 
2035*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
2036*35238bceSAndroid Build Coastguard Worker                                << "Verifying cardinality of separate sample mask bit sets. Expecting equal to the "
2037*35238bceSAndroid Build Coastguard Worker                                   "number of invocations, (greater or equal to "
2038*35238bceSAndroid Build Coastguard Worker                                << minNumInvocations << ")" << tcu::TestLog::EndMessage;
2039*35238bceSAndroid Build Coastguard Worker 
2040*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < height; ++y)
2041*35238bceSAndroid Build Coastguard Worker                 for (int x = 0; x < width; ++x)
2042*35238bceSAndroid Build Coastguard Worker                 {
2043*35238bceSAndroid Build Coastguard Worker                     std::set<uint32_t> masks;
2044*35238bceSAndroid Build Coastguard Worker 
2045*35238bceSAndroid Build Coastguard Worker                     for (int maskNdx = 0; maskNdx < m_numTargetSamples; ++maskNdx)
2046*35238bceSAndroid Build Coastguard Worker                     {
2047*35238bceSAndroid Build Coastguard Worker                         const uint32_t mask = sampleCoverage[maskNdx].getAccess().getPixelUint(x, y).x();
2048*35238bceSAndroid Build Coastguard Worker                         masks.insert(mask);
2049*35238bceSAndroid Build Coastguard Worker                     }
2050*35238bceSAndroid Build Coastguard Worker 
2051*35238bceSAndroid Build Coastguard Worker                     if ((int)masks.size() < (int)minNumInvocations)
2052*35238bceSAndroid Build Coastguard Worker                     {
2053*35238bceSAndroid Build Coastguard Worker                         if (++printCount <= printFloodLimit)
2054*35238bceSAndroid Build Coastguard Worker                         {
2055*35238bceSAndroid Build Coastguard Worker                             m_testCtx.getLog() << tcu::TestLog::Message << "Pixel (" << x << ", " << y
2056*35238bceSAndroid Build Coastguard Worker                                                << "): Pixel invocations had only " << (int)masks.size()
2057*35238bceSAndroid Build Coastguard Worker                                                << " separate mask sets. Expected " << minNumInvocations
2058*35238bceSAndroid Build Coastguard Worker                                                << " or more. Found masks:" << tcu::TestLog::EndMessage;
2059*35238bceSAndroid Build Coastguard Worker 
2060*35238bceSAndroid Build Coastguard Worker                             for (std::set<uint32_t>::iterator it = masks.begin(); it != masks.end(); ++it)
2061*35238bceSAndroid Build Coastguard Worker                                 m_testCtx.getLog()
2062*35238bceSAndroid Build Coastguard Worker                                     << tcu::TestLog::Message << "\tMask: " << tcu::Format::Hex<8>(*it) << "\n"
2063*35238bceSAndroid Build Coastguard Worker                                     << tcu::TestLog::EndMessage;
2064*35238bceSAndroid Build Coastguard Worker                         }
2065*35238bceSAndroid Build Coastguard Worker 
2066*35238bceSAndroid Build Coastguard Worker                         countOk = false;
2067*35238bceSAndroid Build Coastguard Worker                     }
2068*35238bceSAndroid Build Coastguard Worker                 }
2069*35238bceSAndroid Build Coastguard Worker 
2070*35238bceSAndroid Build Coastguard Worker             if (!countOk)
2071*35238bceSAndroid Build Coastguard Worker             {
2072*35238bceSAndroid Build Coastguard Worker                 allOk = false;
2073*35238bceSAndroid Build Coastguard Worker 
2074*35238bceSAndroid Build Coastguard Worker                 if (printCount > printFloodLimit)
2075*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "...\n"
2076*35238bceSAndroid Build Coastguard Worker                                        << "Omitted " << (printCount - printFloodLimit) << " error descriptions."
2077*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::EndMessage;
2078*35238bceSAndroid Build Coastguard Worker             }
2079*35238bceSAndroid Build Coastguard Worker         }
2080*35238bceSAndroid Build Coastguard Worker     }
2081*35238bceSAndroid Build Coastguard Worker 
2082*35238bceSAndroid Build Coastguard Worker     if (!allOk)
2083*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
2084*35238bceSAndroid Build Coastguard Worker }
2085*35238bceSAndroid Build Coastguard Worker 
2086*35238bceSAndroid Build Coastguard Worker class SampleMaskWriteCase : public SampleMaskBaseCase
2087*35238bceSAndroid Build Coastguard Worker {
2088*35238bceSAndroid Build Coastguard Worker public:
2089*35238bceSAndroid Build Coastguard Worker     enum TestMode
2090*35238bceSAndroid Build Coastguard Worker     {
2091*35238bceSAndroid Build Coastguard Worker         TEST_DISCARD = 0,
2092*35238bceSAndroid Build Coastguard Worker         TEST_INVERSE,
2093*35238bceSAndroid Build Coastguard Worker 
2094*35238bceSAndroid Build Coastguard Worker         TEST_LAST
2095*35238bceSAndroid Build Coastguard Worker     };
2096*35238bceSAndroid Build Coastguard Worker     SampleMaskWriteCase(Context &context, const char *name, const char *desc, int sampleCount, RenderTarget target,
2097*35238bceSAndroid Build Coastguard Worker                         ShaderRunMode runMode, TestMode testMode);
2098*35238bceSAndroid Build Coastguard Worker     ~SampleMaskWriteCase(void);
2099*35238bceSAndroid Build Coastguard Worker 
2100*35238bceSAndroid Build Coastguard Worker     void init(void);
2101*35238bceSAndroid Build Coastguard Worker     void preDraw(void);
2102*35238bceSAndroid Build Coastguard Worker     void postDraw(void);
2103*35238bceSAndroid Build Coastguard Worker 
2104*35238bceSAndroid Build Coastguard Worker private:
2105*35238bceSAndroid Build Coastguard Worker     enum
2106*35238bceSAndroid Build Coastguard Worker     {
2107*35238bceSAndroid Build Coastguard Worker         RENDER_SIZE = 64
2108*35238bceSAndroid Build Coastguard Worker     };
2109*35238bceSAndroid Build Coastguard Worker 
2110*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(int numTargetSamples) const;
2111*35238bceSAndroid Build Coastguard Worker     bool verifyImage(const tcu::Surface &resultImage);
2112*35238bceSAndroid Build Coastguard Worker 
2113*35238bceSAndroid Build Coastguard Worker     const TestMode m_testMode;
2114*35238bceSAndroid Build Coastguard Worker };
2115*35238bceSAndroid Build Coastguard Worker 
SampleMaskWriteCase(Context & context,const char * name,const char * desc,int sampleCount,RenderTarget target,ShaderRunMode runMode,TestMode testMode)2116*35238bceSAndroid Build Coastguard Worker SampleMaskWriteCase::SampleMaskWriteCase(Context &context, const char *name, const char *desc, int sampleCount,
2117*35238bceSAndroid Build Coastguard Worker                                          RenderTarget target, ShaderRunMode runMode, TestMode testMode)
2118*35238bceSAndroid Build Coastguard Worker     : SampleMaskBaseCase(context, name, desc, sampleCount, target, RENDER_SIZE, runMode)
2119*35238bceSAndroid Build Coastguard Worker     , m_testMode(testMode)
2120*35238bceSAndroid Build Coastguard Worker {
2121*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(testMode < TEST_LAST);
2122*35238bceSAndroid Build Coastguard Worker }
2123*35238bceSAndroid Build Coastguard Worker 
~SampleMaskWriteCase(void)2124*35238bceSAndroid Build Coastguard Worker SampleMaskWriteCase::~SampleMaskWriteCase(void)
2125*35238bceSAndroid Build Coastguard Worker {
2126*35238bceSAndroid Build Coastguard Worker }
2127*35238bceSAndroid Build Coastguard Worker 
init(void)2128*35238bceSAndroid Build Coastguard Worker void SampleMaskWriteCase::init(void)
2129*35238bceSAndroid Build Coastguard Worker {
2130*35238bceSAndroid Build Coastguard Worker     // log the test method and expectations
2131*35238bceSAndroid Build Coastguard Worker     if (m_testMode == TEST_DISCARD)
2132*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
2133*35238bceSAndroid Build Coastguard Worker                            << "Discarding half of the samples using gl_SampleMask, expecting:\n"
2134*35238bceSAndroid Build Coastguard Worker                            << "    1) half intensity on multisample targets (numSamples > 1)\n"
2135*35238bceSAndroid Build Coastguard Worker                            << "    2) full discard on multisample targets (numSamples == 1)\n"
2136*35238bceSAndroid Build Coastguard Worker                            << "    3) full intensity (no discard) on singlesample targets. (Mask is only applied as a "
2137*35238bceSAndroid Build Coastguard Worker                               "multisample operation.)\n"
2138*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2139*35238bceSAndroid Build Coastguard Worker     else if (m_testMode == TEST_INVERSE)
2140*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
2141*35238bceSAndroid Build Coastguard Worker                            << "Discarding half of the samples using GL_SAMPLE_MASK, setting inverse mask in fragment "
2142*35238bceSAndroid Build Coastguard Worker                               "shader using gl_SampleMask, expecting:\n"
2143*35238bceSAndroid Build Coastguard Worker                            << "    1) full discard on multisample targets (mask & modifiedCoverge == 0)\n"
2144*35238bceSAndroid Build Coastguard Worker                            << "    2) full intensity (no discard) on singlesample targets. (Mask and coverage is only "
2145*35238bceSAndroid Build Coastguard Worker                               "applied as a multisample operation.)\n"
2146*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2147*35238bceSAndroid Build Coastguard Worker     else
2148*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2149*35238bceSAndroid Build Coastguard Worker 
2150*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::init();
2151*35238bceSAndroid Build Coastguard Worker }
2152*35238bceSAndroid Build Coastguard Worker 
preDraw(void)2153*35238bceSAndroid Build Coastguard Worker void SampleMaskWriteCase::preDraw(void)
2154*35238bceSAndroid Build Coastguard Worker {
2155*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2156*35238bceSAndroid Build Coastguard Worker 
2157*35238bceSAndroid Build Coastguard Worker     if (m_testMode == TEST_INVERSE)
2158*35238bceSAndroid Build Coastguard Worker     {
2159*35238bceSAndroid Build Coastguard Worker         // set mask to 0xAAAA.., set inverse mask bit coverage in shader
2160*35238bceSAndroid Build Coastguard Worker 
2161*35238bceSAndroid Build Coastguard Worker         const int maskLoc   = gl.getUniformLocation(m_program->getProgram(), "u_mask");
2162*35238bceSAndroid Build Coastguard Worker         const uint32_t mask = (uint32_t)0xAAAAAAAAUL;
2163*35238bceSAndroid Build Coastguard Worker 
2164*35238bceSAndroid Build Coastguard Worker         if (maskLoc == -1)
2165*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Location of u_mask was -1");
2166*35238bceSAndroid Build Coastguard Worker 
2167*35238bceSAndroid Build Coastguard Worker         gl.enable(GL_SAMPLE_MASK);
2168*35238bceSAndroid Build Coastguard Worker         gl.sampleMaski(0, mask);
2169*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set mask");
2170*35238bceSAndroid Build Coastguard Worker 
2171*35238bceSAndroid Build Coastguard Worker         gl.uniform1ui(maskLoc, mask);
2172*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set mask uniform");
2173*35238bceSAndroid Build Coastguard Worker 
2174*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Setting sample mask " << tcu::Format::Hex<4>(mask)
2175*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2176*35238bceSAndroid Build Coastguard Worker     }
2177*35238bceSAndroid Build Coastguard Worker 
2178*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::preDraw();
2179*35238bceSAndroid Build Coastguard Worker }
2180*35238bceSAndroid Build Coastguard Worker 
postDraw(void)2181*35238bceSAndroid Build Coastguard Worker void SampleMaskWriteCase::postDraw(void)
2182*35238bceSAndroid Build Coastguard Worker {
2183*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2184*35238bceSAndroid Build Coastguard Worker 
2185*35238bceSAndroid Build Coastguard Worker     if (m_testMode == TEST_INVERSE)
2186*35238bceSAndroid Build Coastguard Worker     {
2187*35238bceSAndroid Build Coastguard Worker         const uint32_t fullMask = (1U << m_numTargetSamples) - 1;
2188*35238bceSAndroid Build Coastguard Worker 
2189*35238bceSAndroid Build Coastguard Worker         gl.disable(GL_SAMPLE_MASK);
2190*35238bceSAndroid Build Coastguard Worker         gl.sampleMaski(0, fullMask);
2191*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set mask");
2192*35238bceSAndroid Build Coastguard Worker     }
2193*35238bceSAndroid Build Coastguard Worker 
2194*35238bceSAndroid Build Coastguard Worker     SampleMaskBaseCase::postDraw();
2195*35238bceSAndroid Build Coastguard Worker }
2196*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(int numTargetSamples) const2197*35238bceSAndroid Build Coastguard Worker std::string SampleMaskWriteCase::genFragmentSource(int numTargetSamples) const
2198*35238bceSAndroid Build Coastguard Worker {
2199*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numTargetSamples != 0);
2200*35238bceSAndroid Build Coastguard Worker     DE_UNREF(numTargetSamples);
2201*35238bceSAndroid Build Coastguard Worker 
2202*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
2203*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
2204*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
2205*35238bceSAndroid Build Coastguard Worker         contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
2206*35238bceSAndroid Build Coastguard Worker     map<string, string> args;
2207*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"] = supportsES32orGL45 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) :
2208*35238bceSAndroid Build Coastguard Worker                                                      getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
2209*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXTENSION"]    = supportsES32orGL45 ? "" : "#extension GL_OES_sample_variables : require";
2210*35238bceSAndroid Build Coastguard Worker 
2211*35238bceSAndroid Build Coastguard Worker     if (m_testMode == TEST_DISCARD)
2212*35238bceSAndroid Build Coastguard Worker     {
2213*35238bceSAndroid Build Coastguard Worker         // mask out every other coverage bit
2214*35238bceSAndroid Build Coastguard Worker 
2215*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_VERSION_DECL}\n"
2216*35238bceSAndroid Build Coastguard Worker                "${GLSL_EXTENSION}\n"
2217*35238bceSAndroid Build Coastguard Worker                "layout(location = 0) out mediump vec4 fragColor;\n"
2218*35238bceSAndroid Build Coastguard Worker                "void main (void)\n"
2219*35238bceSAndroid Build Coastguard Worker                "{\n"
2220*35238bceSAndroid Build Coastguard Worker                "    for (int i = 0; i < gl_SampleMask.length(); ++i)\n"
2221*35238bceSAndroid Build Coastguard Worker                "        gl_SampleMask[i] = int(0xAAAAAAAA);\n"
2222*35238bceSAndroid Build Coastguard Worker                "\n";
2223*35238bceSAndroid Build Coastguard Worker 
2224*35238bceSAndroid Build Coastguard Worker         if (m_runMode == RUN_PER_SAMPLE)
2225*35238bceSAndroid Build Coastguard Worker             buf << "    // force per-sample shading\n"
2226*35238bceSAndroid Build Coastguard Worker                    "    highp float blue = float(gl_SampleID);\n"
2227*35238bceSAndroid Build Coastguard Worker                    "\n"
2228*35238bceSAndroid Build Coastguard Worker                    "    fragColor = vec4(0.0, 1.0, blue, 1.0);\n"
2229*35238bceSAndroid Build Coastguard Worker                    "}\n";
2230*35238bceSAndroid Build Coastguard Worker         else
2231*35238bceSAndroid Build Coastguard Worker             buf << "    fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
2232*35238bceSAndroid Build Coastguard Worker                    "}\n";
2233*35238bceSAndroid Build Coastguard Worker     }
2234*35238bceSAndroid Build Coastguard Worker     else if (m_testMode == TEST_INVERSE)
2235*35238bceSAndroid Build Coastguard Worker     {
2236*35238bceSAndroid Build Coastguard Worker         // inverse every coverage bit
2237*35238bceSAndroid Build Coastguard Worker 
2238*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_VERSION_DECL}\n"
2239*35238bceSAndroid Build Coastguard Worker                "${GLSL_EXTENSION}\n"
2240*35238bceSAndroid Build Coastguard Worker                "layout(location = 0) out mediump vec4 fragColor;\n"
2241*35238bceSAndroid Build Coastguard Worker                "uniform highp uint u_mask;\n"
2242*35238bceSAndroid Build Coastguard Worker                "void main (void)\n"
2243*35238bceSAndroid Build Coastguard Worker                "{\n"
2244*35238bceSAndroid Build Coastguard Worker                "    gl_SampleMask[0] = int(~u_mask);\n"
2245*35238bceSAndroid Build Coastguard Worker                "\n";
2246*35238bceSAndroid Build Coastguard Worker 
2247*35238bceSAndroid Build Coastguard Worker         if (m_runMode == RUN_PER_SAMPLE)
2248*35238bceSAndroid Build Coastguard Worker             buf << "    // force per-sample shading\n"
2249*35238bceSAndroid Build Coastguard Worker                    "    highp float blue = float(gl_SampleID);\n"
2250*35238bceSAndroid Build Coastguard Worker                    "\n"
2251*35238bceSAndroid Build Coastguard Worker                    "    fragColor = vec4(0.0, 1.0, blue, 1.0);\n"
2252*35238bceSAndroid Build Coastguard Worker                    "}\n";
2253*35238bceSAndroid Build Coastguard Worker         else
2254*35238bceSAndroid Build Coastguard Worker             buf << "    fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
2255*35238bceSAndroid Build Coastguard Worker                    "}\n";
2256*35238bceSAndroid Build Coastguard Worker     }
2257*35238bceSAndroid Build Coastguard Worker     else
2258*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2259*35238bceSAndroid Build Coastguard Worker 
2260*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(buf.str()).specialize(args);
2261*35238bceSAndroid Build Coastguard Worker }
2262*35238bceSAndroid Build Coastguard Worker 
verifyImage(const tcu::Surface & resultImage)2263*35238bceSAndroid Build Coastguard Worker bool SampleMaskWriteCase::verifyImage(const tcu::Surface &resultImage)
2264*35238bceSAndroid Build Coastguard Worker {
2265*35238bceSAndroid Build Coastguard Worker     const bool singleSampleTarget = m_numRequestedSamples == 0 && !(m_renderTarget == TARGET_DEFAULT &&
2266*35238bceSAndroid Build Coastguard Worker                                                                     m_context.getRenderTarget().getNumSamples() > 1);
2267*35238bceSAndroid Build Coastguard Worker 
2268*35238bceSAndroid Build Coastguard Worker     if (m_testMode == TEST_DISCARD)
2269*35238bceSAndroid Build Coastguard Worker     {
2270*35238bceSAndroid Build Coastguard Worker         if (singleSampleTarget)
2271*35238bceSAndroid Build Coastguard Worker         {
2272*35238bceSAndroid Build Coastguard Worker             // single sample case => multisample operations are not effective => don't discard anything
2273*35238bceSAndroid Build Coastguard Worker             // expect green
2274*35238bceSAndroid Build Coastguard Worker             return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), ColorVerifier(tcu::Vec3(0.0f, 1.0f, 0.0f)));
2275*35238bceSAndroid Build Coastguard Worker         }
2276*35238bceSAndroid Build Coastguard Worker         else if (m_numTargetSamples == 1)
2277*35238bceSAndroid Build Coastguard Worker         {
2278*35238bceSAndroid Build Coastguard Worker             // total discard, expect black
2279*35238bceSAndroid Build Coastguard Worker             return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), ColorVerifier(tcu::Vec3(0.0f, 0.0f, 0.0f)));
2280*35238bceSAndroid Build Coastguard Worker         }
2281*35238bceSAndroid Build Coastguard Worker         else
2282*35238bceSAndroid Build Coastguard Worker         {
2283*35238bceSAndroid Build Coastguard Worker             // partial discard, expect something between black and green
2284*35238bceSAndroid Build Coastguard Worker             return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), PartialDiscardVerifier());
2285*35238bceSAndroid Build Coastguard Worker         }
2286*35238bceSAndroid Build Coastguard Worker     }
2287*35238bceSAndroid Build Coastguard Worker     else if (m_testMode == TEST_INVERSE)
2288*35238bceSAndroid Build Coastguard Worker     {
2289*35238bceSAndroid Build Coastguard Worker         if (singleSampleTarget)
2290*35238bceSAndroid Build Coastguard Worker         {
2291*35238bceSAndroid Build Coastguard Worker             // single sample case => multisample operations are not effective => don't discard anything
2292*35238bceSAndroid Build Coastguard Worker             // expect green
2293*35238bceSAndroid Build Coastguard Worker             return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), ColorVerifier(tcu::Vec3(0.0f, 1.0f, 0.0f)));
2294*35238bceSAndroid Build Coastguard Worker         }
2295*35238bceSAndroid Build Coastguard Worker         else
2296*35238bceSAndroid Build Coastguard Worker         {
2297*35238bceSAndroid Build Coastguard Worker             // total discard, expect black
2298*35238bceSAndroid Build Coastguard Worker             return verifyImageWithVerifier(resultImage, m_testCtx.getLog(), ColorVerifier(tcu::Vec3(0.0f, 0.0f, 0.0f)));
2299*35238bceSAndroid Build Coastguard Worker         }
2300*35238bceSAndroid Build Coastguard Worker     }
2301*35238bceSAndroid Build Coastguard Worker     else
2302*35238bceSAndroid Build Coastguard Worker     {
2303*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2304*35238bceSAndroid Build Coastguard Worker         return false;
2305*35238bceSAndroid Build Coastguard Worker     }
2306*35238bceSAndroid Build Coastguard Worker }
2307*35238bceSAndroid Build Coastguard Worker 
2308*35238bceSAndroid Build Coastguard Worker } // namespace
2309*35238bceSAndroid Build Coastguard Worker 
SampleVariableTests(Context & context)2310*35238bceSAndroid Build Coastguard Worker SampleVariableTests::SampleVariableTests(Context &context)
2311*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "sample_variables", "Test sample variables")
2312*35238bceSAndroid Build Coastguard Worker {
2313*35238bceSAndroid Build Coastguard Worker }
2314*35238bceSAndroid Build Coastguard Worker 
~SampleVariableTests(void)2315*35238bceSAndroid Build Coastguard Worker SampleVariableTests::~SampleVariableTests(void)
2316*35238bceSAndroid Build Coastguard Worker {
2317*35238bceSAndroid Build Coastguard Worker }
2318*35238bceSAndroid Build Coastguard Worker 
init(void)2319*35238bceSAndroid Build Coastguard Worker void SampleVariableTests::init(void)
2320*35238bceSAndroid Build Coastguard Worker {
2321*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const numSampleGroup = new tcu::TestCaseGroup(m_testCtx, "num_samples", "Test NumSamples");
2322*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const maxSampleGroup = new tcu::TestCaseGroup(m_testCtx, "max_samples", "Test MaxSamples");
2323*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const sampleIDGroup  = new tcu::TestCaseGroup(m_testCtx, "sample_id", "Test SampleID");
2324*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const samplePosGroup = new tcu::TestCaseGroup(m_testCtx, "sample_pos", "Test SamplePosition");
2325*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const sampleMaskInGroup =
2326*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "sample_mask_in", "Test SampleMaskIn");
2327*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const sampleMaskGroup = new tcu::TestCaseGroup(m_testCtx, "sample_mask", "Test SampleMask");
2328*35238bceSAndroid Build Coastguard Worker 
2329*35238bceSAndroid Build Coastguard Worker     addChild(numSampleGroup);
2330*35238bceSAndroid Build Coastguard Worker     addChild(maxSampleGroup);
2331*35238bceSAndroid Build Coastguard Worker     addChild(sampleIDGroup);
2332*35238bceSAndroid Build Coastguard Worker     addChild(samplePosGroup);
2333*35238bceSAndroid Build Coastguard Worker     addChild(sampleMaskInGroup);
2334*35238bceSAndroid Build Coastguard Worker     addChild(sampleMaskGroup);
2335*35238bceSAndroid Build Coastguard Worker 
2336*35238bceSAndroid Build Coastguard Worker     static const struct RenderTarget
2337*35238bceSAndroid Build Coastguard Worker     {
2338*35238bceSAndroid Build Coastguard Worker         const char *name;
2339*35238bceSAndroid Build Coastguard Worker         const char *desc;
2340*35238bceSAndroid Build Coastguard Worker         int numSamples;
2341*35238bceSAndroid Build Coastguard Worker         MultisampleRenderCase::RenderTarget target;
2342*35238bceSAndroid Build Coastguard Worker     } targets[] = {
2343*35238bceSAndroid Build Coastguard Worker         {"default_framebuffer", "Test with default framebuffer", 0, MultisampleRenderCase::TARGET_DEFAULT},
2344*35238bceSAndroid Build Coastguard Worker         {"singlesample_texture", "Test with singlesample texture", 0, MultisampleRenderCase::TARGET_TEXTURE},
2345*35238bceSAndroid Build Coastguard Worker         {"multisample_texture_1", "Test with multisample texture", 1, MultisampleRenderCase::TARGET_TEXTURE},
2346*35238bceSAndroid Build Coastguard Worker         {"multisample_texture_2", "Test with multisample texture", 2, MultisampleRenderCase::TARGET_TEXTURE},
2347*35238bceSAndroid Build Coastguard Worker         {"multisample_texture_4", "Test with multisample texture", 4, MultisampleRenderCase::TARGET_TEXTURE},
2348*35238bceSAndroid Build Coastguard Worker         {"multisample_texture_8", "Test with multisample texture", 8, MultisampleRenderCase::TARGET_TEXTURE},
2349*35238bceSAndroid Build Coastguard Worker         {"multisample_texture_16", "Test with multisample texture", 16, MultisampleRenderCase::TARGET_TEXTURE},
2350*35238bceSAndroid Build Coastguard Worker         {"singlesample_rbo", "Test with singlesample rbo", 0, MultisampleRenderCase::TARGET_RENDERBUFFER},
2351*35238bceSAndroid Build Coastguard Worker         {"multisample_rbo_1", "Test with multisample rbo", 1, MultisampleRenderCase::TARGET_RENDERBUFFER},
2352*35238bceSAndroid Build Coastguard Worker         {"multisample_rbo_2", "Test with multisample rbo", 2, MultisampleRenderCase::TARGET_RENDERBUFFER},
2353*35238bceSAndroid Build Coastguard Worker         {"multisample_rbo_4", "Test with multisample rbo", 4, MultisampleRenderCase::TARGET_RENDERBUFFER},
2354*35238bceSAndroid Build Coastguard Worker         {"multisample_rbo_8", "Test with multisample rbo", 8, MultisampleRenderCase::TARGET_RENDERBUFFER},
2355*35238bceSAndroid Build Coastguard Worker         {"multisample_rbo_16", "Test with multisample rbo", 16, MultisampleRenderCase::TARGET_RENDERBUFFER},
2356*35238bceSAndroid Build Coastguard Worker     };
2357*35238bceSAndroid Build Coastguard Worker 
2358*35238bceSAndroid Build Coastguard Worker     // .num_samples
2359*35238bceSAndroid Build Coastguard Worker     {
2360*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2361*35238bceSAndroid Build Coastguard Worker             numSampleGroup->addChild(new NumSamplesCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2362*35238bceSAndroid Build Coastguard Worker                                                         targets[targetNdx].numSamples, targets[targetNdx].target));
2363*35238bceSAndroid Build Coastguard Worker     }
2364*35238bceSAndroid Build Coastguard Worker 
2365*35238bceSAndroid Build Coastguard Worker     // .max_samples
2366*35238bceSAndroid Build Coastguard Worker     {
2367*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2368*35238bceSAndroid Build Coastguard Worker             maxSampleGroup->addChild(new MaxSamplesCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2369*35238bceSAndroid Build Coastguard Worker                                                         targets[targetNdx].numSamples, targets[targetNdx].target));
2370*35238bceSAndroid Build Coastguard Worker     }
2371*35238bceSAndroid Build Coastguard Worker 
2372*35238bceSAndroid Build Coastguard Worker     // .sample_ID
2373*35238bceSAndroid Build Coastguard Worker     {
2374*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2375*35238bceSAndroid Build Coastguard Worker             sampleIDGroup->addChild(new SampleIDCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2376*35238bceSAndroid Build Coastguard Worker                                                      targets[targetNdx].numSamples, targets[targetNdx].target));
2377*35238bceSAndroid Build Coastguard Worker     }
2378*35238bceSAndroid Build Coastguard Worker 
2379*35238bceSAndroid Build Coastguard Worker     // .sample_pos
2380*35238bceSAndroid Build Coastguard Worker     {{tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "correctness", "Test SamplePos correctness");
2381*35238bceSAndroid Build Coastguard Worker     samplePosGroup->addChild(group);
2382*35238bceSAndroid Build Coastguard Worker 
2383*35238bceSAndroid Build Coastguard Worker     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2384*35238bceSAndroid Build Coastguard Worker         group->addChild(new SamplePosCorrectnessCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2385*35238bceSAndroid Build Coastguard Worker                                                      targets[targetNdx].numSamples, targets[targetNdx].target));
2386*35238bceSAndroid Build Coastguard Worker }
2387*35238bceSAndroid Build Coastguard Worker 
2388*35238bceSAndroid Build Coastguard Worker {
2389*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "distribution", "Test SamplePos distribution");
2390*35238bceSAndroid Build Coastguard Worker     samplePosGroup->addChild(group);
2391*35238bceSAndroid Build Coastguard Worker 
2392*35238bceSAndroid Build Coastguard Worker     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2393*35238bceSAndroid Build Coastguard Worker         group->addChild(new SamplePosDistributionCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2394*35238bceSAndroid Build Coastguard Worker                                                       targets[targetNdx].numSamples, targets[targetNdx].target));
2395*35238bceSAndroid Build Coastguard Worker }
2396*35238bceSAndroid Build Coastguard Worker } // namespace Functional
2397*35238bceSAndroid Build Coastguard Worker 
2398*35238bceSAndroid Build Coastguard Worker // .sample_mask_in
2399*35238bceSAndroid Build Coastguard Worker {// .sample_mask
2400*35238bceSAndroid Build Coastguard Worker  {tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "sample_mask", "Test with GL_SAMPLE_MASK");
2401*35238bceSAndroid Build Coastguard Worker sampleMaskInGroup->addChild(group);
2402*35238bceSAndroid Build Coastguard Worker 
2403*35238bceSAndroid Build Coastguard Worker for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2404*35238bceSAndroid Build Coastguard Worker     group->addChild(new SampleMaskCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2405*35238bceSAndroid Build Coastguard Worker                                        targets[targetNdx].numSamples, targets[targetNdx].target));
2406*35238bceSAndroid Build Coastguard Worker } // namespace gles31
2407*35238bceSAndroid Build Coastguard Worker // .bit_count_per_pixel
2408*35238bceSAndroid Build Coastguard Worker {
2409*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const group =
2410*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "bit_count_per_pixel", "Test number of coverage bits");
2411*35238bceSAndroid Build Coastguard Worker     sampleMaskInGroup->addChild(group);
2412*35238bceSAndroid Build Coastguard Worker 
2413*35238bceSAndroid Build Coastguard Worker     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2414*35238bceSAndroid Build Coastguard Worker         group->addChild(new SampleMaskCountCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2415*35238bceSAndroid Build Coastguard Worker                                                 targets[targetNdx].numSamples, targets[targetNdx].target,
2416*35238bceSAndroid Build Coastguard Worker                                                 SampleMaskCountCase::RUN_PER_PIXEL));
2417*35238bceSAndroid Build Coastguard Worker }
2418*35238bceSAndroid Build Coastguard Worker // .bit_count_per_sample
2419*35238bceSAndroid Build Coastguard Worker {
2420*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const group =
2421*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "bit_count_per_sample", "Test number of coverage bits");
2422*35238bceSAndroid Build Coastguard Worker     sampleMaskInGroup->addChild(group);
2423*35238bceSAndroid Build Coastguard Worker 
2424*35238bceSAndroid Build Coastguard Worker     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2425*35238bceSAndroid Build Coastguard Worker         group->addChild(new SampleMaskCountCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2426*35238bceSAndroid Build Coastguard Worker                                                 targets[targetNdx].numSamples, targets[targetNdx].target,
2427*35238bceSAndroid Build Coastguard Worker                                                 SampleMaskCountCase::RUN_PER_SAMPLE));
2428*35238bceSAndroid Build Coastguard Worker }
2429*35238bceSAndroid Build Coastguard Worker // .bit_count_per_two_samples
2430*35238bceSAndroid Build Coastguard Worker {
2431*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const group =
2432*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "bit_count_per_two_samples", "Test number of coverage bits");
2433*35238bceSAndroid Build Coastguard Worker     sampleMaskInGroup->addChild(group);
2434*35238bceSAndroid Build Coastguard Worker 
2435*35238bceSAndroid Build Coastguard Worker     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2436*35238bceSAndroid Build Coastguard Worker         group->addChild(new SampleMaskCountCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2437*35238bceSAndroid Build Coastguard Worker                                                 targets[targetNdx].numSamples, targets[targetNdx].target,
2438*35238bceSAndroid Build Coastguard Worker                                                 SampleMaskCountCase::RUN_PER_TWO_SAMPLES));
2439*35238bceSAndroid Build Coastguard Worker }
2440*35238bceSAndroid Build Coastguard Worker // .bits_unique_per_sample
2441*35238bceSAndroid Build Coastguard Worker {
2442*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "bits_unique_per_sample", "Test coverage bits");
2443*35238bceSAndroid Build Coastguard Worker     sampleMaskInGroup->addChild(group);
2444*35238bceSAndroid Build Coastguard Worker 
2445*35238bceSAndroid Build Coastguard Worker     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2446*35238bceSAndroid Build Coastguard Worker         if (targets[targetNdx].target == MultisampleRenderCase::TARGET_TEXTURE)
2447*35238bceSAndroid Build Coastguard Worker             group->addChild(new SampleMaskUniqueCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2448*35238bceSAndroid Build Coastguard Worker                                                      targets[targetNdx].numSamples, targets[targetNdx].target,
2449*35238bceSAndroid Build Coastguard Worker                                                      SampleMaskUniqueCase::RUN_PER_SAMPLE));
2450*35238bceSAndroid Build Coastguard Worker }
2451*35238bceSAndroid Build Coastguard Worker // .bits_unique_per_two_samples
2452*35238bceSAndroid Build Coastguard Worker {
2453*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const group =
2454*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "bits_unique_per_two_samples", "Test coverage bits");
2455*35238bceSAndroid Build Coastguard Worker     sampleMaskInGroup->addChild(group);
2456*35238bceSAndroid Build Coastguard Worker 
2457*35238bceSAndroid Build Coastguard Worker     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2458*35238bceSAndroid Build Coastguard Worker         if (targets[targetNdx].target == MultisampleRenderCase::TARGET_TEXTURE)
2459*35238bceSAndroid Build Coastguard Worker             group->addChild(new SampleMaskUniqueSetCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2460*35238bceSAndroid Build Coastguard Worker                                                         targets[targetNdx].numSamples, targets[targetNdx].target,
2461*35238bceSAndroid Build Coastguard Worker                                                         SampleMaskUniqueCase::RUN_PER_TWO_SAMPLES));
2462*35238bceSAndroid Build Coastguard Worker }
2463*35238bceSAndroid Build Coastguard Worker } // namespace deqp
2464*35238bceSAndroid Build Coastguard Worker 
2465*35238bceSAndroid Build Coastguard Worker // .sample_mask
2466*35238bceSAndroid Build Coastguard Worker {
2467*35238bceSAndroid Build Coastguard Worker     // .discard_half_per_pixel
2468*35238bceSAndroid Build Coastguard Worker     {
2469*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const group =
2470*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "discard_half_per_pixel", "Test coverage bits");
2471*35238bceSAndroid Build Coastguard Worker         sampleMaskGroup->addChild(group);
2472*35238bceSAndroid Build Coastguard Worker 
2473*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2474*35238bceSAndroid Build Coastguard Worker             group->addChild(new SampleMaskWriteCase(
2475*35238bceSAndroid Build Coastguard Worker                 m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples,
2476*35238bceSAndroid Build Coastguard Worker                 targets[targetNdx].target, SampleMaskWriteCase::RUN_PER_PIXEL, SampleMaskWriteCase::TEST_DISCARD));
2477*35238bceSAndroid Build Coastguard Worker     }
2478*35238bceSAndroid Build Coastguard Worker     // .discard_half_per_sample
2479*35238bceSAndroid Build Coastguard Worker     {
2480*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const group =
2481*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "discard_half_per_sample", "Test coverage bits");
2482*35238bceSAndroid Build Coastguard Worker         sampleMaskGroup->addChild(group);
2483*35238bceSAndroid Build Coastguard Worker 
2484*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2485*35238bceSAndroid Build Coastguard Worker             group->addChild(new SampleMaskWriteCase(
2486*35238bceSAndroid Build Coastguard Worker                 m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples,
2487*35238bceSAndroid Build Coastguard Worker                 targets[targetNdx].target, SampleMaskWriteCase::RUN_PER_SAMPLE, SampleMaskWriteCase::TEST_DISCARD));
2488*35238bceSAndroid Build Coastguard Worker     }
2489*35238bceSAndroid Build Coastguard Worker     // .discard_half_per_two_samples
2490*35238bceSAndroid Build Coastguard Worker     {
2491*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const group =
2492*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "discard_half_per_two_samples", "Test coverage bits");
2493*35238bceSAndroid Build Coastguard Worker         sampleMaskGroup->addChild(group);
2494*35238bceSAndroid Build Coastguard Worker 
2495*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2496*35238bceSAndroid Build Coastguard Worker             group->addChild(new SampleMaskWriteCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2497*35238bceSAndroid Build Coastguard Worker                                                     targets[targetNdx].numSamples, targets[targetNdx].target,
2498*35238bceSAndroid Build Coastguard Worker                                                     SampleMaskWriteCase::RUN_PER_TWO_SAMPLES,
2499*35238bceSAndroid Build Coastguard Worker                                                     SampleMaskWriteCase::TEST_DISCARD));
2500*35238bceSAndroid Build Coastguard Worker     }
2501*35238bceSAndroid Build Coastguard Worker 
2502*35238bceSAndroid Build Coastguard Worker     // .discard_half_per_two_samples
2503*35238bceSAndroid Build Coastguard Worker     {
2504*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "inverse_per_pixel", "Test coverage bits");
2505*35238bceSAndroid Build Coastguard Worker         sampleMaskGroup->addChild(group);
2506*35238bceSAndroid Build Coastguard Worker 
2507*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2508*35238bceSAndroid Build Coastguard Worker             group->addChild(new SampleMaskWriteCase(
2509*35238bceSAndroid Build Coastguard Worker                 m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples,
2510*35238bceSAndroid Build Coastguard Worker                 targets[targetNdx].target, SampleMaskWriteCase::RUN_PER_PIXEL, SampleMaskWriteCase::TEST_INVERSE));
2511*35238bceSAndroid Build Coastguard Worker     }
2512*35238bceSAndroid Build Coastguard Worker     // .inverse_per_sample
2513*35238bceSAndroid Build Coastguard Worker     {
2514*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "inverse_per_sample", "Test coverage bits");
2515*35238bceSAndroid Build Coastguard Worker         sampleMaskGroup->addChild(group);
2516*35238bceSAndroid Build Coastguard Worker 
2517*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2518*35238bceSAndroid Build Coastguard Worker             group->addChild(new SampleMaskWriteCase(
2519*35238bceSAndroid Build Coastguard Worker                 m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples,
2520*35238bceSAndroid Build Coastguard Worker                 targets[targetNdx].target, SampleMaskWriteCase::RUN_PER_SAMPLE, SampleMaskWriteCase::TEST_INVERSE));
2521*35238bceSAndroid Build Coastguard Worker     }
2522*35238bceSAndroid Build Coastguard Worker     // .inverse_per_two_samples
2523*35238bceSAndroid Build Coastguard Worker     {
2524*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const group =
2525*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "inverse_per_two_samples", "Test coverage bits");
2526*35238bceSAndroid Build Coastguard Worker         sampleMaskGroup->addChild(group);
2527*35238bceSAndroid Build Coastguard Worker 
2528*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2529*35238bceSAndroid Build Coastguard Worker             group->addChild(new SampleMaskWriteCase(m_context, targets[targetNdx].name, targets[targetNdx].desc,
2530*35238bceSAndroid Build Coastguard Worker                                                     targets[targetNdx].numSamples, targets[targetNdx].target,
2531*35238bceSAndroid Build Coastguard Worker                                                     SampleMaskWriteCase::RUN_PER_TWO_SAMPLES,
2532*35238bceSAndroid Build Coastguard Worker                                                     SampleMaskWriteCase::TEST_INVERSE));
2533*35238bceSAndroid Build Coastguard Worker     }
2534*35238bceSAndroid Build Coastguard Worker }
2535*35238bceSAndroid Build Coastguard Worker }
2536*35238bceSAndroid Build Coastguard Worker 
2537*35238bceSAndroid Build Coastguard Worker } // Functional
2538*35238bceSAndroid Build Coastguard Worker } // gles31
2539*35238bceSAndroid Build Coastguard Worker } // deqp
2540