xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fFboMultisampleTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief FBO multisample tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es3fApiCase.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "es3fFboMultisampleTests.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "es3fFboTestCase.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "es3fFboTestUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluTextureUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "sglrContextUtil.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker namespace deqp
38*35238bceSAndroid Build Coastguard Worker {
39*35238bceSAndroid Build Coastguard Worker namespace gles3
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker namespace Functional
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker using std::string;
45*35238bceSAndroid Build Coastguard Worker using tcu::IVec2;
46*35238bceSAndroid Build Coastguard Worker using tcu::IVec3;
47*35238bceSAndroid Build Coastguard Worker using tcu::IVec4;
48*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
49*35238bceSAndroid Build Coastguard Worker using tcu::UVec4;
50*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
51*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
52*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
53*35238bceSAndroid Build Coastguard Worker using namespace FboTestUtil;
54*35238bceSAndroid Build Coastguard Worker 
55*35238bceSAndroid Build Coastguard Worker class BasicFboMultisampleCase : public FboTestCase
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker public:
BasicFboMultisampleCase(Context & context,const char * name,const char * desc,uint32_t colorFormat,uint32_t depthStencilFormat,const IVec2 & size,int numSamples)58*35238bceSAndroid Build Coastguard Worker     BasicFboMultisampleCase(Context &context, const char *name, const char *desc, uint32_t colorFormat,
59*35238bceSAndroid Build Coastguard Worker                             uint32_t depthStencilFormat, const IVec2 &size, int numSamples)
60*35238bceSAndroid Build Coastguard Worker         : FboTestCase(context, name, desc)
61*35238bceSAndroid Build Coastguard Worker         , m_colorFormat(colorFormat)
62*35238bceSAndroid Build Coastguard Worker         , m_depthStencilFormat(depthStencilFormat)
63*35238bceSAndroid Build Coastguard Worker         , m_size(size)
64*35238bceSAndroid Build Coastguard Worker         , m_numSamples(numSamples)
65*35238bceSAndroid Build Coastguard Worker     {
66*35238bceSAndroid Build Coastguard Worker     }
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker protected:
preCheck(void)69*35238bceSAndroid Build Coastguard Worker     void preCheck(void)
70*35238bceSAndroid Build Coastguard Worker     {
71*35238bceSAndroid Build Coastguard Worker         checkFormatSupport(m_colorFormat);
72*35238bceSAndroid Build Coastguard Worker         checkSampleCount(m_colorFormat, m_numSamples);
73*35238bceSAndroid Build Coastguard Worker 
74*35238bceSAndroid Build Coastguard Worker         if (m_depthStencilFormat != GL_NONE)
75*35238bceSAndroid Build Coastguard Worker         {
76*35238bceSAndroid Build Coastguard Worker             checkFormatSupport(m_depthStencilFormat);
77*35238bceSAndroid Build Coastguard Worker             checkSampleCount(m_depthStencilFormat, m_numSamples);
78*35238bceSAndroid Build Coastguard Worker         }
79*35238bceSAndroid Build Coastguard Worker     }
80*35238bceSAndroid Build Coastguard Worker 
render(tcu::Surface & dst)81*35238bceSAndroid Build Coastguard Worker     void render(tcu::Surface &dst)
82*35238bceSAndroid Build Coastguard Worker     {
83*35238bceSAndroid Build Coastguard Worker         tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFormat);
84*35238bceSAndroid Build Coastguard Worker         tcu::TextureFormat depthStencilFmt =
85*35238bceSAndroid Build Coastguard Worker             m_depthStencilFormat != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFormat) : tcu::TextureFormat();
86*35238bceSAndroid Build Coastguard Worker         tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt);
87*35238bceSAndroid Build Coastguard Worker         bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
88*35238bceSAndroid Build Coastguard Worker         bool stencil =
89*35238bceSAndroid Build Coastguard Worker             depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
90*35238bceSAndroid Build Coastguard Worker         GradientShader gradShader(getFragmentOutputType(colorFmt));
91*35238bceSAndroid Build Coastguard Worker         FlatColorShader flatShader(getFragmentOutputType(colorFmt));
92*35238bceSAndroid Build Coastguard Worker         uint32_t gradShaderID           = getCurrentContext()->createProgram(&gradShader);
93*35238bceSAndroid Build Coastguard Worker         uint32_t flatShaderID           = getCurrentContext()->createProgram(&flatShader);
94*35238bceSAndroid Build Coastguard Worker         uint32_t msaaFbo                = 0;
95*35238bceSAndroid Build Coastguard Worker         uint32_t resolveFbo             = 0;
96*35238bceSAndroid Build Coastguard Worker         uint32_t msaaColorRbo           = 0;
97*35238bceSAndroid Build Coastguard Worker         uint32_t resolveColorRbo        = 0;
98*35238bceSAndroid Build Coastguard Worker         uint32_t msaaDepthStencilRbo    = 0;
99*35238bceSAndroid Build Coastguard Worker         uint32_t resolveDepthStencilRbo = 0;
100*35238bceSAndroid Build Coastguard Worker 
101*35238bceSAndroid Build Coastguard Worker         // Create framebuffers.
102*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 2; ndx++)
103*35238bceSAndroid Build Coastguard Worker         {
104*35238bceSAndroid Build Coastguard Worker             uint32_t &fbo             = ndx ? resolveFbo : msaaFbo;
105*35238bceSAndroid Build Coastguard Worker             uint32_t &colorRbo        = ndx ? resolveColorRbo : msaaColorRbo;
106*35238bceSAndroid Build Coastguard Worker             uint32_t &depthStencilRbo = ndx ? resolveDepthStencilRbo : msaaDepthStencilRbo;
107*35238bceSAndroid Build Coastguard Worker             int samples               = ndx ? 0 : m_numSamples;
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker             glGenRenderbuffers(1, &colorRbo);
110*35238bceSAndroid Build Coastguard Worker             glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
111*35238bceSAndroid Build Coastguard Worker             glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, m_colorFormat, m_size.x(), m_size.y());
112*35238bceSAndroid Build Coastguard Worker 
113*35238bceSAndroid Build Coastguard Worker             if (depth || stencil)
114*35238bceSAndroid Build Coastguard Worker             {
115*35238bceSAndroid Build Coastguard Worker                 glGenRenderbuffers(1, &depthStencilRbo);
116*35238bceSAndroid Build Coastguard Worker                 glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRbo);
117*35238bceSAndroid Build Coastguard Worker                 glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, m_depthStencilFormat, m_size.x(),
118*35238bceSAndroid Build Coastguard Worker                                                  m_size.y());
119*35238bceSAndroid Build Coastguard Worker             }
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker             glGenFramebuffers(1, &fbo);
122*35238bceSAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, fbo);
123*35238bceSAndroid Build Coastguard Worker             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
124*35238bceSAndroid Build Coastguard Worker             if (depth)
125*35238bceSAndroid Build Coastguard Worker                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
126*35238bceSAndroid Build Coastguard Worker             if (stencil)
127*35238bceSAndroid Build Coastguard Worker                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker             checkError();
130*35238bceSAndroid Build Coastguard Worker             checkFramebufferStatus(GL_FRAMEBUFFER);
131*35238bceSAndroid Build Coastguard Worker         }
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, msaaFbo);
134*35238bceSAndroid Build Coastguard Worker         glViewport(0, 0, m_size.x(), m_size.y());
135*35238bceSAndroid Build Coastguard Worker 
136*35238bceSAndroid Build Coastguard Worker         // Clear depth and stencil buffers.
137*35238bceSAndroid Build Coastguard Worker         glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker         // Fill MSAA fbo with gradient, depth = [-1..1]
140*35238bceSAndroid Build Coastguard Worker         glEnable(GL_DEPTH_TEST);
141*35238bceSAndroid Build Coastguard Worker         gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
142*35238bceSAndroid Build Coastguard Worker         sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
143*35238bceSAndroid Build Coastguard Worker 
144*35238bceSAndroid Build Coastguard Worker         // Render random-colored quads.
145*35238bceSAndroid Build Coastguard Worker         {
146*35238bceSAndroid Build Coastguard Worker             const int numQuads = 8;
147*35238bceSAndroid Build Coastguard Worker             de::Random rnd(9);
148*35238bceSAndroid Build Coastguard Worker 
149*35238bceSAndroid Build Coastguard Worker             glDepthFunc(GL_ALWAYS);
150*35238bceSAndroid Build Coastguard Worker             glEnable(GL_STENCIL_TEST);
151*35238bceSAndroid Build Coastguard Worker             glStencilFunc(GL_ALWAYS, 0, 0xffu);
152*35238bceSAndroid Build Coastguard Worker             glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
153*35238bceSAndroid Build Coastguard Worker 
154*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < numQuads; ndx++)
155*35238bceSAndroid Build Coastguard Worker             {
156*35238bceSAndroid Build Coastguard Worker                 float r  = rnd.getFloat();
157*35238bceSAndroid Build Coastguard Worker                 float g  = rnd.getFloat();
158*35238bceSAndroid Build Coastguard Worker                 float b  = rnd.getFloat();
159*35238bceSAndroid Build Coastguard Worker                 float a  = rnd.getFloat();
160*35238bceSAndroid Build Coastguard Worker                 float x0 = rnd.getFloat(-1.0f, 1.0f);
161*35238bceSAndroid Build Coastguard Worker                 float y0 = rnd.getFloat(-1.0f, 1.0f);
162*35238bceSAndroid Build Coastguard Worker                 float z0 = rnd.getFloat(-1.0f, 1.0f);
163*35238bceSAndroid Build Coastguard Worker                 float x1 = rnd.getFloat(-1.0f, 1.0f);
164*35238bceSAndroid Build Coastguard Worker                 float y1 = rnd.getFloat(-1.0f, 1.0f);
165*35238bceSAndroid Build Coastguard Worker                 float z1 = rnd.getFloat(-1.0f, 1.0f);
166*35238bceSAndroid Build Coastguard Worker 
167*35238bceSAndroid Build Coastguard Worker                 flatShader.setColor(*getCurrentContext(), flatShaderID,
168*35238bceSAndroid Build Coastguard Worker                                     Vec4(r, g, b, a) * (colorFmtInfo.valueMax - colorFmtInfo.valueMin) +
169*35238bceSAndroid Build Coastguard Worker                                         colorFmtInfo.valueMin);
170*35238bceSAndroid Build Coastguard Worker                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(x0, y0, z0), Vec3(x1, y1, z1));
171*35238bceSAndroid Build Coastguard Worker             }
172*35238bceSAndroid Build Coastguard Worker         }
173*35238bceSAndroid Build Coastguard Worker 
174*35238bceSAndroid Build Coastguard Worker         glDisable(GL_DEPTH_TEST);
175*35238bceSAndroid Build Coastguard Worker         glDisable(GL_STENCIL_TEST);
176*35238bceSAndroid Build Coastguard Worker         checkError();
177*35238bceSAndroid Build Coastguard Worker 
178*35238bceSAndroid Build Coastguard Worker         // Resolve using glBlitFramebuffer().
179*35238bceSAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
180*35238bceSAndroid Build Coastguard Worker         glBlitFramebuffer(0, 0, m_size.x(), m_size.y(), 0, 0, m_size.x(), m_size.y(),
181*35238bceSAndroid Build Coastguard Worker                           GL_COLOR_BUFFER_BIT | (depth ? GL_DEPTH_BUFFER_BIT : 0) |
182*35238bceSAndroid Build Coastguard Worker                               (stencil ? GL_STENCIL_BUFFER_BIT : 0),
183*35238bceSAndroid Build Coastguard Worker                           GL_NEAREST);
184*35238bceSAndroid Build Coastguard Worker 
185*35238bceSAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFbo);
186*35238bceSAndroid Build Coastguard Worker 
187*35238bceSAndroid Build Coastguard Worker         if (depth)
188*35238bceSAndroid Build Coastguard Worker         {
189*35238bceSAndroid Build Coastguard Worker             // Visualize depth.
190*35238bceSAndroid Build Coastguard Worker             const int numSteps = 8;
191*35238bceSAndroid Build Coastguard Worker             const float step   = 2.0f / (float)numSteps;
192*35238bceSAndroid Build Coastguard Worker 
193*35238bceSAndroid Build Coastguard Worker             glEnable(GL_DEPTH_TEST);
194*35238bceSAndroid Build Coastguard Worker             glDepthFunc(GL_LESS);
195*35238bceSAndroid Build Coastguard Worker             glDepthMask(GL_FALSE);
196*35238bceSAndroid Build Coastguard Worker             glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < numSteps; ndx++)
199*35238bceSAndroid Build Coastguard Worker             {
200*35238bceSAndroid Build Coastguard Worker                 float d = -1.0f + step * (float)ndx;
201*35238bceSAndroid Build Coastguard Worker                 float c = (float)ndx / (float)(numSteps - 1);
202*35238bceSAndroid Build Coastguard Worker 
203*35238bceSAndroid Build Coastguard Worker                 flatShader.setColor(*getCurrentContext(), flatShaderID,
204*35238bceSAndroid Build Coastguard Worker                                     Vec4(0.0f, 0.0f, c, 1.0f) * (colorFmtInfo.valueMax - colorFmtInfo.valueMin) +
205*35238bceSAndroid Build Coastguard Worker                                         colorFmtInfo.valueMin);
206*35238bceSAndroid Build Coastguard Worker                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, d), Vec3(1.0f, 1.0f, d));
207*35238bceSAndroid Build Coastguard Worker             }
208*35238bceSAndroid Build Coastguard Worker 
209*35238bceSAndroid Build Coastguard Worker             glDisable(GL_DEPTH_TEST);
210*35238bceSAndroid Build Coastguard Worker         }
211*35238bceSAndroid Build Coastguard Worker 
212*35238bceSAndroid Build Coastguard Worker         if (stencil)
213*35238bceSAndroid Build Coastguard Worker         {
214*35238bceSAndroid Build Coastguard Worker             // Visualize stencil.
215*35238bceSAndroid Build Coastguard Worker             const int numSteps = 4;
216*35238bceSAndroid Build Coastguard Worker             const int step     = 1;
217*35238bceSAndroid Build Coastguard Worker 
218*35238bceSAndroid Build Coastguard Worker             glEnable(GL_STENCIL_TEST);
219*35238bceSAndroid Build Coastguard Worker             glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
220*35238bceSAndroid Build Coastguard Worker             glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
221*35238bceSAndroid Build Coastguard Worker 
222*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < numSteps; ndx++)
223*35238bceSAndroid Build Coastguard Worker             {
224*35238bceSAndroid Build Coastguard Worker                 int s   = step * ndx;
225*35238bceSAndroid Build Coastguard Worker                 float c = (float)ndx / (float)(numSteps - 1);
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker                 glStencilFunc(GL_EQUAL, s, 0xffu);
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker                 flatShader.setColor(*getCurrentContext(), flatShaderID,
230*35238bceSAndroid Build Coastguard Worker                                     Vec4(0.0f, c, 0.0f, 1.0f) * (colorFmtInfo.valueMax - colorFmtInfo.valueMin) +
231*35238bceSAndroid Build Coastguard Worker                                         colorFmtInfo.valueMin);
232*35238bceSAndroid Build Coastguard Worker                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
233*35238bceSAndroid Build Coastguard Worker             }
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker             glDisable(GL_STENCIL_TEST);
236*35238bceSAndroid Build Coastguard Worker         }
237*35238bceSAndroid Build Coastguard Worker 
238*35238bceSAndroid Build Coastguard Worker         readPixels(dst, 0, 0, m_size.x(), m_size.y(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
239*35238bceSAndroid Build Coastguard Worker     }
240*35238bceSAndroid Build Coastguard Worker 
colorCompare(const tcu::Surface & reference,const tcu::Surface & result)241*35238bceSAndroid Build Coastguard Worker     bool colorCompare(const tcu::Surface &reference, const tcu::Surface &result)
242*35238bceSAndroid Build Coastguard Worker     {
243*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA threshold(tcu::max(getFormatThreshold(m_colorFormat), tcu::RGBA(12, 12, 12, 12)));
244*35238bceSAndroid Build Coastguard Worker 
245*35238bceSAndroid Build Coastguard Worker         return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(),
246*35238bceSAndroid Build Coastguard Worker                                     result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
247*35238bceSAndroid Build Coastguard Worker     }
248*35238bceSAndroid Build Coastguard Worker 
compare(const tcu::Surface & reference,const tcu::Surface & result)249*35238bceSAndroid Build Coastguard Worker     bool compare(const tcu::Surface &reference, const tcu::Surface &result)
250*35238bceSAndroid Build Coastguard Worker     {
251*35238bceSAndroid Build Coastguard Worker         if (m_depthStencilFormat != GL_NONE)
252*35238bceSAndroid Build Coastguard Worker             return FboTestCase::compare(reference, result);
253*35238bceSAndroid Build Coastguard Worker         else
254*35238bceSAndroid Build Coastguard Worker             return colorCompare(reference, result);
255*35238bceSAndroid Build Coastguard Worker     }
256*35238bceSAndroid Build Coastguard Worker 
257*35238bceSAndroid Build Coastguard Worker private:
258*35238bceSAndroid Build Coastguard Worker     uint32_t m_colorFormat;
259*35238bceSAndroid Build Coastguard Worker     uint32_t m_depthStencilFormat;
260*35238bceSAndroid Build Coastguard Worker     IVec2 m_size;
261*35238bceSAndroid Build Coastguard Worker     int m_numSamples;
262*35238bceSAndroid Build Coastguard Worker };
263*35238bceSAndroid Build Coastguard Worker 
264*35238bceSAndroid Build Coastguard Worker // Ported from WebGL [1], originally written to test a Qualcomm driver bug [2].
265*35238bceSAndroid Build Coastguard Worker // [1] https://github.com/KhronosGroup/WebGL/blob/main/sdk/tests/conformance2/renderbuffers/multisampled-renderbuffer-initialization.html
266*35238bceSAndroid Build Coastguard Worker // [2] http://crbug.com/696126
267*35238bceSAndroid Build Coastguard Worker class RenderbufferResizeCase : public ApiCase
268*35238bceSAndroid Build Coastguard Worker {
269*35238bceSAndroid Build Coastguard Worker public:
RenderbufferResizeCase(Context & context,const char * name,const char * desc,bool multisampled1,bool multisampled2)270*35238bceSAndroid Build Coastguard Worker     RenderbufferResizeCase(Context &context, const char *name, const char *desc, bool multisampled1, bool multisampled2)
271*35238bceSAndroid Build Coastguard Worker         : ApiCase(context, name, desc)
272*35238bceSAndroid Build Coastguard Worker         , m_multisampled1(multisampled1)
273*35238bceSAndroid Build Coastguard Worker         , m_multisampled2(multisampled2)
274*35238bceSAndroid Build Coastguard Worker     {
275*35238bceSAndroid Build Coastguard Worker     }
276*35238bceSAndroid Build Coastguard Worker 
277*35238bceSAndroid Build Coastguard Worker protected:
test()278*35238bceSAndroid Build Coastguard Worker     void test()
279*35238bceSAndroid Build Coastguard Worker     {
280*35238bceSAndroid Build Coastguard Worker         glDisable(GL_DEPTH_TEST);
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker         int maxSamples = 0;
283*35238bceSAndroid Build Coastguard Worker         glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &maxSamples);
284*35238bceSAndroid Build Coastguard Worker         uint32_t samp1 = m_multisampled1 ? maxSamples : 0;
285*35238bceSAndroid Build Coastguard Worker         uint32_t samp2 = m_multisampled2 ? maxSamples : 0;
286*35238bceSAndroid Build Coastguard Worker 
287*35238bceSAndroid Build Coastguard Worker         static const uint32_t W1 = 10, H1 = 10;
288*35238bceSAndroid Build Coastguard Worker         static const uint32_t W2 = 40, H2 = 40;
289*35238bceSAndroid Build Coastguard Worker 
290*35238bceSAndroid Build Coastguard Worker         // Set up non-multisampled buffer to blit to and read back from.
291*35238bceSAndroid Build Coastguard Worker         uint32_t fboResolve = 0;
292*35238bceSAndroid Build Coastguard Worker         uint32_t rboResolve = 0;
293*35238bceSAndroid Build Coastguard Worker         {
294*35238bceSAndroid Build Coastguard Worker             glGenFramebuffers(1, &fboResolve);
295*35238bceSAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, fboResolve);
296*35238bceSAndroid Build Coastguard Worker             glGenRenderbuffers(1, &rboResolve);
297*35238bceSAndroid Build Coastguard Worker             glBindRenderbuffer(GL_RENDERBUFFER, rboResolve);
298*35238bceSAndroid Build Coastguard Worker             glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, W2, H2);
299*35238bceSAndroid Build Coastguard Worker             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboResolve);
300*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
301*35238bceSAndroid Build Coastguard Worker             glClearBufferfv(GL_COLOR, 0, Vec4(1.0f, 0.0f, 0.0f, 1.0f).getPtr());
302*35238bceSAndroid Build Coastguard Worker         }
303*35238bceSAndroid Build Coastguard Worker         expectError(GL_NO_ERROR);
304*35238bceSAndroid Build Coastguard Worker 
305*35238bceSAndroid Build Coastguard Worker         // Set up multisampled buffer to test.
306*35238bceSAndroid Build Coastguard Worker         uint32_t fboMultisampled = 0;
307*35238bceSAndroid Build Coastguard Worker         uint32_t rboMultisampled = 0;
308*35238bceSAndroid Build Coastguard Worker         {
309*35238bceSAndroid Build Coastguard Worker             glGenFramebuffers(1, &fboMultisampled);
310*35238bceSAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, fboMultisampled);
311*35238bceSAndroid Build Coastguard Worker             glGenRenderbuffers(1, &rboMultisampled);
312*35238bceSAndroid Build Coastguard Worker             glBindRenderbuffer(GL_RENDERBUFFER, rboMultisampled);
313*35238bceSAndroid Build Coastguard Worker             // Allocate,
314*35238bceSAndroid Build Coastguard Worker             glRenderbufferStorageMultisample(GL_RENDERBUFFER, samp1, GL_RGBA8, W1, H1);
315*35238bceSAndroid Build Coastguard Worker             // attach,
316*35238bceSAndroid Build Coastguard Worker             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboMultisampled);
317*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
318*35238bceSAndroid Build Coastguard Worker             glClearBufferfv(GL_COLOR, 0, Vec4(0.0f, 0.0f, 1.0f, 1.0f).getPtr());
319*35238bceSAndroid Build Coastguard Worker             // and allocate again with different parameters.
320*35238bceSAndroid Build Coastguard Worker             glRenderbufferStorageMultisample(GL_RENDERBUFFER, samp2, GL_RGBA8, W2, H2);
321*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
322*35238bceSAndroid Build Coastguard Worker             glClearBufferfv(GL_COLOR, 0, Vec4(0.0f, 1.0f, 0.0f, 1.0f).getPtr());
323*35238bceSAndroid Build Coastguard Worker         }
324*35238bceSAndroid Build Coastguard Worker         expectError(GL_NO_ERROR);
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker         // This is a blit from the multisampled buffer to the non-multisampled buffer.
327*35238bceSAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMultisampled);
328*35238bceSAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboResolve);
329*35238bceSAndroid Build Coastguard Worker         // Blit color from fboMultisampled (should be green) to fboResolve (should currently be red).
330*35238bceSAndroid Build Coastguard Worker         glBlitFramebuffer(0, 0, W2, H2, 0, 0, W2, H2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
331*35238bceSAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
332*35238bceSAndroid Build Coastguard Worker         expectError(GL_NO_ERROR);
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker         // fboResolve should now be green.
335*35238bceSAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, fboResolve);
336*35238bceSAndroid Build Coastguard Worker         uint32_t pixels[W2 * H2] = {};
337*35238bceSAndroid Build Coastguard Worker         glReadPixels(0, 0, W2, H2, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
338*35238bceSAndroid Build Coastguard Worker         expectError(GL_NO_ERROR);
339*35238bceSAndroid Build Coastguard Worker 
340*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA threshold(tcu::max(getFormatThreshold(GL_RGBA8), tcu::RGBA(12, 12, 12, 12)));
341*35238bceSAndroid Build Coastguard Worker         for (uint32_t y = 0; y < H2; ++y)
342*35238bceSAndroid Build Coastguard Worker         {
343*35238bceSAndroid Build Coastguard Worker             for (uint32_t x = 0; x < W2; ++x)
344*35238bceSAndroid Build Coastguard Worker             {
345*35238bceSAndroid Build Coastguard Worker                 tcu::RGBA color(pixels[y * W2 + x]);
346*35238bceSAndroid Build Coastguard Worker                 TCU_CHECK(compareThreshold(color, tcu::RGBA::green(), threshold));
347*35238bceSAndroid Build Coastguard Worker             }
348*35238bceSAndroid Build Coastguard Worker         }
349*35238bceSAndroid Build Coastguard Worker     }
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker private:
352*35238bceSAndroid Build Coastguard Worker     bool m_multisampled1;
353*35238bceSAndroid Build Coastguard Worker     bool m_multisampled2;
354*35238bceSAndroid Build Coastguard Worker };
355*35238bceSAndroid Build Coastguard Worker 
FboMultisampleTests(Context & context)356*35238bceSAndroid Build Coastguard Worker FboMultisampleTests::FboMultisampleTests(Context &context) : TestCaseGroup(context, "msaa", "Multisample FBO tests")
357*35238bceSAndroid Build Coastguard Worker {
358*35238bceSAndroid Build Coastguard Worker }
359*35238bceSAndroid Build Coastguard Worker 
~FboMultisampleTests(void)360*35238bceSAndroid Build Coastguard Worker FboMultisampleTests::~FboMultisampleTests(void)
361*35238bceSAndroid Build Coastguard Worker {
362*35238bceSAndroid Build Coastguard Worker }
363*35238bceSAndroid Build Coastguard Worker 
init(void)364*35238bceSAndroid Build Coastguard Worker void FboMultisampleTests::init(void)
365*35238bceSAndroid Build Coastguard Worker {
366*35238bceSAndroid Build Coastguard Worker     static const uint32_t colorFormats[] = {// RGBA formats
367*35238bceSAndroid Build Coastguard Worker                                             GL_RGBA8, GL_SRGB8_ALPHA8, GL_RGB10_A2, GL_RGBA4, GL_RGB5_A1,
368*35238bceSAndroid Build Coastguard Worker 
369*35238bceSAndroid Build Coastguard Worker                                             // RGB formats
370*35238bceSAndroid Build Coastguard Worker                                             GL_RGB8, GL_RGB565,
371*35238bceSAndroid Build Coastguard Worker 
372*35238bceSAndroid Build Coastguard Worker                                             // RG formats
373*35238bceSAndroid Build Coastguard Worker                                             GL_RG8,
374*35238bceSAndroid Build Coastguard Worker 
375*35238bceSAndroid Build Coastguard Worker                                             // R formats
376*35238bceSAndroid Build Coastguard Worker                                             GL_R8,
377*35238bceSAndroid Build Coastguard Worker 
378*35238bceSAndroid Build Coastguard Worker                                             // GL_EXT_color_buffer_float
379*35238bceSAndroid Build Coastguard Worker                                             GL_RGBA32F, GL_RGBA16F, GL_R11F_G11F_B10F, GL_RG32F, GL_RG16F, GL_R32F,
380*35238bceSAndroid Build Coastguard Worker                                             GL_R16F};
381*35238bceSAndroid Build Coastguard Worker 
382*35238bceSAndroid Build Coastguard Worker     static const uint32_t depthStencilFormats[] = {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
383*35238bceSAndroid Build Coastguard Worker                                                    GL_DEPTH32F_STENCIL8,  GL_DEPTH24_STENCIL8,  GL_STENCIL_INDEX8};
384*35238bceSAndroid Build Coastguard Worker 
385*35238bceSAndroid Build Coastguard Worker     static const int sampleCounts[] = {2, 4, 8};
386*35238bceSAndroid Build Coastguard Worker 
387*35238bceSAndroid Build Coastguard Worker     for (int sampleCntNdx = 0; sampleCntNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCntNdx++)
388*35238bceSAndroid Build Coastguard Worker     {
389*35238bceSAndroid Build Coastguard Worker         int samples = sampleCounts[sampleCntNdx];
390*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *sampleCountGroup =
391*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, (de::toString(samples) + "_samples").c_str(), "");
392*35238bceSAndroid Build Coastguard Worker         addChild(sampleCountGroup);
393*35238bceSAndroid Build Coastguard Worker 
394*35238bceSAndroid Build Coastguard Worker         // Color formats.
395*35238bceSAndroid Build Coastguard Worker         for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
396*35238bceSAndroid Build Coastguard Worker             sampleCountGroup->addChild(new BasicFboMultisampleCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
397*35238bceSAndroid Build Coastguard Worker                                                                    colorFormats[fmtNdx], GL_NONE, IVec2(119, 131),
398*35238bceSAndroid Build Coastguard Worker                                                                    samples));
399*35238bceSAndroid Build Coastguard Worker 
400*35238bceSAndroid Build Coastguard Worker         // Depth/stencil formats.
401*35238bceSAndroid Build Coastguard Worker         for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++)
402*35238bceSAndroid Build Coastguard Worker             sampleCountGroup->addChild(
403*35238bceSAndroid Build Coastguard Worker                 new BasicFboMultisampleCase(m_context, getFormatName(depthStencilFormats[fmtNdx]), "", GL_RGBA8,
404*35238bceSAndroid Build Coastguard Worker                                             depthStencilFormats[fmtNdx], IVec2(119, 131), samples));
405*35238bceSAndroid Build Coastguard Worker     }
406*35238bceSAndroid Build Coastguard Worker 
407*35238bceSAndroid Build Coastguard Worker     // .renderbuffer_resize
408*35238bceSAndroid Build Coastguard Worker     {
409*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *group =
410*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "renderbuffer_resize", "Multisample renderbuffer resize");
411*35238bceSAndroid Build Coastguard Worker         addChild(group);
412*35238bceSAndroid Build Coastguard Worker 
413*35238bceSAndroid Build Coastguard Worker         {
414*35238bceSAndroid Build Coastguard Worker             group->addChild(new RenderbufferResizeCase(m_context, "nonms_to_nonms", "", false, false));
415*35238bceSAndroid Build Coastguard Worker             group->addChild(new RenderbufferResizeCase(m_context, "nonms_to_ms", "", false, true));
416*35238bceSAndroid Build Coastguard Worker             group->addChild(new RenderbufferResizeCase(m_context, "ms_to_nonms", "", true, false));
417*35238bceSAndroid Build Coastguard Worker             group->addChild(new RenderbufferResizeCase(m_context, "ms_to_ms", "", true, true));
418*35238bceSAndroid Build Coastguard Worker         }
419*35238bceSAndroid Build Coastguard Worker     }
420*35238bceSAndroid Build Coastguard Worker }
421*35238bceSAndroid Build Coastguard Worker 
422*35238bceSAndroid Build Coastguard Worker } // namespace Functional
423*35238bceSAndroid Build Coastguard Worker } // namespace gles3
424*35238bceSAndroid Build Coastguard Worker } // namespace deqp
425