Merge "Fix color change verification in dithering tests" into nougat-cts-dev am:...
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fFboMultisampleTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief FBO multisample tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es3fFboMultisampleTests.hpp"
25 #include "es3fFboTestCase.hpp"
26 #include "es3fFboTestUtil.hpp"
27 #include "gluTextureUtil.hpp"
28 #include "tcuImageCompare.hpp"
29 #include "tcuTextureUtil.hpp"
30 #include "tcuTestLog.hpp"
31 #include "deStringUtil.hpp"
32 #include "deRandom.hpp"
33 #include "sglrContextUtil.hpp"
34 #include "glwEnums.hpp"
35
36 namespace deqp
37 {
38 namespace gles3
39 {
40 namespace Functional
41 {
42
43 using std::string;
44 using tcu::TestLog;
45 using tcu::Vec2;
46 using tcu::Vec3;
47 using tcu::Vec4;
48 using tcu::IVec2;
49 using tcu::IVec3;
50 using tcu::IVec4;
51 using tcu::UVec4;
52 using namespace FboTestUtil;
53
54 class BasicFboMultisampleCase : public FboTestCase
55 {
56 public:
57         BasicFboMultisampleCase (Context& context, const char* name, const char* desc, deUint32 colorFormat, deUint32 depthStencilFormat, const IVec2& size, int numSamples)
58                 : FboTestCase                   (context, name, desc)
59                 , m_colorFormat                 (colorFormat)
60                 , m_depthStencilFormat  (depthStencilFormat)
61                 , m_size                                (size)
62                 , m_numSamples                  (numSamples)
63         {
64         }
65
66 protected:
67         void preCheck (void)
68         {
69                 checkFormatSupport      (m_colorFormat);
70                 checkSampleCount        (m_colorFormat, m_numSamples);
71
72                 if (m_depthStencilFormat != GL_NONE)
73                 {
74                         checkFormatSupport      (m_depthStencilFormat);
75                         checkSampleCount        (m_depthStencilFormat, m_numSamples);
76                 }
77         }
78
79         void render (tcu::Surface& dst)
80         {
81                 tcu::TextureFormat              colorFmt                                = glu::mapGLInternalFormat(m_colorFormat);
82                 tcu::TextureFormat              depthStencilFmt                 = m_depthStencilFormat != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFormat) : tcu::TextureFormat();
83                 tcu::TextureFormatInfo  colorFmtInfo                    = tcu::getTextureFormatInfo(colorFmt);
84                 bool                                    depth                                   = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
85                 bool                                    stencil                                 = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
86                 GradientShader                  gradShader                              (getFragmentOutputType(colorFmt));
87                 FlatColorShader                 flatShader                              (getFragmentOutputType(colorFmt));
88                 deUint32                                gradShaderID                    = getCurrentContext()->createProgram(&gradShader);
89                 deUint32                                flatShaderID                    = getCurrentContext()->createProgram(&flatShader);
90                 deUint32                                msaaFbo                                 = 0;
91                 deUint32                                resolveFbo                              = 0;
92                 deUint32                                msaaColorRbo                    = 0;
93                 deUint32                                resolveColorRbo                 = 0;
94                 deUint32                                msaaDepthStencilRbo             = 0;
95                 deUint32                                resolveDepthStencilRbo  = 0;
96
97                 // Create framebuffers.
98                 for (int ndx = 0; ndx < 2; ndx++)
99                 {
100                         deUint32&       fbo                             = ndx ? resolveFbo                              : msaaFbo;
101                         deUint32&       colorRbo                = ndx ? resolveColorRbo                 : msaaColorRbo;
102                         deUint32&       depthStencilRbo = ndx ? resolveDepthStencilRbo  : msaaDepthStencilRbo;
103                         int                     samples                 = ndx ? 0                                               : m_numSamples;
104
105                         glGenRenderbuffers(1, &colorRbo);
106                         glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
107                         glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, m_colorFormat, m_size.x(), m_size.y());
108
109                         if (depth || stencil)
110                         {
111                                 glGenRenderbuffers(1, &depthStencilRbo);
112                                 glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRbo);
113                                 glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, m_depthStencilFormat, m_size.x(), m_size.y());
114                         }
115
116                         glGenFramebuffers(1, &fbo);
117                         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
118                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
119                         if (depth)
120                                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
121                         if (stencil)
122                                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
123
124                         checkError();
125                         checkFramebufferStatus(GL_FRAMEBUFFER);
126                 }
127
128                 glBindFramebuffer(GL_FRAMEBUFFER, msaaFbo);
129                 glViewport(0, 0, m_size.x(), m_size.y());
130
131                 // Clear depth and stencil buffers.
132                 glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
133
134                 // Fill MSAA fbo with gradient, depth = [-1..1]
135                 glEnable(GL_DEPTH_TEST);
136                 gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
137                 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
138
139                 // Render random-colored quads.
140                 {
141                         const int               numQuads        = 8;
142                         de::Random              rnd                     (9);
143
144                         glDepthFunc(GL_ALWAYS);
145                         glEnable(GL_STENCIL_TEST);
146                         glStencilFunc(GL_ALWAYS, 0, 0xffu);
147                         glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
148
149                         for (int ndx = 0; ndx < numQuads; ndx++)
150                         {
151                                 float   r               = rnd.getFloat();
152                                 float   g               = rnd.getFloat();
153                                 float   b               = rnd.getFloat();
154                                 float   a               = rnd.getFloat();
155                                 float   x0              = rnd.getFloat(-1.0f, 1.0f);
156                                 float   y0              = rnd.getFloat(-1.0f, 1.0f);
157                                 float   z0              = rnd.getFloat(-1.0f, 1.0f);
158                                 float   x1              = rnd.getFloat(-1.0f, 1.0f);
159                                 float   y1              = rnd.getFloat(-1.0f, 1.0f);
160                                 float   z1              = rnd.getFloat(-1.0f, 1.0f);
161
162                                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(r,g,b,a) * (colorFmtInfo.valueMax-colorFmtInfo.valueMin) + colorFmtInfo.valueMin);
163                                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(x0, y0, z0), Vec3(x1, y1, z1));
164                         }
165                 }
166
167                 glDisable(GL_DEPTH_TEST);
168                 glDisable(GL_STENCIL_TEST);
169                 checkError();
170
171                 // Resolve using glBlitFramebuffer().
172                 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
173                 glBlitFramebuffer(0, 0, m_size.x(), m_size.y(), 0, 0, m_size.x(), m_size.y(), GL_COLOR_BUFFER_BIT | (depth ? GL_DEPTH_BUFFER_BIT : 0) | (stencil ? GL_STENCIL_BUFFER_BIT : 0), GL_NEAREST);
174
175                 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFbo);
176
177                 if (depth)
178                 {
179                         // Visualize depth.
180                         const int       numSteps        = 8;
181                         const float     step            = 2.0f / (float)numSteps;
182
183                         glEnable(GL_DEPTH_TEST);
184                         glDepthFunc(GL_LESS);
185                         glDepthMask(GL_FALSE);
186                         glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
187
188                         for (int ndx = 0; ndx < numSteps; ndx++)
189                         {
190                                 float d = -1.0f + step*(float)ndx;
191                                 float c = (float)ndx / (float)(numSteps-1);
192
193                                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, c, 1.0f) * (colorFmtInfo.valueMax-colorFmtInfo.valueMin) + colorFmtInfo.valueMin);
194                                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, d), Vec3(1.0f, 1.0f, d));
195                         }
196
197                         glDisable(GL_DEPTH_TEST);
198                 }
199
200                 if (stencil)
201                 {
202                         // Visualize stencil.
203                         const int       numSteps        = 4;
204                         const int       step            = 1;
205
206                         glEnable(GL_STENCIL_TEST);
207                         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
208                         glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
209
210                         for (int ndx = 0; ndx < numSteps; ndx++)
211                         {
212                                 int             s       = step*ndx;
213                                 float   c       = (float)ndx / (float)(numSteps-1);
214
215                                 glStencilFunc(GL_EQUAL, s, 0xffu);
216
217                                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, c, 0.0f, 1.0f) * (colorFmtInfo.valueMax-colorFmtInfo.valueMin) + colorFmtInfo.valueMin);
218                                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
219                         }
220
221                         glDisable(GL_STENCIL_TEST);
222                 }
223
224                 readPixels(dst, 0, 0, m_size.x(), m_size.y(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
225         }
226
227         bool colorCompare (const tcu::Surface& reference, const tcu::Surface& result)
228         {
229                 const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_colorFormat), tcu::RGBA(12, 12, 12, 12)));
230
231                 return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
232         }
233
234         bool compare (const tcu::Surface& reference, const tcu::Surface& result)
235         {
236                 if (m_depthStencilFormat != GL_NONE)
237                         return FboTestCase::compare(reference, result);
238                 else
239                         return colorCompare(reference, result);
240         }
241
242 private:
243         deUint32        m_colorFormat;
244         deUint32        m_depthStencilFormat;
245         IVec2           m_size;
246         int                     m_numSamples;
247 };
248
249 FboMultisampleTests::FboMultisampleTests (Context& context)
250         : TestCaseGroup(context, "msaa", "Multisample FBO tests")
251 {
252 }
253
254 FboMultisampleTests::~FboMultisampleTests (void)
255 {
256 }
257
258 void FboMultisampleTests::init (void)
259 {
260         static const deUint32 colorFormats[] =
261         {
262                 // RGBA formats
263                 GL_RGBA8,
264                 GL_SRGB8_ALPHA8,
265                 GL_RGB10_A2,
266                 GL_RGBA4,
267                 GL_RGB5_A1,
268
269                 // RGB formats
270                 GL_RGB8,
271                 GL_RGB565,
272
273                 // RG formats
274                 GL_RG8,
275
276                 // R formats
277                 GL_R8,
278
279                 // GL_EXT_color_buffer_float
280                 GL_RGBA32F,
281                 GL_RGBA16F,
282                 GL_R11F_G11F_B10F,
283                 GL_RG32F,
284                 GL_RG16F,
285                 GL_R32F,
286                 GL_R16F
287         };
288
289         static const deUint32 depthStencilFormats[] =
290         {
291                 GL_DEPTH_COMPONENT32F,
292                 GL_DEPTH_COMPONENT24,
293                 GL_DEPTH_COMPONENT16,
294                 GL_DEPTH32F_STENCIL8,
295                 GL_DEPTH24_STENCIL8,
296                 GL_STENCIL_INDEX8
297         };
298
299         static const int sampleCounts[] = { 2, 4, 8 };
300
301         for (int sampleCntNdx = 0; sampleCntNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCntNdx++)
302         {
303                 int                                     samples                         = sampleCounts[sampleCntNdx];
304                 tcu::TestCaseGroup*     sampleCountGroup        = new tcu::TestCaseGroup(m_testCtx, (de::toString(samples) + "_samples").c_str(), "");
305                 addChild(sampleCountGroup);
306
307                 // Color formats.
308                 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
309                         sampleCountGroup->addChild(new BasicFboMultisampleCase(m_context, getFormatName(colorFormats[fmtNdx]), "", colorFormats[fmtNdx], GL_NONE, IVec2(119, 131), samples));
310
311                 // Depth/stencil formats.
312                 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++)
313                         sampleCountGroup->addChild(new BasicFboMultisampleCase(m_context, getFormatName(depthStencilFormats[fmtNdx]), "", GL_RGBA8, depthStencilFormats[fmtNdx], IVec2(119, 131), samples));
314         }
315 }
316
317 } // Functional
318 } // gles3
319 } // deqp