CP: Remove two read-backs from copy image tests am: 263e135474
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglMultiContextTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2016 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 EGL multi context tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglMultiContextTests.hpp"
25
26 #include "egluUtil.hpp"
27 #include "egluUnique.hpp"
28 #include "egluStrUtil.hpp"
29 #include "egluConfigFilter.hpp"
30
31 #include "eglwLibrary.hpp"
32 #include "eglwEnums.hpp"
33
34 #include "gluDefs.hpp"
35
36 #include "glwFunctions.hpp"
37 #include "glwEnums.hpp"
38
39 #include "tcuResultCollector.hpp"
40 #include "tcuTestLog.hpp"
41
42 #include "deRandom.hpp"
43
44 #include <vector>
45
46 namespace deqp
47 {
48 namespace egl
49 {
50 namespace
51 {
52
53 using tcu::TestLog;
54
55 class MultiContextTest : public TestCase
56 {
57 public:
58         enum Use
59         {
60                 USE_NONE = 0,
61                 USE_MAKECURRENT,
62                 USE_CLEAR,
63
64                 USE_LAST
65         };
66
67         enum Sharing
68         {
69                 SHARING_NONE = 0,
70                 SHARING_SHARED,
71                 SHARING_LAST
72         };
73                                         MultiContextTest        (EglTestContext& eglTestCtx, Sharing sharing, Use use, const char* name, const char* description);
74
75         IterateResult   iterate                         (void);
76
77 private:
78         const Sharing   m_sharing;
79         const Use               m_use;
80 };
81
82 MultiContextTest::MultiContextTest (EglTestContext& eglTestCtx, Sharing sharing, Use use, const char* name, const char* description)
83         : TestCase      (eglTestCtx, name, description)
84         , m_sharing     (sharing)
85         , m_use         (use)
86 {
87 }
88
89 bool isES2Renderable (const eglu::CandidateConfig& c)
90 {
91         return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT;
92 }
93
94 eglw::EGLConfig getConfig (const eglw::Library& egl, eglw::EGLDisplay display)
95 {
96         eglu::FilterList filters;
97         filters << isES2Renderable;
98         return eglu::chooseSingleConfig(egl, display, filters);
99 }
100
101 tcu::TestCase::IterateResult MultiContextTest::iterate (void)
102 {
103         const deUint32                                  seed                    = m_sharing == SHARING_SHARED ? 2498541716u : 8825414;
104         const size_t                                    maxContextCount = 128;
105         const size_t                                    minContextCount = 32;
106         const eglw::EGLint                              attribList[]    =
107         {
108                 EGL_CONTEXT_CLIENT_VERSION, 2,
109                 EGL_NONE
110         };
111         const eglw::EGLint                              pbufferAttribList[]     =
112         {
113                 EGL_WIDTH,      64,
114                 EGL_HEIGHT,     64,
115                 EGL_NONE
116         };
117
118         TestLog&                                                log                             = m_testCtx.getLog();
119         tcu::ResultCollector                    resultCollector (log);
120         de::Random                                              rng                             (seed);
121
122         const eglw::Library&                    egl                             = m_eglTestCtx.getLibrary();
123         const eglu::UniqueDisplay               display                 (egl, eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay()));
124         const eglw::EGLConfig                   config                  = getConfig(egl, *display);
125
126         const eglu::UniqueSurface               surface                 (egl, *display, m_use != USE_NONE ? egl.createPbufferSurface(*display, config, pbufferAttribList) : EGL_NO_SURFACE);
127         EGLU_CHECK_MSG(egl, "Failed to create pbuffer.");
128
129         std::vector<eglw::EGLContext>   contexts;
130         glw::Functions                                  gl;
131
132         contexts.reserve(maxContextCount);
133
134         log << TestLog::Message << "Trying to create " << maxContextCount << (m_sharing == SHARING_SHARED ? " shared " : " ") << "contexts." << TestLog::EndMessage;
135         log << TestLog::Message << "Requiring that at least " << minContextCount << " contexts can be created." << TestLog::EndMessage;
136
137         if (m_use == USE_CLEAR)
138                 m_eglTestCtx.initGLFunctions(&gl, glu::ApiType::es(2,0));
139
140         EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));
141
142         try
143         {
144                 for (size_t contextCount = 0; contextCount < maxContextCount; contextCount++)
145                 {
146                         const eglw::EGLContext  sharedContext   = (m_sharing == SHARING_SHARED && contextCount > 0 ? contexts[rng.getUint32() % (deUint32)contextCount] : EGL_NO_CONTEXT);
147                         const eglw::EGLContext  context                 = egl.createContext(*display, config, sharedContext, attribList);
148                         const eglw::EGLint              error                   = egl.getError();
149
150                         if (context == EGL_NO_CONTEXT || error != EGL_SUCCESS)
151                         {
152                                 log << TestLog::Message << "Got error after creating " << contextCount << " contexts." << TestLog::EndMessage;
153
154                                 if (error == EGL_BAD_ALLOC)
155                                 {
156                                         if (contextCount < minContextCount)
157                                                 resultCollector.fail("Couldn't create the minimum number of contexts required.");
158                                         else
159                                                 log << TestLog::Message << "Got EGL_BAD_ALLOC." << TestLog::EndMessage;
160                                 }
161                                 else
162                                         resultCollector.fail("eglCreateContext() produced error that is not EGL_BAD_ALLOC: " + eglu::getErrorStr(error).toString());
163
164                                 if (context != EGL_NO_CONTEXT)
165                                         resultCollector.fail("eglCreateContext() produced error, but context is not EGL_NO_CONTEXT");
166
167                                 break;
168                         }
169                         else
170                         {
171                                 contexts.push_back(context);
172
173                                 if (m_use == USE_MAKECURRENT || m_use == USE_CLEAR)
174                                 {
175                                         const eglw::EGLBoolean  result                          = egl.makeCurrent(*display, *surface, *surface, context);
176                                         const eglw::EGLint              makeCurrentError        = egl.getError();
177
178                                         if (!result || makeCurrentError != EGL_SUCCESS)
179                                         {
180                                                 log << TestLog::Message << "Failed to make " << (contextCount + 1) << "th context current: " << eglu::getErrorStr(makeCurrentError) << TestLog::EndMessage;
181                                                 resultCollector.fail("Failed to make context current");
182
183                                                 break;
184                                         }
185                                         else if (m_use == USE_CLEAR)
186                                         {
187                                                 gl.clearColor(0.25f, 0.75f, 0.50f, 1.00f);
188                                                 gl.clear(GL_COLOR_BUFFER_BIT);
189                                                 gl.finish();
190                                                 GLU_CHECK_GLW_MSG(gl, "Failed to clear color.");
191                                         }
192                                 }
193                         }
194                 }
195
196                 for (size_t contextNdx = 0; contextNdx < contexts.size(); contextNdx++)
197                 {
198                         EGLU_CHECK_CALL(egl, destroyContext(*display, contexts[contextNdx]));
199                         contexts[contextNdx] = EGL_NO_CONTEXT;
200                 }
201
202                 if (m_use == USE_MAKECURRENT || m_use == USE_CLEAR)
203                         EGLU_CHECK_CALL(egl, makeCurrent(*display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
204         }
205         catch (...)
206         {
207                 for (size_t contextNdx = 0; contextNdx < contexts.size(); contextNdx++)
208                 {
209                         if (contexts[contextNdx] != EGL_NO_CONTEXT)
210                                 EGLU_CHECK_CALL(egl, destroyContext(*display, contexts[contextNdx]));
211                 }
212
213                 if (m_use == USE_MAKECURRENT || m_use == USE_CLEAR)
214                         EGLU_CHECK_CALL(egl, makeCurrent(*display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
215
216                 throw;
217         }
218
219         resultCollector.setTestContextResult(m_testCtx);
220         return STOP;
221 }
222
223 } // anonymous
224
225 TestCaseGroup* createMultiContextTests (EglTestContext& eglTestCtx)
226 {
227         de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "multicontext", "EGL multi context tests."));
228
229         group->addChild(new MultiContextTest(eglTestCtx, MultiContextTest::SHARING_NONE,        MultiContextTest::USE_NONE,                     "non_shared",                           "Create multiple non-shared contexts."));
230         group->addChild(new MultiContextTest(eglTestCtx, MultiContextTest::SHARING_SHARED,      MultiContextTest::USE_NONE,             "shared",                                       "Create multiple shared contexts."));
231
232         group->addChild(new MultiContextTest(eglTestCtx, MultiContextTest::SHARING_NONE,        MultiContextTest::USE_MAKECURRENT,      "non_shared_make_current",      "Create multiple non-shared contexts."));
233         group->addChild(new MultiContextTest(eglTestCtx, MultiContextTest::SHARING_SHARED,      MultiContextTest::USE_MAKECURRENT,      "shared_make_current",          "Create multiple shared contexts."));
234
235         group->addChild(new MultiContextTest(eglTestCtx, MultiContextTest::SHARING_NONE,        MultiContextTest::USE_CLEAR,            "non_shared_clear",                     "Create multiple non-shared contexts."));
236         group->addChild(new MultiContextTest(eglTestCtx, MultiContextTest::SHARING_SHARED,      MultiContextTest::USE_CLEAR,            "shared_clear",                         "Create multiple shared contexts."));
237
238         return group.release();
239 }
240
241 } // egl
242 } // deqp