Fix PIPELINE_STAGE_TOP_OF_PIPE_BIT usage in api tests
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fFboTestCase.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 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 Base class for FBO tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es31fFboTestCase.hpp"
25 #include "es31fFboTestUtil.hpp"
26 #include "tcuTestLog.hpp"
27 #include "tcuImageCompare.hpp"
28 #include "tcuRenderTarget.hpp"
29 #include "sglrGLContext.hpp"
30 #include "sglrReferenceContext.hpp"
31 #include "gluStrUtil.hpp"
32 #include "gluContextInfo.hpp"
33 #include "deRandom.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36
37 #include <algorithm>
38
39 namespace deqp
40 {
41 namespace gles31
42 {
43 namespace Functional
44 {
45
46 using tcu::TestLog;
47 using std::string;
48
49 FboTestCase::FboTestCase (Context& context, const char* name, const char* description, bool useScreenSizedViewport)
50         : TestCase                      (context, name, description)
51         , m_viewportWidth       (useScreenSizedViewport ? context.getRenderTarget().getWidth() : 128)
52         , m_viewportHeight      (useScreenSizedViewport ? context.getRenderTarget().getHeight() : 128)
53 {
54 }
55
56 FboTestCase::~FboTestCase (void)
57 {
58 }
59
60 FboTestCase::IterateResult FboTestCase::iterate (void)
61 {
62         glu::RenderContext&                     renderCtx               = TestCase::m_context.getRenderContext();
63         const tcu::RenderTarget&        renderTarget    = renderCtx.getRenderTarget();
64         TestLog&                                        log                             = m_testCtx.getLog();
65
66         // Viewport.
67         de::Random                                      rnd                             (deStringHash(getName()));
68         int                                                     width                   = deMin32(renderTarget.getWidth(),      m_viewportWidth);
69         int                                                     height                  = deMin32(renderTarget.getHeight(),     m_viewportHeight);
70         int                                                     x                               = rnd.getInt(0, renderTarget.getWidth()         - width);
71         int                                                     y                               = rnd.getInt(0, renderTarget.getHeight()        - height);
72
73         // Surface format and storage is choosen by render().
74         tcu::Surface                            reference;
75         tcu::Surface                            result;
76
77         // Call preCheck() that can throw exception if some requirement is not met.
78         preCheck();
79
80         log << TestLog::Message << "Rendering with GL driver" << TestLog::EndMessage;
81
82         // Render using GLES3.1
83         try
84         {
85                 sglr::GLContext context(renderCtx, log, 0, tcu::IVec4(x, y, width, height));
86                 setContext(&context);
87                 render(result);
88
89                 // Check error.
90                 deUint32 err = glGetError();
91                 if (err != GL_NO_ERROR)
92                         throw glu::Error(err, glu::getErrorStr(err).toString().c_str(), DE_NULL, __FILE__, __LINE__);
93
94                 setContext(DE_NULL);
95         }
96         catch (const FboTestUtil::FboIncompleteException& e)
97         {
98                 if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED)
99                 {
100                         log << e;
101                         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
102                         return STOP;
103                 }
104                 else
105                         throw;
106         }
107
108         log << TestLog::Message << "Rendering reference image" << TestLog::EndMessage;
109
110         // Render reference.
111         {
112                 sglr::ReferenceContextBuffers   buffers (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height);
113                 sglr::ReferenceContext                  context (sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
114
115                 setContext(&context);
116                 render(reference);
117                 setContext(DE_NULL);
118         }
119
120         bool isOk = compare(reference, result);
121         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS      : QP_TEST_RESULT_FAIL,
122                                                         isOk ? "Pass"                           : "Image comparison failed");
123         return STOP;
124 }
125
126 bool FboTestCase::compare (const tcu::Surface& reference, const tcu::Surface& result)
127 {
128         return tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference, result, 0.05f, tcu::COMPARE_LOG_RESULT);
129 }
130
131 void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height, const tcu::TextureFormat& format, const tcu::Vec4& scale, const tcu::Vec4& bias)
132 {
133         FboTestUtil::readPixels(*getCurrentContext(), dst, x, y, width, height, format, scale, bias);
134 }
135
136 void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
137 {
138         getCurrentContext()->readPixels(dst, x, y, width, height);
139 }
140
141 void FboTestCase::checkFramebufferStatus (deUint32 target)
142 {
143         deUint32 status = glCheckFramebufferStatus(target);
144         if (status != GL_FRAMEBUFFER_COMPLETE)
145                 throw FboTestUtil::FboIncompleteException(status, __FILE__, __LINE__);
146 }
147
148 void FboTestCase::checkError (void)
149 {
150         deUint32 err = glGetError();
151         if (err != GL_NO_ERROR)
152                 throw glu::Error((int)err, (string("Got ") + glu::getErrorStr(err).toString()).c_str(), DE_NULL, __FILE__, __LINE__);
153 }
154
155 static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext)
156 {
157         const bool supportsES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
158         switch (format)
159         {
160                 // Color-renderable formats
161                 case GL_RGBA32I:
162                 case GL_RGBA32UI:
163                 case GL_RGBA16I:
164                 case GL_RGBA16UI:
165                 case GL_RGBA8:
166                 case GL_RGBA8I:
167                 case GL_RGBA8UI:
168                 case GL_SRGB8_ALPHA8:
169                 case GL_RGB10_A2:
170                 case GL_RGB10_A2UI:
171                 case GL_RGBA4:
172                 case GL_RGB5_A1:
173                 case GL_RGB8:
174                 case GL_RGB565:
175                 case GL_RG32I:
176                 case GL_RG32UI:
177                 case GL_RG16I:
178                 case GL_RG16UI:
179                 case GL_RG8:
180                 case GL_RG8I:
181                 case GL_RG8UI:
182                 case GL_R32I:
183                 case GL_R32UI:
184                 case GL_R16I:
185                 case GL_R16UI:
186                 case GL_R8:
187                 case GL_R8I:
188                 case GL_R8UI:
189                         return true;
190
191                 // Depth formats
192                 case GL_DEPTH_COMPONENT32F:
193                 case GL_DEPTH_COMPONENT24:
194                 case GL_DEPTH_COMPONENT16:
195                         return true;
196
197                 // Depth+stencil formats
198                 case GL_DEPTH32F_STENCIL8:
199                 case GL_DEPTH24_STENCIL8:
200                         return true;
201
202                 // Stencil formats
203                 case GL_STENCIL_INDEX8:
204                         return true;
205
206                 // Float format
207                 case GL_RGBA32F:
208                 case GL_R11F_G11F_B10F:
209                 case GL_RG32F:
210                 case GL_R32F:
211                 case GL_RGBA16F:
212                 case GL_RG16F:
213                 case GL_R16F:
214                         return supportsES32;
215
216                 default:
217                         return false;
218         }
219 }
220
221 static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext)
222 {
223         const bool                                      supportsES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
224         std::vector<std::string>        out;
225
226         DE_ASSERT(!isRequiredFormat(format, renderContext));
227
228         switch (format)
229         {
230                 case GL_RGB16F:
231                         out.push_back("GL_EXT_color_buffer_half_float");
232                         break;
233
234                 case GL_RGB32F:
235                         out.push_back("GL_EXT_color_buffer_float");
236                         break;
237
238                 case GL_RGBA16F:
239                 case GL_RG16F:
240                 case GL_R16F:
241                         if (!supportsES32)
242                                 out.push_back("GL_EXT_color_buffer_half_float");
243                         break;
244
245                 case GL_RGBA32F:
246                 case GL_R11F_G11F_B10F:
247                 case GL_RG32F:
248                 case GL_R32F:
249                         if (!supportsES32)
250                                 out.push_back("GL_EXT_color_buffer_float");
251                         break;
252
253                 default:
254                         break;
255         }
256
257         return out;
258 }
259
260 static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
261 {
262         for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
263         {
264                 const std::string& extension = *iter;
265
266                 if (context.getContextInfo().isExtensionSupported(extension.c_str()))
267                         return true;
268         }
269
270         return false;
271 }
272
273 void FboTestCase::checkFormatSupport (deUint32 sizedFormat)
274 {
275         const bool                                              isCoreFormat    = isRequiredFormat(sizedFormat, m_context.getRenderContext());
276         const std::vector<std::string>  requiredExts    = (!isCoreFormat) ? getEnablingExtensions(sizedFormat, m_context.getRenderContext()) : std::vector<std::string>();
277
278         // Check that we don't try to use invalid formats.
279         DE_ASSERT(isCoreFormat || !requiredExts.empty());
280
281         if (!requiredExts.empty() && !isAnyExtensionSupported(m_context, requiredExts))
282                 throw tcu::NotSupportedError("Format not supported");
283 }
284
285 static int getMinimumSampleCount (deUint32 format)
286 {
287         switch (format)
288         {
289                 // Core formats
290                 case GL_RGBA32I:
291                 case GL_RGBA32UI:
292                 case GL_RGBA16I:
293                 case GL_RGBA16UI:
294                 case GL_RGBA8:
295                 case GL_RGBA8I:
296                 case GL_RGBA8UI:
297                 case GL_SRGB8_ALPHA8:
298                 case GL_RGB10_A2:
299                 case GL_RGB10_A2UI:
300                 case GL_RGBA4:
301                 case GL_RGB5_A1:
302                 case GL_RGB8:
303                 case GL_RGB565:
304                 case GL_RG32I:
305                 case GL_RG32UI:
306                 case GL_RG16I:
307                 case GL_RG16UI:
308                 case GL_RG8:
309                 case GL_RG8I:
310                 case GL_RG8UI:
311                 case GL_R32I:
312                 case GL_R32UI:
313                 case GL_R16I:
314                 case GL_R16UI:
315                 case GL_R8:
316                 case GL_R8I:
317                 case GL_R8UI:
318                 case GL_DEPTH_COMPONENT32F:
319                 case GL_DEPTH_COMPONENT24:
320                 case GL_DEPTH_COMPONENT16:
321                 case GL_DEPTH32F_STENCIL8:
322                 case GL_DEPTH24_STENCIL8:
323                 case GL_STENCIL_INDEX8:
324                         return 4;
325
326                 // GL_EXT_color_buffer_float
327                 case GL_R11F_G11F_B10F:
328                 case GL_RG16F:
329                 case GL_R16F:
330                         return 4;
331
332                 case GL_RGBA32F:
333                 case GL_RGBA16F:
334                 case GL_RG32F:
335                 case GL_R32F:
336                         return 0;
337
338                 // GL_EXT_color_buffer_half_float
339                 case GL_RGB16F:
340                         return 0;
341
342                 default:
343                         DE_FATAL("Unknown format");
344                         return 0;
345         }
346 }
347
348 static std::vector<int> querySampleCounts (const glw::Functions& gl, deUint32 format)
349 {
350         int                                     numSampleCounts         = 0;
351         std::vector<int>        sampleCounts;
352
353         gl.getInternalformativ(GL_RENDERBUFFER, format, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts);
354
355         if (numSampleCounts > 0)
356         {
357                 sampleCounts.resize(numSampleCounts);
358                 gl.getInternalformativ(GL_RENDERBUFFER, format, GL_SAMPLES, (glw::GLsizei)sampleCounts.size(), &sampleCounts[0]);
359         }
360
361         GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query sample counts for format");
362
363         return sampleCounts;
364 }
365
366 void FboTestCase::checkSampleCount (deUint32 sizedFormat, int numSamples)
367 {
368         const int minSampleCount = getMinimumSampleCount(sizedFormat);
369
370         if (numSamples > minSampleCount)
371         {
372                 // Exceeds spec-mandated minimum - need to check.
373                 const std::vector<int> supportedSampleCounts = querySampleCounts(m_context.getRenderContext().getFunctions(), sizedFormat);
374
375                 if (std::find(supportedSampleCounts.begin(), supportedSampleCounts.end(), numSamples) == supportedSampleCounts.end())
376                         throw tcu::NotSupportedError("Sample count not supported");
377         }
378 }
379
380 void FboTestCase::clearColorBuffer (const tcu::TextureFormat& format, const tcu::Vec4& value)
381 {
382         FboTestUtil::clearColorBuffer(*getCurrentContext(), format, value);
383 }
384
385 } // Functional
386 } // gles31
387 } // deqp