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