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
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
23 #include "piglit-dispatch.h"
24 #include "piglit-util-gl.h"
26 /* Global state maintained by the Piglit dispatch mechanism: */
29 * Which function to call to get the address of a core function.
31 static piglit_get_core_proc_address_function_ptr get_core_proc_address
= NULL
;
34 * Which function to call to get the address of a function defined in
37 static piglit_get_ext_proc_address_function_ptr get_ext_proc_address
= NULL
;
40 * Which function to call if the test attempts to call a function that
41 * is not supported by the implementation.
43 static piglit_error_function_ptr unsupported
= NULL
;
46 * Which function to call if get_core_proc_address or
47 * get_ext_proc_address returns NULL.
49 static piglit_error_function_ptr get_proc_address_failure
= NULL
;
52 * The GL version extracted from glGetString(GL_VERSION), times 10.
53 * For example, if the GL version is 2.1, the value 21 is stored here.
55 * We cache this here because calling glGetString is prohibited
56 * between glBegin and glEnd, and to avoid the inefficiency of
57 * redundant glGetString queries.
59 static int gl_version
= 0;
62 * True if piglit_dispatch_init has been called.
64 static bool is_initialized
= false;
66 static piglit_dispatch_api dispatch_api
;
69 * Generated code calls this function to verify that the dispatch
70 * mechanism has been properly initialized.
78 printf("piglit_dispatch_init() must be called before GL functions\n");
84 * Generated code calls this function to retrieve the address of a
87 static piglit_dispatch_function_ptr
88 get_core_proc(const char *name
, int gl_10x_version
)
90 piglit_dispatch_function_ptr function_pointer
= get_core_proc_address(name
, gl_10x_version
);
91 if (function_pointer
== NULL
)
92 get_proc_address_failure(name
);
93 return function_pointer
;
97 * Generated code calls this function to retrieve the address of a
98 * function defined in an extension.
100 static piglit_dispatch_function_ptr
101 get_ext_proc(const char *name
)
103 piglit_dispatch_function_ptr function_pointer
= get_ext_proc_address(name
);
104 if (function_pointer
== NULL
)
105 get_proc_address_failure(name
);
106 return function_pointer
;
110 * Generated code calls this function to determine whether a given GL
111 * version is supported.
114 check_version(int required_version
)
116 return gl_version
>= required_version
;
120 * Generated code calls this function to determine whether a given
121 * extension is supported.
124 check_extension(const char *name
)
126 return piglit_is_extension_supported(name
);
129 #include "piglit-dispatch-gen.c"
132 * Initialize the dispatch mechanism.
134 * \param api is the API under test. This determines whether
135 * deprecated functionality is supported (since deprecated functions
136 * cannot be used in forward compatible contexts). It also affects
137 * which GL version is queried for (since, for example a function
138 * might be supported in GLES as of version 2.0, but in OpenGL only as
139 * of version 2.1). Not yet implemented.
141 * \param get_core_proc and get_ext_proc are the functions to call to
142 * retrieve the address of a core GL function or an extension
143 * function. Note that for OpenGL, these can both map to the same
144 * function (e.g. glXGetProcAddressARB). However, in GLES, core
145 * functions are not allowed to be queried using the GetProcAddress
146 * mechanism, so get_core_proc will need to be implemented by looking
147 * up a symbol in a shared library (e.g. using dlsym()). When Waffle
148 * is in use, these are ignored and replaced with the Waffle functions
149 * that do the appropriate lookup according to the platform. One day
150 * we'll drop non-waffle support and remove this part of the
153 * \param unsupported_proc is the function to call if a test attempts
154 * to use unsupported GL functionality. It is passed the name of the
155 * function that the test attempted to use.
157 * \param failure_proc is the function to call if a call to
158 * get_core_proc() or get_ext_proc() unexpectedly returned NULL. It
159 * is passed the name of the function that was passed to
160 * get_core_proc() or get_ext_proc().
163 piglit_dispatch_init(piglit_dispatch_api api
,
164 piglit_get_core_proc_address_function_ptr get_core_proc
,
165 piglit_get_ext_proc_address_function_ptr get_ext_proc
,
166 piglit_error_function_ptr unsupported_proc
,
167 piglit_error_function_ptr failure_proc
)
171 get_core_proc_address
= get_core_proc
;
172 get_ext_proc_address
= get_ext_proc
;
173 unsupported
= unsupported_proc
;
174 get_proc_address_failure
= failure_proc
;
176 /* No need to reset the dispatch pointers the first time */
177 if (is_initialized
) {
178 reset_dispatch_pointers();
181 is_initialized
= true;
183 /* Store the GL version and extension string for use by
184 * check_version() and check_extension(). Note: the
185 * following two calls are safe because the only GL function
186 * they call is glGetString(), and the stub function for
187 * glGetString does not need to call check_version() or
190 gl_version
= piglit_get_gl_version();
194 * Compare two strings in the function_names table.
196 static int compare_function_names(const void *x
, const void *y
)
198 const char *x_str
= *(const char * const *) x
;
199 const char *y_str
= *(const char * const *) y
;
200 return strcmp(x_str
, y_str
);
204 * Retrieve a GL function pointer given the function name.
206 * This function is similar to glXGetProcAddressARB(), except that:
208 * - It is platform-independent.
210 * - It may be called on any supported function, regardless of whether
211 * the function is defined in GL core or an extension, and
212 * regardless of whether desktop GL or GLES is in use.
214 * - Synonymous function names (e.g. glMapBuffer and glMapBufferARB)
215 * may be used interchangeably; the correct function is automatically
216 * chosen based on the GL version and extension string.
218 * - If the requested function is not supported by the implementation,
219 * the unsupported_proc that was passed to piglit_dispatch_init() is
222 piglit_dispatch_function_ptr
223 piglit_dispatch_resolve_function(const char *name
)
225 size_t item_size
= sizeof(function_names
[0]);
226 size_t num_items
= ARRAY_SIZE(function_names
);
227 const char * const *item
= (const char * const *)
228 bsearch(&name
, function_names
, num_items
, item_size
,
229 compare_function_names
);
235 size_t item_index
= item
- function_names
;
236 return function_resolvers
[item_index
]();