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