1 /*
2  * Copyright (c) Intel 2011
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
18  * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "piglit-util-egl.h"
25 
piglit_get_egl_error_name(EGLint error)26 const char* piglit_get_egl_error_name(EGLint error) {
27 #define CASE(x) case x: return #x;
28     switch (error) {
29     CASE(EGL_SUCCESS)
30 
31     CASE(EGL_BAD_ACCESS)
32     CASE(EGL_BAD_ALLOC)
33     CASE(EGL_BAD_ATTRIBUTE)
34     CASE(EGL_BAD_CONFIG)
35     CASE(EGL_BAD_CONTEXT)
36     CASE(EGL_BAD_CURRENT_SURFACE)
37     CASE(EGL_BAD_DISPLAY)
38     CASE(EGL_BAD_MATCH)
39     CASE(EGL_BAD_NATIVE_PIXMAP)
40     CASE(EGL_BAD_NATIVE_WINDOW)
41     CASE(EGL_BAD_PARAMETER)
42     CASE(EGL_BAD_SURFACE)
43     CASE(EGL_CONTEXT_LOST)
44     CASE(EGL_NOT_INITIALIZED)
45     default:
46         return "(unrecognized error)";
47     }
48 #undef CASE
49 }
50 
51 bool
piglit_check_egl_error(EGLint expected_error)52 piglit_check_egl_error(EGLint expected_error)
53 {
54 	EGLint actual_error;
55 
56 	actual_error = eglGetError();
57 	if (actual_error == expected_error) {
58 		return true;
59 	}
60 
61 	/*
62 	 * If the lookup of the error's name is successful, then print
63 	 *     Unexpected EGL error: NAME 0xHEX
64 	 * Else, print
65 	 *     Unexpected EGL error: 0xHEX
66 	 */
67 	printf("Unexpected EGL error: %s 0x%x\n",
68                piglit_get_egl_error_name(actual_error), actual_error);
69 
70 	/* Print the expected error, but only if an error was really expected. */
71 	if (expected_error != EGL_SUCCESS) {
72 		printf("Expected EGL error: %s 0x%x\n",
73 		piglit_get_egl_error_name(expected_error), expected_error);
74         }
75 
76 	return false;
77 }
78 
79 EGLDisplay
piglit_egl_get_default_display(EGLenum platform)80 piglit_egl_get_default_display(EGLenum platform)
81 {
82 	return piglit_egl_get_display(platform, EGL_DEFAULT_DISPLAY);
83 }
84 
85 EGLDisplay
piglit_egl_get_display(EGLenum platform,void * native_display)86 piglit_egl_get_display(EGLenum platform, void *native_display)
87 {
88 	static bool once = true;
89 
90 	static bool has_base = false;
91 	static bool has_x11 = false;
92 	static bool has_wayland = false;
93 	static bool has_gbm = false;
94 	static bool has_surfaceless_mesa = false;
95 
96 	static EGLDisplay (*peglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list);
97 
98 	if (platform == EGL_NONE) {
99 		return eglGetDisplay(native_display);
100 	}
101 
102 	if (once) {
103 		once = false;
104 
105 		has_base = piglit_is_egl_extension_supported(EGL_NO_DISPLAY, "EGL_EXT_platform_base");
106 		has_x11 = piglit_is_egl_extension_supported(EGL_NO_DISPLAY, "EGL_EXT_platform_x11");
107 		has_wayland = piglit_is_egl_extension_supported(EGL_NO_DISPLAY, "EGL_EXT_platform_wayland");
108 		has_gbm = piglit_is_egl_extension_supported(EGL_NO_DISPLAY, "EGL_EXT_platform_gbm");
109 		has_surfaceless_mesa = piglit_is_egl_extension_supported(EGL_NO_DISPLAY, "EGL_MESA_platform_surfaceless");
110 
111 		peglGetPlatformDisplayEXT = (void*) eglGetProcAddress("eglGetPlatformDisplayEXT");
112 	}
113 
114 	if (!has_base) {
115 		return EGL_NO_DISPLAY;
116 	}
117 
118 	switch (platform) {
119 	case EGL_PLATFORM_X11_EXT:
120 		if (!has_x11) {
121 			return EGL_NO_DISPLAY;
122 		}
123 		break;
124 	case EGL_PLATFORM_WAYLAND_EXT:
125 		if (!has_wayland) {
126 			return EGL_NO_DISPLAY;
127 		}
128 		break;
129 	case EGL_PLATFORM_GBM_MESA:
130 		if (!has_gbm) {
131 			return EGL_NO_DISPLAY;
132 		}
133 		break;
134 	case EGL_PLATFORM_SURFACELESS_MESA:
135 		if (!has_surfaceless_mesa) {
136 			return EGL_NO_DISPLAY;
137 		}
138 		break;
139 	default:
140 		fprintf(stderr, "%s: unrecognized platform %#x\n", __func__, platform);
141 		return EGL_NO_DISPLAY;
142 	}
143 
144 	return peglGetPlatformDisplayEXT(platform, native_display, NULL);
145 }
146 
147 bool
piglit_is_egl_extension_supported(EGLDisplay egl_dpy,const char * name)148 piglit_is_egl_extension_supported(EGLDisplay egl_dpy, const char *name)
149 {
150 	const char *const egl_extension_list =
151 		eglQueryString(egl_dpy, EGL_EXTENSIONS);
152 
153 	/*
154 	 * If EGL does not support EGL_EXT_client_extensions, then
155 	 * eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS) returns NULL and
156 	 * generates EGL_BAD_DISPLAY.  In this case, just report that the
157 	 * requested (client) extension is not supported.
158 	 */
159 	if (!egl_extension_list && egl_dpy == EGL_NO_DISPLAY &&
160 			piglit_check_egl_error(EGL_BAD_DISPLAY))
161 		return false;
162 
163 	return piglit_is_extension_in_string(egl_extension_list, name);
164 }
165 
piglit_require_egl_extension(EGLDisplay dpy,const char * name)166 void piglit_require_egl_extension(EGLDisplay dpy, const char *name)
167 {
168 	if (!piglit_is_egl_extension_supported(dpy, name)) {
169 		printf("Test requires %s\n", name);
170 		piglit_report_result(PIGLIT_SKIP);
171 	}
172 }
173 
174 bool
piglit_egl_bind_api(EGLenum api)175 piglit_egl_bind_api(EGLenum api)
176 {
177 	const char *api_string = "";
178 
179 	if (eglBindAPI(api))
180 		return true;
181 
182 	if (api == EGL_OPENGL_API)
183 		api_string = "EGL_OPENGL_API";
184 	else if (api == EGL_OPENGL_ES_API)
185 		api_string = "EGL_OPENGL_ES_API";
186 	else
187 		assert(0);
188 
189 	if (piglit_check_egl_error(EGL_BAD_PARAMETER)) {
190 		fprintf(stderr, "eglBindAPI(%s) failed because EGL "
191 				"does not support the API\n",
192 			api_string);
193 		return false;
194 	} else {
195 		fprintf(stderr, "unexpected error for "
196 				"eglBindAPI(%s)\n",
197 				api_string);
198 		piglit_report_result(PIGLIT_FAIL);
199 	}
200 
201 	assert(0);
202 	return false;
203 }
204