glsl-array-bounds: set out-of-bounds array index inside shader
[piglit.git] / tests / util / piglit-dispatch-init.c
blob3d9772d9b8b50b738739a57be479dcc42450cd2d
1 /* Copyright 2012 Intel Corporation
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice (including the next
11 * paragraph) shall be included in all copies or substantial portions of the
12 * Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
23 #include "piglit-util-gl.h"
25 #if defined(_WIN32)
27 #elif defined(__APPLE__)
29 #include <stdlib.h>
30 #include <string.h>
31 #include <AvailabilityMacros.h>
32 #include <dlfcn.h>
34 #else /* Linux */
36 #include <dlfcn.h>
38 #if defined(PIGLIT_HAS_GLX)
39 # include "glxew.h"
40 #elif defined(PIGLIT_HAS_EGL)
41 # include <EGL/egl.h>
42 #endif
44 #endif
46 #if defined(PIGLIT_USE_WAFFLE)
47 #include <waffle.h>
48 #include "piglit-util-waffle.h"
49 #include "piglit-framework-gl.h"
50 #endif
52 /**
53 * Generated code calls this function if the test tries to use a GL
54 * function that is not supported on the current implementation.
56 * This function terminates the test with a SKIP; this saves the
57 * piglit test from the burden of having to pre-check whether the
58 * implementation supports the functionality being tested.
60 static void
61 default_unsupported(const char *name)
63 printf("Function \"%s\" not supported on this implementation\n", name);
64 piglit_report_result(PIGLIT_SKIP);
67 /**
68 * Generated code calls this function if a call to GetProcAddress()
69 * returns NULL.
71 * We don't expect this to ever happen, since we only call
72 * GetProcAddress() for functions that the implementation claims to
73 * support. So if it does happen we terminate the test with a FAIL.
75 static void
76 default_get_proc_address_failure(const char *function_name)
78 printf("GetProcAddress failed for \"%s\"\n", function_name);
79 piglit_report_result(PIGLIT_FAIL);
82 #if defined(__APPLE__) || defined(PIGLIT_HAS_EGL)
83 static void *
84 do_dlsym(void **handle, const char *lib_name, const char *function_name)
86 void *result;
88 if (!*handle)
89 *handle = dlopen(lib_name, RTLD_LAZY);
91 if (!*handle) {
92 fprintf(stderr, "Could not open %s: %s\n", lib_name, dlerror());
93 return NULL;
96 result = dlsym(*handle, function_name);
97 if (!result)
98 fprintf(stderr, "%s() not found in %s: %s\n", function_name,
99 lib_name, dlerror());
101 return result;
103 #endif
105 #if defined(_WIN32)
108 * This function is used to retrieve the address of GL extension
109 * functions, and core GL functions for GL versions above 1.3, on
110 * Windows.
112 static piglit_dispatch_function_ptr
113 get_ext_proc_address(const char *function_name)
115 return (piglit_dispatch_function_ptr) wglGetProcAddress(function_name);
119 * This function is used to retrieve the address of core GL functions
120 * on windows.
122 static piglit_dispatch_function_ptr
123 get_core_proc_address(const char *function_name, int gl_10x_version)
125 if (gl_10x_version > 11) {
126 return get_ext_proc_address(function_name);
127 } else {
128 piglit_dispatch_function_ptr p;
129 /* Try GetProcAddress() first.
130 * If that fails, try wglGetProcAddress().
132 p = (piglit_dispatch_function_ptr)
133 GetProcAddress(LoadLibraryA("OPENGL32"), function_name);
134 if (!p)
135 p = get_ext_proc_address(function_name);
136 return p;
141 #elif defined(__APPLE__)
144 * This function is used to retrieve the address of all GL functions
145 * on Apple.
147 static piglit_dispatch_function_ptr
148 get_ext_proc_address(const char *function_name)
150 static const char *opengl_path =
151 "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
152 static void *opengl_lib = NULL;
154 return do_dlsym(&opengl_lib, opengl_path, function_name);
158 * This function is used to retrieve the address of core GL functions
159 * on Apple.
161 static piglit_dispatch_function_ptr
162 get_core_proc_address(const char *function_name, int gl_10x_version)
164 /* We don't need to worry about the GL version, since on Apple
165 * we retrieve all proc addresses in the same way.
167 (void) gl_10x_version;
169 return get_ext_proc_address(function_name);
172 #else /* Linux */
175 * This function is used to retrieve the address of all GL functions
176 * on Linux.
178 static piglit_dispatch_function_ptr
179 get_ext_proc_address(const char *function_name)
181 #if defined(PIGLIT_HAS_GLX)
182 return glXGetProcAddressARB((const GLubyte *) function_name);
183 #elif defined(PIGLIT_HAS_EGL)
184 return eglGetProcAddress(function_name);
185 #else
186 (void)function_name;
187 return (piglit_dispatch_function_ptr)NULL;
188 #endif
192 * This function is used to retrieve the address of core GL functions
193 * on Linux.
195 * eglGetProcAddress supports querying core functions only if EGL >= 1.5 or if
196 * EGL_KHR_get_all_proc_addresses or EGL_KHR_client_get_all_proc_addresses is
197 * supported. Rather than worry about such details, we consistently use dlysm()
198 * to lookup core *OpenGL ES* functions on systems where EGL is available.
200 * Lookup for core *OpenGL* functions is more complicated because the EGL 1.4
201 * specification, the antiquated OpenGL ABI for Linux [1] from year 2000, and
202 * various libGL.so implementations all disagree on the set of symbols that
203 * libGL.so should statically expose and which are queryable with
204 * eglGetProcAddress. The EGL 1.4 spec (as explained above) does not require
205 * eglGetProcAddress to work for core functions. The OpenGL ABI spec requires
206 * that libGL.so expose *no* symbols statically except those contained in GL
207 * 1.2 and select extensions. Actual driver vendors tend to expose most, if
208 * not all, symbols statically from libGL.so.
210 * Considering how messy this situation is, the most robust way to query a core
211 * function on EGL is via dlsym followed by eglGetProcAddress.
213 * [1] https://www.opengl.org/registry/ABI/
215 static piglit_dispatch_function_ptr
216 get_core_proc_address(const char *function_name, int gl_10x_version)
218 #if defined(PIGLIT_HAS_EGL)
219 #define GLES1_LIB "libGLESv1_CM.so.1"
220 #define GLES2_LIB "libGLESv2.so.2"
221 static void *gles1_handle;
222 static void *gles2_handle;
223 piglit_dispatch_function_ptr p = NULL;
225 switch (gl_10x_version) {
226 case 11:
227 p = do_dlsym(&gles1_handle, GLES1_LIB, function_name);
228 break;
229 case 20:
230 p = do_dlsym(&gles2_handle, GLES2_LIB, function_name);
231 break;
232 case 10:
233 default:
234 /* We query the address of core OpenGL functions as if they
235 * were extension functions. Read about the gory details
236 * above. */
237 break;
239 if (!p)
240 p = get_ext_proc_address(function_name);
242 return p;
243 #else
244 /* We don't need to worry about the GL version, since when using GLX
245 * we retrieve all proc addresses in the same way.
247 (void) gl_10x_version;
248 return get_ext_proc_address(function_name);
249 #endif
252 #endif
254 #ifdef PIGLIT_USE_WAFFLE
255 static enum waffle_enum piglit_waffle_dl = WAFFLE_DL_OPENGL;
258 * This function is used to retrieve the address of core GL functions
259 * via the waffle library.
261 static piglit_dispatch_function_ptr
262 get_wfl_core_proc(const char *name, int gl_10x_version)
264 piglit_dispatch_function_ptr func;
266 func = (piglit_dispatch_function_ptr)waffle_dl_sym(piglit_waffle_dl,
267 name);
268 if (!func) {
269 func = (piglit_dispatch_function_ptr)waffle_get_proc_address(name);
270 if (!func)
271 wfl_log_error(__FUNCTION__);
274 return func;
278 * This function is used to retrieve the address of functions not part of the
279 * core GL specification via the waffle library.
281 static piglit_dispatch_function_ptr
282 get_wfl_ext_proc(const char *name)
284 piglit_dispatch_function_ptr func;
286 func = (piglit_dispatch_function_ptr)waffle_get_proc_address(name);
287 if (!func)
288 wfl_log_error(__FUNCTION__);
290 return func;
292 #endif
295 * Initialize the GL dispatch mechanism to a default configuration.
297 * Eventually we will want to replace this with code that initializes
298 * the GL dispatch mechanism based on run-time parameters (e.g. to
299 * select X vs Wayland, or desktop GL vs GLES).
301 * This function is safe to call multiple times--it only has an effect
302 * on the first call.
304 void
305 piglit_dispatch_default_init(piglit_dispatch_api api)
307 static bool already_initialized = false;
309 if (already_initialized)
310 return;
312 #ifdef PIGLIT_USE_WAFFLE
313 switch (api) {
314 case PIGLIT_DISPATCH_GL:
315 piglit_waffle_dl = WAFFLE_DL_OPENGL;
316 break;
317 case PIGLIT_DISPATCH_ES1:
318 piglit_waffle_dl = WAFFLE_DL_OPENGL_ES1;
319 break;
320 case PIGLIT_DISPATCH_ES2:
321 piglit_waffle_dl = WAFFLE_DL_OPENGL_ES2;
322 break;
325 if (gl_fw) {
326 piglit_dispatch_init(api,
327 get_wfl_core_proc,
328 get_wfl_ext_proc,
329 default_unsupported,
330 default_get_proc_address_failure);
331 } else
332 #endif
335 piglit_dispatch_init(api,
336 get_core_proc_address,
337 get_ext_proc_address,
338 default_unsupported,
339 default_get_proc_address_failure);
342 already_initialized = true;