1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core
3e5c31af7Sopenharmony_ci * ----------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2015 Intel Corporation
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief surfaceless platform
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "tcuSurfacelessPlatform.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include <string>
27e5c31af7Sopenharmony_ci#include <vector>
28e5c31af7Sopenharmony_ci#include <sys/utsname.h>
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_ci#include "deDynamicLibrary.hpp"
31e5c31af7Sopenharmony_ci#include "deMemory.h"
32e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp"
33e5c31af7Sopenharmony_ci#include "egluUtil.hpp"
34e5c31af7Sopenharmony_ci#include "egluGLUtil.hpp"
35e5c31af7Sopenharmony_ci#include "eglwEnums.hpp"
36e5c31af7Sopenharmony_ci#include "eglwLibrary.hpp"
37e5c31af7Sopenharmony_ci#include "gluPlatform.hpp"
38e5c31af7Sopenharmony_ci#include "gluRenderConfig.hpp"
39e5c31af7Sopenharmony_ci#include "glwInitES20Direct.hpp"
40e5c31af7Sopenharmony_ci#include "glwInitES30Direct.hpp"
41e5c31af7Sopenharmony_ci#include "glwInitFunctions.hpp"
42e5c31af7Sopenharmony_ci#include "tcuFunctionLibrary.hpp"
43e5c31af7Sopenharmony_ci#include "tcuPixelFormat.hpp"
44e5c31af7Sopenharmony_ci#include "tcuPlatform.hpp"
45e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
46e5c31af7Sopenharmony_ci#include "vkPlatform.hpp"
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_ci#include <EGL/egl.h>
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_ciusing std::string;
51e5c31af7Sopenharmony_ciusing std::vector;
52e5c31af7Sopenharmony_ci
53e5c31af7Sopenharmony_ci#if !defined(EGL_KHR_create_context)
54e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_FLAGS_KHR					0x30FC
55e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_MAJOR_VERSION_KHR				0x3098
56e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_MINOR_VERSION_KHR				0x30FB
57e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR	0x00000002
58e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR			0x00000001
59e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR			0x00000001
60e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR		0x00000002
61e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR			0x30FD
62e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR	0x31BD
63e5c31af7Sopenharmony_ci	#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR		0x00000004
64e5c31af7Sopenharmony_ci	#define EGL_KHR_create_context					1
65e5c31af7Sopenharmony_ci	#define EGL_LOSE_CONTEXT_ON_RESET_KHR				0x31BF
66e5c31af7Sopenharmony_ci	#define EGL_NO_RESET_NOTIFICATION_KHR				0x31BE
67e5c31af7Sopenharmony_ci	#define EGL_OPENGL_ES3_BIT_KHR					0x00000040
68e5c31af7Sopenharmony_ci#endif // EGL_KHR_create_context
69e5c31af7Sopenharmony_ci
70e5c31af7Sopenharmony_ci// Default library names
71e5c31af7Sopenharmony_ci#if !defined(DEQP_GLES2_LIBRARY_PATH)
72e5c31af7Sopenharmony_ci#	define DEQP_GLES2_LIBRARY_PATH "libGLESv2.so"
73e5c31af7Sopenharmony_ci#endif
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ci#if !defined(DEQP_GLES3_LIBRARY_PATH)
76e5c31af7Sopenharmony_ci#	define DEQP_GLES3_LIBRARY_PATH DEQP_GLES2_LIBRARY_PATH
77e5c31af7Sopenharmony_ci#endif
78e5c31af7Sopenharmony_ci
79e5c31af7Sopenharmony_ci#if !defined(DEQP_OPENGL_LIBRARY_PATH)
80e5c31af7Sopenharmony_ci#	define DEQP_OPENGL_LIBRARY_PATH "libGL.so"
81e5c31af7Sopenharmony_ci#endif
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_ci#if !defined(DEQP_VULKAN_LIBRARY_PATH)
84e5c31af7Sopenharmony_ci#	if (DE_OS == DE_OS_ANDROID)
85e5c31af7Sopenharmony_ci#		define DEQP_VULKAN_LIBRARY_PATH "libvulkan.so"
86e5c31af7Sopenharmony_ci#	else
87e5c31af7Sopenharmony_ci#		define DEQP_VULKAN_LIBRARY_PATH "libvulkan.so.1"
88e5c31af7Sopenharmony_ci#	endif
89e5c31af7Sopenharmony_ci#endif
90e5c31af7Sopenharmony_ci
91e5c31af7Sopenharmony_cinamespace tcu
92e5c31af7Sopenharmony_ci{
93e5c31af7Sopenharmony_cinamespace surfaceless
94e5c31af7Sopenharmony_ci{
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ciclass VulkanLibrary : public vk::Library
97e5c31af7Sopenharmony_ci{
98e5c31af7Sopenharmony_cipublic:
99e5c31af7Sopenharmony_ci	VulkanLibrary (const char* libraryPath)
100e5c31af7Sopenharmony_ci		: m_library	(libraryPath != DE_NULL ? libraryPath : DEQP_VULKAN_LIBRARY_PATH)
101e5c31af7Sopenharmony_ci		, m_driver	(m_library)
102e5c31af7Sopenharmony_ci	{
103e5c31af7Sopenharmony_ci	}
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ci	const vk::PlatformInterface& getPlatformInterface (void) const
106e5c31af7Sopenharmony_ci	{
107e5c31af7Sopenharmony_ci		return m_driver;
108e5c31af7Sopenharmony_ci	}
109e5c31af7Sopenharmony_ci	const tcu::FunctionLibrary&		getFunctionLibrary		(void) const
110e5c31af7Sopenharmony_ci	{
111e5c31af7Sopenharmony_ci		return m_library;
112e5c31af7Sopenharmony_ci	}
113e5c31af7Sopenharmony_ciprivate:
114e5c31af7Sopenharmony_ci	const tcu::DynamicFunctionLibrary	m_library;
115e5c31af7Sopenharmony_ci	const vk::PlatformDriver			m_driver;
116e5c31af7Sopenharmony_ci};
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_ci// Copied from tcuX11Platform.cpp
119e5c31af7Sopenharmony_ciclass VulkanPlatform : public vk::Platform
120e5c31af7Sopenharmony_ci{
121e5c31af7Sopenharmony_cipublic:
122e5c31af7Sopenharmony_ci	vk::Library* createLibrary (const char* libraryPath) const
123e5c31af7Sopenharmony_ci	{
124e5c31af7Sopenharmony_ci		return new VulkanLibrary(libraryPath);
125e5c31af7Sopenharmony_ci	}
126e5c31af7Sopenharmony_ci
127e5c31af7Sopenharmony_ci	void describePlatform (std::ostream& dst) const
128e5c31af7Sopenharmony_ci	{
129e5c31af7Sopenharmony_ci		utsname		sysInfo;
130e5c31af7Sopenharmony_ci
131e5c31af7Sopenharmony_ci		deMemset(&sysInfo, 0, sizeof(sysInfo));
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_ci		if (uname(&sysInfo) != 0)
134e5c31af7Sopenharmony_ci			throw std::runtime_error("uname() failed");
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci		dst << "OS: " << sysInfo.sysname << " " << sysInfo.release << " " << sysInfo.version << "\n";
137e5c31af7Sopenharmony_ci		dst << "CPU: " << sysInfo.machine << "\n";
138e5c31af7Sopenharmony_ci	}
139e5c31af7Sopenharmony_ci};
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_cibool isEGLExtensionSupported(
142e5c31af7Sopenharmony_ci		const eglw::Library& egl,
143e5c31af7Sopenharmony_ci		eglw::EGLDisplay,
144e5c31af7Sopenharmony_ci		const std::string& extName)
145e5c31af7Sopenharmony_ci{
146e5c31af7Sopenharmony_ci	const vector<string> exts = eglu::getClientExtensions(egl);
147e5c31af7Sopenharmony_ci	return de::contains(exts.begin(), exts.end(), extName);
148e5c31af7Sopenharmony_ci}
149e5c31af7Sopenharmony_ci
150e5c31af7Sopenharmony_ciclass GetProcFuncLoader : public glw::FunctionLoader
151e5c31af7Sopenharmony_ci{
152e5c31af7Sopenharmony_cipublic:
153e5c31af7Sopenharmony_ci	GetProcFuncLoader(const eglw::Library& egl): m_egl(egl)
154e5c31af7Sopenharmony_ci	{
155e5c31af7Sopenharmony_ci	}
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_ci	glw::GenericFuncType get(const char* name) const
158e5c31af7Sopenharmony_ci	{
159e5c31af7Sopenharmony_ci		return (glw::GenericFuncType)m_egl.getProcAddress(name);
160e5c31af7Sopenharmony_ci	}
161e5c31af7Sopenharmony_ciprotected:
162e5c31af7Sopenharmony_ci	const eglw::Library& m_egl;
163e5c31af7Sopenharmony_ci};
164e5c31af7Sopenharmony_ci
165e5c31af7Sopenharmony_ciclass DynamicFuncLoader : public glw::FunctionLoader
166e5c31af7Sopenharmony_ci{
167e5c31af7Sopenharmony_cipublic:
168e5c31af7Sopenharmony_ci	DynamicFuncLoader(de::DynamicLibrary* library): m_library(library)
169e5c31af7Sopenharmony_ci	{
170e5c31af7Sopenharmony_ci	}
171e5c31af7Sopenharmony_ci
172e5c31af7Sopenharmony_ci	glw::GenericFuncType get(const char* name) const
173e5c31af7Sopenharmony_ci	{
174e5c31af7Sopenharmony_ci		return (glw::GenericFuncType)m_library->getFunction(name);
175e5c31af7Sopenharmony_ci	}
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ciprivate:
178e5c31af7Sopenharmony_ci	de::DynamicLibrary*		m_library;
179e5c31af7Sopenharmony_ci};
180e5c31af7Sopenharmony_ci
181e5c31af7Sopenharmony_ciclass Platform : public tcu::Platform, public glu::Platform
182e5c31af7Sopenharmony_ci{
183e5c31af7Sopenharmony_cipublic:
184e5c31af7Sopenharmony_ci					Platform	(void);
185e5c31af7Sopenharmony_ci	const glu::Platform&		getGLPlatform	(void) const { return *this; }
186e5c31af7Sopenharmony_ci	const vk::Platform&			getVulkanPlatform	(void) const { return m_vkPlatform; }
187e5c31af7Sopenharmony_ci
188e5c31af7Sopenharmony_ciprivate:
189e5c31af7Sopenharmony_ci	VulkanPlatform		m_vkPlatform;
190e5c31af7Sopenharmony_ci};
191e5c31af7Sopenharmony_ci
192e5c31af7Sopenharmony_ciclass ContextFactory : public glu::ContextFactory
193e5c31af7Sopenharmony_ci{
194e5c31af7Sopenharmony_cipublic:
195e5c31af7Sopenharmony_ci					ContextFactory	(void);
196e5c31af7Sopenharmony_ci	glu::RenderContext*		createContext	(const glu::RenderConfig& config, const tcu::CommandLine&, const glu::RenderContext*) const;
197e5c31af7Sopenharmony_ci};
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ciclass EglRenderContext : public glu::RenderContext
200e5c31af7Sopenharmony_ci{
201e5c31af7Sopenharmony_cipublic:
202e5c31af7Sopenharmony_ci					EglRenderContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine, const glu::RenderContext* sharedContext);
203e5c31af7Sopenharmony_ci					~EglRenderContext(void);
204e5c31af7Sopenharmony_ci
205e5c31af7Sopenharmony_ci	glu::ContextType		getType		(void) const	{ return m_contextType; }
206e5c31af7Sopenharmony_ci	eglw::EGLContext		getEglContext	(void) const	{ return m_eglContext; }
207e5c31af7Sopenharmony_ci	const glw::Functions&		getFunctions	(void) const	{ return m_glFunctions; }
208e5c31af7Sopenharmony_ci	const tcu::RenderTarget&	getRenderTarget	(void) const;
209e5c31af7Sopenharmony_ci	void				postIterate	(void);
210e5c31af7Sopenharmony_ci	virtual void		makeCurrent		(void);
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci	virtual glw::GenericFuncType    getProcAddress	(const char* name) const { return m_egl.getProcAddress(name); }
213e5c31af7Sopenharmony_ci
214e5c31af7Sopenharmony_ciprivate:
215e5c31af7Sopenharmony_ci	const eglw::DefaultLibrary      m_egl;
216e5c31af7Sopenharmony_ci	const glu::ContextType		m_contextType;
217e5c31af7Sopenharmony_ci	eglw::EGLDisplay		m_eglDisplay;
218e5c31af7Sopenharmony_ci	eglw::EGLContext		m_eglContext;
219e5c31af7Sopenharmony_ci	eglw::EGLSurface		m_eglSurface;
220e5c31af7Sopenharmony_ci	de::DynamicLibrary*		m_glLibrary;
221e5c31af7Sopenharmony_ci	glw::Functions			m_glFunctions;
222e5c31af7Sopenharmony_ci	tcu::RenderTarget		m_renderTarget;
223e5c31af7Sopenharmony_ci};
224e5c31af7Sopenharmony_ci
225e5c31af7Sopenharmony_ciPlatform::Platform(void)
226e5c31af7Sopenharmony_ci{
227e5c31af7Sopenharmony_ci	m_contextFactoryRegistry.registerFactory(new ContextFactory());
228e5c31af7Sopenharmony_ci}
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ciContextFactory::ContextFactory()
231e5c31af7Sopenharmony_ci	: glu::ContextFactory("default", "EGL surfaceless context")
232e5c31af7Sopenharmony_ci{}
233e5c31af7Sopenharmony_ci
234e5c31af7Sopenharmony_ciglu::RenderContext* ContextFactory::createContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine, const glu::RenderContext* sharedContext) const
235e5c31af7Sopenharmony_ci{
236e5c31af7Sopenharmony_ci	return new EglRenderContext(config, cmdLine, sharedContext);
237e5c31af7Sopenharmony_ci}
238e5c31af7Sopenharmony_ci
239e5c31af7Sopenharmony_ciEglRenderContext::EglRenderContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine, const glu::RenderContext *sharedContext)
240e5c31af7Sopenharmony_ci	: m_egl("libEGL.so")
241e5c31af7Sopenharmony_ci	, m_contextType(config.type)
242e5c31af7Sopenharmony_ci	, m_eglDisplay(EGL_NO_DISPLAY)
243e5c31af7Sopenharmony_ci	, m_eglContext(EGL_NO_CONTEXT)
244e5c31af7Sopenharmony_ci	, m_renderTarget(
245e5c31af7Sopenharmony_ci			config.width,
246e5c31af7Sopenharmony_ci			config.height,
247e5c31af7Sopenharmony_ci			tcu::PixelFormat(
248e5c31af7Sopenharmony_ci					config.redBits,
249e5c31af7Sopenharmony_ci					config.greenBits,
250e5c31af7Sopenharmony_ci					config.blueBits,
251e5c31af7Sopenharmony_ci					config.alphaBits),
252e5c31af7Sopenharmony_ci			config.depthBits,
253e5c31af7Sopenharmony_ci			config.stencilBits,
254e5c31af7Sopenharmony_ci			config.numSamples)
255e5c31af7Sopenharmony_ci
256e5c31af7Sopenharmony_ci{
257e5c31af7Sopenharmony_ci	vector<eglw::EGLint>	context_attribs;
258e5c31af7Sopenharmony_ci	vector<eglw::EGLint>	frame_buffer_attribs;
259e5c31af7Sopenharmony_ci	vector<eglw::EGLint>	surface_attribs;
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ci	const glu::ContextType&	contextType = config.type;
262e5c31af7Sopenharmony_ci	eglw::EGLint		eglMajorVersion;
263e5c31af7Sopenharmony_ci	eglw::EGLint		eglMinorVersion;
264e5c31af7Sopenharmony_ci	eglw::EGLint		flags = 0;
265e5c31af7Sopenharmony_ci	eglw::EGLint		num_configs;
266e5c31af7Sopenharmony_ci	eglw::EGLConfig		egl_config = NULL;
267e5c31af7Sopenharmony_ci
268e5c31af7Sopenharmony_ci	(void) cmdLine;
269e5c31af7Sopenharmony_ci
270e5c31af7Sopenharmony_ci	m_eglDisplay = m_egl.getDisplay(NULL);
271e5c31af7Sopenharmony_ci	EGLU_CHECK_MSG(m_egl, "eglGetDisplay()");
272e5c31af7Sopenharmony_ci	if (m_eglDisplay == EGL_NO_DISPLAY)
273e5c31af7Sopenharmony_ci		throw tcu::ResourceError("eglGetDisplay() failed");
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci	EGLU_CHECK_CALL(m_egl, initialize(m_eglDisplay, &eglMajorVersion, &eglMinorVersion));
276e5c31af7Sopenharmony_ci
277e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_RENDERABLE_TYPE);
278e5c31af7Sopenharmony_ci	switch(contextType.getMajorVersion())
279e5c31af7Sopenharmony_ci	{
280e5c31af7Sopenharmony_ci		case 3:
281e5c31af7Sopenharmony_ci			frame_buffer_attribs.push_back(EGL_OPENGL_ES3_BIT);
282e5c31af7Sopenharmony_ci			break;
283e5c31af7Sopenharmony_ci		case 2:
284e5c31af7Sopenharmony_ci			frame_buffer_attribs.push_back(EGL_OPENGL_ES2_BIT);
285e5c31af7Sopenharmony_ci			break;
286e5c31af7Sopenharmony_ci		default:
287e5c31af7Sopenharmony_ci			frame_buffer_attribs.push_back(EGL_OPENGL_ES_BIT);
288e5c31af7Sopenharmony_ci	}
289e5c31af7Sopenharmony_ci
290e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_SURFACE_TYPE);
291e5c31af7Sopenharmony_ci	switch (config.surfaceType)
292e5c31af7Sopenharmony_ci	{
293e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_DONT_CARE:
294e5c31af7Sopenharmony_ci			frame_buffer_attribs.push_back(EGL_DONT_CARE);
295e5c31af7Sopenharmony_ci			break;
296e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
297e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
298e5c31af7Sopenharmony_ci			frame_buffer_attribs.push_back(EGL_PBUFFER_BIT);
299e5c31af7Sopenharmony_ci			surface_attribs.push_back(EGL_WIDTH);
300e5c31af7Sopenharmony_ci			surface_attribs.push_back(config.width);
301e5c31af7Sopenharmony_ci			surface_attribs.push_back(EGL_HEIGHT);
302e5c31af7Sopenharmony_ci			surface_attribs.push_back(config.height);
303e5c31af7Sopenharmony_ci			break;
304e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_WINDOW:
305e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("surfaceless platform does not support --deqp-surface-type=window");
306e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_LAST:
307e5c31af7Sopenharmony_ci			TCU_CHECK_INTERNAL(false);
308e5c31af7Sopenharmony_ci	}
309e5c31af7Sopenharmony_ci
310e5c31af7Sopenharmony_ci	surface_attribs.push_back(EGL_NONE);
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_RED_SIZE);
313e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(config.redBits);
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_GREEN_SIZE);
316e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(config.greenBits);
317e5c31af7Sopenharmony_ci
318e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_BLUE_SIZE);
319e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(config.blueBits);
320e5c31af7Sopenharmony_ci
321e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_ALPHA_SIZE);
322e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(config.alphaBits);
323e5c31af7Sopenharmony_ci
324e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_DEPTH_SIZE);
325e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(config.depthBits);
326e5c31af7Sopenharmony_ci
327e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_STENCIL_SIZE);
328e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(config.stencilBits);
329e5c31af7Sopenharmony_ci
330e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_SAMPLES);
331e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(config.numSamples);
332e5c31af7Sopenharmony_ci
333e5c31af7Sopenharmony_ci	frame_buffer_attribs.push_back(EGL_NONE);
334e5c31af7Sopenharmony_ci
335e5c31af7Sopenharmony_ci	if (!eglChooseConfig(m_eglDisplay, &frame_buffer_attribs[0], NULL, 0, &num_configs))
336e5c31af7Sopenharmony_ci		throw tcu::ResourceError("surfaceless couldn't find any config");
337e5c31af7Sopenharmony_ci
338e5c31af7Sopenharmony_ci	eglw::EGLConfig		all_configs[num_configs];
339e5c31af7Sopenharmony_ci
340e5c31af7Sopenharmony_ci	if (!eglChooseConfig(m_eglDisplay, &frame_buffer_attribs[0], all_configs, num_configs, &num_configs))
341e5c31af7Sopenharmony_ci		throw tcu::ResourceError("surfaceless couldn't find any config");
342e5c31af7Sopenharmony_ci
343e5c31af7Sopenharmony_ci	for (int i = 0; i < num_configs; i++) {
344e5c31af7Sopenharmony_ci		EGLint red, green, blue, alpha, depth, stencil, samples;
345e5c31af7Sopenharmony_ci		eglGetConfigAttrib(m_eglDisplay, all_configs[i], EGL_RED_SIZE, &red);
346e5c31af7Sopenharmony_ci		eglGetConfigAttrib(m_eglDisplay, all_configs[i], EGL_GREEN_SIZE, &green);
347e5c31af7Sopenharmony_ci		eglGetConfigAttrib(m_eglDisplay, all_configs[i], EGL_BLUE_SIZE, &blue);
348e5c31af7Sopenharmony_ci		eglGetConfigAttrib(m_eglDisplay, all_configs[i], EGL_ALPHA_SIZE, &alpha);
349e5c31af7Sopenharmony_ci		eglGetConfigAttrib(m_eglDisplay, all_configs[i], EGL_DEPTH_SIZE, &depth);
350e5c31af7Sopenharmony_ci		eglGetConfigAttrib(m_eglDisplay, all_configs[i], EGL_STENCIL_SIZE, &stencil);
351e5c31af7Sopenharmony_ci		eglGetConfigAttrib(m_eglDisplay, all_configs[i], EGL_SAMPLES, &samples);
352e5c31af7Sopenharmony_ci
353e5c31af7Sopenharmony_ci		if (
354e5c31af7Sopenharmony_ci				(glu::RenderConfig::DONT_CARE == config.redBits		|| red		== config.redBits)		&&
355e5c31af7Sopenharmony_ci				(glu::RenderConfig::DONT_CARE == config.greenBits	|| green	== config.greenBits)	&&
356e5c31af7Sopenharmony_ci				(glu::RenderConfig::DONT_CARE == config.blueBits	|| blue		== config.blueBits)		&&
357e5c31af7Sopenharmony_ci				(glu::RenderConfig::DONT_CARE == config.alphaBits	|| alpha	== config.alphaBits)	&&
358e5c31af7Sopenharmony_ci				(glu::RenderConfig::DONT_CARE == config.depthBits	|| depth	== config.depthBits)	&&
359e5c31af7Sopenharmony_ci				(glu::RenderConfig::DONT_CARE == config.stencilBits	|| stencil	== config.stencilBits)	&&
360e5c31af7Sopenharmony_ci				(glu::RenderConfig::DONT_CARE == config.numSamples	|| samples	== config.numSamples)) {
361e5c31af7Sopenharmony_ci			egl_config = all_configs[i];
362e5c31af7Sopenharmony_ci			break;
363e5c31af7Sopenharmony_ci		}
364e5c31af7Sopenharmony_ci	}
365e5c31af7Sopenharmony_ci
366e5c31af7Sopenharmony_ci	if (!egl_config)
367e5c31af7Sopenharmony_ci		throw tcu::ResourceError("surfaceless couldn't find a matching config");
368e5c31af7Sopenharmony_ci
369e5c31af7Sopenharmony_ci	switch (config.surfaceType)
370e5c31af7Sopenharmony_ci	{
371e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_DONT_CARE:
372e5c31af7Sopenharmony_ci			m_eglSurface = EGL_NO_SURFACE;
373e5c31af7Sopenharmony_ci			break;
374e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
375e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
376e5c31af7Sopenharmony_ci			m_eglSurface = eglCreatePbufferSurface(m_eglDisplay, egl_config, &surface_attribs[0]);
377e5c31af7Sopenharmony_ci			break;
378e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_WINDOW:
379e5c31af7Sopenharmony_ci		case glu::RenderConfig::SURFACETYPE_LAST:
380e5c31af7Sopenharmony_ci			TCU_CHECK_INTERNAL(false);
381e5c31af7Sopenharmony_ci	}
382e5c31af7Sopenharmony_ci
383e5c31af7Sopenharmony_ci	context_attribs.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
384e5c31af7Sopenharmony_ci	context_attribs.push_back(contextType.getMajorVersion());
385e5c31af7Sopenharmony_ci	context_attribs.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
386e5c31af7Sopenharmony_ci	context_attribs.push_back(contextType.getMinorVersion());
387e5c31af7Sopenharmony_ci
388e5c31af7Sopenharmony_ci	switch (contextType.getProfile())
389e5c31af7Sopenharmony_ci	{
390e5c31af7Sopenharmony_ci		case glu::PROFILE_ES:
391e5c31af7Sopenharmony_ci			EGLU_CHECK_CALL(m_egl, bindAPI(EGL_OPENGL_ES_API));
392e5c31af7Sopenharmony_ci			break;
393e5c31af7Sopenharmony_ci		case glu::PROFILE_CORE:
394e5c31af7Sopenharmony_ci			EGLU_CHECK_CALL(m_egl, bindAPI(EGL_OPENGL_API));
395e5c31af7Sopenharmony_ci			context_attribs.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
396e5c31af7Sopenharmony_ci			context_attribs.push_back(EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR);
397e5c31af7Sopenharmony_ci			break;
398e5c31af7Sopenharmony_ci		case glu::PROFILE_COMPATIBILITY:
399e5c31af7Sopenharmony_ci			EGLU_CHECK_CALL(m_egl, bindAPI(EGL_OPENGL_API));
400e5c31af7Sopenharmony_ci			context_attribs.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
401e5c31af7Sopenharmony_ci			context_attribs.push_back(EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR);
402e5c31af7Sopenharmony_ci			break;
403e5c31af7Sopenharmony_ci		case glu::PROFILE_LAST:
404e5c31af7Sopenharmony_ci			TCU_CHECK_INTERNAL(false);
405e5c31af7Sopenharmony_ci	}
406e5c31af7Sopenharmony_ci
407e5c31af7Sopenharmony_ci	if ((contextType.getFlags() & glu::CONTEXT_DEBUG) != 0)
408e5c31af7Sopenharmony_ci		flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
409e5c31af7Sopenharmony_ci
410e5c31af7Sopenharmony_ci	if ((contextType.getFlags() & glu::CONTEXT_ROBUST) != 0)
411e5c31af7Sopenharmony_ci		flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
412e5c31af7Sopenharmony_ci
413e5c31af7Sopenharmony_ci	if ((contextType.getFlags() & glu::CONTEXT_FORWARD_COMPATIBLE) != 0)
414e5c31af7Sopenharmony_ci		flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
415e5c31af7Sopenharmony_ci
416e5c31af7Sopenharmony_ci	context_attribs.push_back(EGL_CONTEXT_FLAGS_KHR);
417e5c31af7Sopenharmony_ci	context_attribs.push_back(flags);
418e5c31af7Sopenharmony_ci
419e5c31af7Sopenharmony_ci	context_attribs.push_back(EGL_NONE);
420e5c31af7Sopenharmony_ci
421e5c31af7Sopenharmony_ci	const EglRenderContext *sharedEglRenderContext = dynamic_cast<const EglRenderContext*>(sharedContext);
422e5c31af7Sopenharmony_ci	eglw::EGLContext sharedEglContext = sharedEglRenderContext ? sharedEglRenderContext->getEglContext() : EGL_NO_CONTEXT;
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_ci	m_eglContext = m_egl.createContext(m_eglDisplay, egl_config, sharedEglContext, &context_attribs[0]);
425e5c31af7Sopenharmony_ci	EGLU_CHECK_MSG(m_egl, "eglCreateContext()");
426e5c31af7Sopenharmony_ci	if (!m_eglContext)
427e5c31af7Sopenharmony_ci		throw tcu::ResourceError("eglCreateContext failed");
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_ci	EGLU_CHECK_CALL(m_egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
430e5c31af7Sopenharmony_ci
431e5c31af7Sopenharmony_ci	if ((eglMajorVersion == 1 && eglMinorVersion >= 5) ||
432e5c31af7Sopenharmony_ci		isEGLExtensionSupported(m_egl, m_eglDisplay, "EGL_KHR_get_all_proc_addresses") ||
433e5c31af7Sopenharmony_ci		isEGLExtensionSupported(m_egl, EGL_NO_DISPLAY, "EGL_KHR_client_get_all_proc_addresses"))
434e5c31af7Sopenharmony_ci	{
435e5c31af7Sopenharmony_ci		// Use eglGetProcAddress() for core functions
436e5c31af7Sopenharmony_ci		GetProcFuncLoader funcLoader(m_egl);
437e5c31af7Sopenharmony_ci		glu::initCoreFunctions(&m_glFunctions, &funcLoader, contextType.getAPI());
438e5c31af7Sopenharmony_ci	}
439e5c31af7Sopenharmony_ci#if !defined(DEQP_GLES2_RUNTIME_LOAD)
440e5c31af7Sopenharmony_ci	else if (contextType.getAPI() == glu::ApiType::es(2,0))
441e5c31af7Sopenharmony_ci	{
442e5c31af7Sopenharmony_ci		glw::initES20Direct(&m_glFunctions);
443e5c31af7Sopenharmony_ci	}
444e5c31af7Sopenharmony_ci#endif
445e5c31af7Sopenharmony_ci#if !defined(DEQP_GLES3_RUNTIME_LOAD)
446e5c31af7Sopenharmony_ci	else if (contextType.getAPI() == glu::ApiType::es(3,0))
447e5c31af7Sopenharmony_ci	{
448e5c31af7Sopenharmony_ci		glw::initES30Direct(&m_glFunctions);
449e5c31af7Sopenharmony_ci	}
450e5c31af7Sopenharmony_ci#endif
451e5c31af7Sopenharmony_ci	else
452e5c31af7Sopenharmony_ci	{
453e5c31af7Sopenharmony_ci		const char* libraryPath = NULL;
454e5c31af7Sopenharmony_ci
455e5c31af7Sopenharmony_ci		if (glu::isContextTypeES(contextType))
456e5c31af7Sopenharmony_ci		{
457e5c31af7Sopenharmony_ci			if (contextType.getMinorVersion() <= 2)
458e5c31af7Sopenharmony_ci				libraryPath = DEQP_GLES2_LIBRARY_PATH;
459e5c31af7Sopenharmony_ci			else
460e5c31af7Sopenharmony_ci				libraryPath = DEQP_GLES3_LIBRARY_PATH;
461e5c31af7Sopenharmony_ci		}
462e5c31af7Sopenharmony_ci		else
463e5c31af7Sopenharmony_ci		{
464e5c31af7Sopenharmony_ci			libraryPath = DEQP_OPENGL_LIBRARY_PATH;
465e5c31af7Sopenharmony_ci		}
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_ci		m_glLibrary = new de::DynamicLibrary(libraryPath);
468e5c31af7Sopenharmony_ci
469e5c31af7Sopenharmony_ci		DynamicFuncLoader funcLoader(m_glLibrary);
470e5c31af7Sopenharmony_ci		glu::initCoreFunctions(&m_glFunctions, &funcLoader, contextType.getAPI());
471e5c31af7Sopenharmony_ci	}
472e5c31af7Sopenharmony_ci
473e5c31af7Sopenharmony_ci	{
474e5c31af7Sopenharmony_ci		GetProcFuncLoader extLoader(m_egl);
475e5c31af7Sopenharmony_ci		glu::initExtensionFunctions(&m_glFunctions, &extLoader, contextType.getAPI());
476e5c31af7Sopenharmony_ci	}
477e5c31af7Sopenharmony_ci}
478e5c31af7Sopenharmony_ci
479e5c31af7Sopenharmony_ciEglRenderContext::~EglRenderContext(void)
480e5c31af7Sopenharmony_ci{
481e5c31af7Sopenharmony_ci	try
482e5c31af7Sopenharmony_ci	{
483e5c31af7Sopenharmony_ci		if (m_eglDisplay != EGL_NO_DISPLAY)
484e5c31af7Sopenharmony_ci		{
485e5c31af7Sopenharmony_ci			EGLU_CHECK_CALL(m_egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
486e5c31af7Sopenharmony_ci
487e5c31af7Sopenharmony_ci			if (m_eglContext != EGL_NO_CONTEXT)
488e5c31af7Sopenharmony_ci				EGLU_CHECK_CALL(m_egl, destroyContext(m_eglDisplay, m_eglContext));
489e5c31af7Sopenharmony_ci		}
490e5c31af7Sopenharmony_ci
491e5c31af7Sopenharmony_ci		EGLU_CHECK_CALL(m_egl, terminate(m_eglDisplay));
492e5c31af7Sopenharmony_ci	}
493e5c31af7Sopenharmony_ci	catch (...)
494e5c31af7Sopenharmony_ci	{
495e5c31af7Sopenharmony_ci	}
496e5c31af7Sopenharmony_ci}
497e5c31af7Sopenharmony_ci
498e5c31af7Sopenharmony_ciconst tcu::RenderTarget& EglRenderContext::getRenderTarget(void) const
499e5c31af7Sopenharmony_ci{
500e5c31af7Sopenharmony_ci	return m_renderTarget;
501e5c31af7Sopenharmony_ci}
502e5c31af7Sopenharmony_ci
503e5c31af7Sopenharmony_civoid EglRenderContext::makeCurrent (void)
504e5c31af7Sopenharmony_ci{
505e5c31af7Sopenharmony_ci	EGLU_CHECK_CALL(m_egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
506e5c31af7Sopenharmony_ci}
507e5c31af7Sopenharmony_ci
508e5c31af7Sopenharmony_civoid EglRenderContext::postIterate(void)
509e5c31af7Sopenharmony_ci{
510e5c31af7Sopenharmony_ci	this->getFunctions().finish();
511e5c31af7Sopenharmony_ci}
512e5c31af7Sopenharmony_ci
513e5c31af7Sopenharmony_ci} // namespace surfaceless
514e5c31af7Sopenharmony_ci} // namespace tcu
515e5c31af7Sopenharmony_ci
516e5c31af7Sopenharmony_citcu::Platform* createPlatform(void)
517e5c31af7Sopenharmony_ci{
518e5c31af7Sopenharmony_ci	return new tcu::surfaceless::Platform();
519e5c31af7Sopenharmony_ci}
520