[Piglit] [PATCH v2 09/13] piglit-dispatch: Remaining infrastructure.
Paul Berry
stereotype441 at gmail.com
Mon Mar 12 14:41:43 PDT 2012
Previous patches introduced code generation for the auto-generated
portions of the piglit-dispatch mechanism. This patch supplies the
remaining hand-written code, which includes:
- Code to initialize piglit-dispatch.
- The actions to be taken when looking up a function, when function
lookup fails, or when a function is unsupported.
- Code to determine whether piglit-dispatch has been initialized,
which GL version is supported, and whether a given extension is
supported.
- Code to look up a function using a name supplied at run-time.
- Definitions of basic GL types.
---
tests/util/piglit-dispatch-init.c | 122 +++++++++++++++++++
tests/util/piglit-dispatch.c | 238 +++++++++++++++++++++++++++++++++++++
tests/util/piglit-dispatch.h | 149 +++++++++++++++++++++++
3 files changed, 509 insertions(+), 0 deletions(-)
create mode 100644 tests/util/piglit-dispatch-init.c
create mode 100644 tests/util/piglit-dispatch.c
create mode 100644 tests/util/piglit-dispatch.h
diff --git a/tests/util/piglit-dispatch-init.c b/tests/util/piglit-dispatch-init.c
new file mode 100644
index 0000000..069475f
--- /dev/null
+++ b/tests/util/piglit-dispatch-init.c
@@ -0,0 +1,122 @@
+/* Copyright 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "piglit-util.h"
+#include "glxew.h"
+
+#ifdef __APPLE__
+#include <stdlib.h>
+#include <string.h>
+#include <AvailabilityMacros.h>
+#include <dlfcn.h>
+#endif
+
+/**
+ * Generated code calls this function if the test tries to use a GL
+ * function that is not supported on the current implementation.
+ *
+ * This function terminates the test with a SKIP; this saves the
+ * piglit test from the burden of having to pre-check whether the
+ * implementation supports the functionality being tested.
+ */
+static void
+default_unsupported(const char *name)
+{
+ printf("Function \"%s\" not supported on this implementation\n", name);
+ piglit_report_result(PIGLIT_SKIP);
+}
+
+/**
+ * Generated code calls this function if a call to GetProcAddress()
+ * returns NULL.
+ *
+ * We don't expect this to ever happen, since we only call
+ * GetProcAddress() for functions that the implementation claims to
+ * support. So if it does happen we terminate the test with a FAIL.
+ */
+static void
+default_get_proc_address_failure(const char *function_name)
+{
+ printf("GetProcAddress failed for \"%s\"\n", function_name);
+ piglit_report_result(PIGLIT_FAIL);
+}
+
+/**
+ * Generated code calls this function to retrieve the address of a
+ * function from the implementation.
+ *
+ * For the moment we only support GLX and Apple. In the future there
+ * will be versions of this function for EGL and Windows.
+ */
+static piglit_dispatch_function_ptr
+default_get_proc_address(const char *function_name)
+{
+#ifdef __APPLE__
+
+ static const char *opengl_path =
+ "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
+ static void *opengl_lib = NULL;
+
+ /* Dynamically load lib */
+ if (!opengl_lib)
+ {
+ opengl_lib = dlopen(opengl_path, RTLD_LAZY);
+ if (!opengl_lib)
+ return NULL;
+ }
+
+ return (piglit_dispatch_function_ptr) dlsym(opengl_lib, function_name);
+
+#else /* Linux */
+
+ /* TODO: support stuff other than GLX */
+ return glXGetProcAddressARB((const GLubyte *) function_name);
+
+#endif
+}
+
+/**
+ * Initialize the GL dispatch mechanism to a default configuration.
+ *
+ * Eventually we will want to replace this with code that initializes
+ * the GL dispatch mechanism based on run-time parameters (e.g. to
+ * select X vs Wayland, or desktop GL vs GLES).
+ *
+ * This function is safe to call multiple times--it only has an effect
+ * on the first call.
+ */
+void
+piglit_dispatch_default_init()
+{
+ static bool already_initialized = false;
+
+ if (already_initialized)
+ return;
+
+ piglit_dispatch_init(PIGLIT_DISPATCH_GL,
+ default_get_proc_address,
+ default_get_proc_address,
+ default_unsupported,
+ default_get_proc_address_failure);
+
+ already_initialized = true;
+}
diff --git a/tests/util/piglit-dispatch.c b/tests/util/piglit-dispatch.c
new file mode 100644
index 0000000..96443b2
--- /dev/null
+++ b/tests/util/piglit-dispatch.c
@@ -0,0 +1,238 @@
+/* Copyright 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "piglit-util.h"
+
+/* Global state maintained by the Piglit dispatch mechanism: */
+
+/**
+ * Which function to call to get the address of a core function.
+ */
+static piglit_get_proc_address_function_ptr __get_core_proc_address = NULL;
+
+/**
+ * Which function to call to get the address of a function defined in
+ * an extension.
+ */
+static piglit_get_proc_address_function_ptr __get_ext_proc_address = NULL;
+
+/**
+ * Which function to call if the test attempts to call a function that
+ * is not supported by the implementation.
+ */
+static piglit_error_function_ptr __unsupported = NULL;
+
+/**
+ * Which function to call if __get_core_proc_address or
+ * __get_ext_proc_address returns NULL.
+ */
+static piglit_error_function_ptr __get_proc_address_failure = NULL;
+
+/**
+ * The GL version extracted from glGetString(GL_VERSION), times 10.
+ * For example, if the GL version is 2.1, the value 21 is stored here.
+ *
+ * We cache this here because calling glGetString is prohibited
+ * between glBegin and glEnd, and to avoid the inefficiency of
+ * redundant glGetString queries.
+ */
+static int __gl_version = 0;
+
+/**
+ * The GL extension string returned by glGetString(GL_EXTENSIONS).
+ *
+ * We cache this here because calling glGetString is prohibited
+ * between glBegin and glEnd, and to avoid the inefficiency of
+ * redundant glGetString queries.
+ */
+static const char *__gl_extensions = NULL;
+
+/**
+ * True if piglit_dispatch_init has been called.
+ */
+static bool __is_initialized = false;
+
+/**
+ * Generated code calls this function to verify that the dispatch
+ * mechanism has been properly initialized.
+ */
+static void
+__check_initialized()
+{
+ if (__is_initialized)
+ return;
+
+ printf("piglit_dispatch_init() must be called before GL functions\n");
+ assert(false);
+ exit(1);
+}
+
+/**
+ * Generated code calls this function to retrieve the address of a
+ * core function.
+ */
+static piglit_dispatch_function_ptr
+__get_core_proc(const char *name)
+{
+ void *function_pointer = __get_core_proc_address(name);
+ if (function_pointer == NULL)
+ __get_proc_address_failure(name);
+ return function_pointer;
+}
+
+/**
+ * Generated code calls this function to retrieve the address of a
+ * function defined in an extension.
+ */
+static piglit_dispatch_function_ptr
+__get_ext_proc(const char *name)
+{
+ void *function_pointer = __get_ext_proc_address(name);
+ if (function_pointer == NULL)
+ __get_proc_address_failure(name);
+ return function_pointer;
+}
+
+/**
+ * Generated code calls this function to determine whether a given GL
+ * version is supported.
+ */
+static inline bool
+__check_version(int required_version)
+{
+ return __gl_version >= required_version;
+}
+
+/**
+ * Generated code calls this function to determine whether a given
+ * extension is supported.
+ */
+static inline bool
+__check_extension(const char *name)
+{
+ return piglit_is_extension_in_string(__gl_extensions, name);
+}
+
+#include "generated_dispatch.c"
+
+/**
+ * Initialize the dispatch mechanism.
+ *
+ * - api is the API under test. This determines whether deprecated
+ * functionality is supported (since deprecated functions cannot be
+ * used in forward compatible contexts). It also affects which GL
+ * version is queried for (since, for example a function might be
+ * supported in GLES as of version 2.0, but in OpenGL only as of
+ * version 2.1). Not yet implemented.
+ *
+ * - get_core_proc and get_ext_proc are the functions to call to
+ * retrieve the address of a core GL function or an extension
+ * function. Note that for OpenGL, these can both map to the same
+ * function (e.g. glXGetProcAddressARB). However, in GLES, core
+ * functions are not allowed to be queried using the GetProcAddress
+ * mechanism, so get_core_proc will need to be implemented by
+ * looking up a symbol in a shared library (e.g. using dlsym()).
+ *
+ * - unsupported_proc is the function to call if a test attempts to
+ * use unsupported GL functionality. It is passed the name of the
+ * function that the test attempted to use.
+ *
+ * - failure_proc is the function to call if a call to get_core_proc()
+ * or get_ext_proc() unexpectedly returned NULL. It is passed the
+ * name of the function that was passed to get_core_proc() or
+ * get_ext_proc().
+ */
+void
+piglit_dispatch_init(piglit_dispatch_api api,
+ piglit_get_proc_address_function_ptr get_core_proc,
+ piglit_get_proc_address_function_ptr get_ext_proc,
+ piglit_error_function_ptr unsupported_proc,
+ piglit_error_function_ptr failure_proc)
+{
+ (void) api; /* Not yet implemented--assume GL. */
+
+ __get_core_proc_address = get_core_proc;
+ __get_ext_proc_address = get_ext_proc;
+ __unsupported = unsupported_proc;
+ __get_proc_address_failure = failure_proc;
+
+ initialize_dispatch_pointers();
+
+ __is_initialized = true;
+
+ /* Store the GL version and extension string for use by
+ * __check_version() and __check_extension(). Note: the
+ * following two calls are safe because the only GL function
+ * they call is glGetString(), and the stub function for
+ * glGetString does not need to call __check_version() or
+ * __check_extension().
+ */
+ __gl_version = piglit_get_gl_version();
+ __gl_extensions = (const char *) glGetString(GL_EXTENSIONS);
+}
+
+/**
+ * Compare two strings in the function_names table.
+ */
+static int compare_function_names(const void *x, const void *y)
+{
+ const char *x_str = *(const char * const *) x;
+ const char *y_str = *(const char * const *) y;
+ return strcmp(x_str, y_str);
+}
+
+/**
+ * Retrieve a GL function pointer given the function name.
+ *
+ * This function is similar to glXGetProcAddressARB(), except that:
+ *
+ * - It is platform-independent.
+ *
+ * - It may be called on any supported function, regardless of whether
+ * the function is defined in GL core or an extension, and
+ * regardless of whether desktop GL or GLES is in use.
+ *
+ * - Synonymous function names (e.g. glMapBuffer and glMapBufferARB)
+ * may be used interchangably; the correct function is automatically
+ * chosen based on the GL version and extension string.
+ *
+ * - If the requested function is not supported by the implementation,
+ * the unsupported_proc that was passed to piglit_dispatch_init() is
+ * called.
+ */
+piglit_dispatch_function_ptr
+piglit_dispatch_resolve_function(const char *name)
+{
+ size_t item_size = sizeof(function_names[0]);
+ size_t num_items = ARRAY_SIZE(function_names);
+ const char * const *item = (const char * const *)
+ bsearch(&name, function_names, num_items, item_size,
+ compare_function_names);
+ __check_initialized();
+ if (!item) {
+ __unsupported(name);
+ return NULL;
+ } else {
+ size_t item_index = item - function_names;
+ return function_resolvers[item_index]();
+ }
+}
diff --git a/tests/util/piglit-dispatch.h b/tests/util/piglit-dispatch.h
new file mode 100644
index 0000000..55d9101
--- /dev/null
+++ b/tests/util/piglit-dispatch.h
@@ -0,0 +1,149 @@
+/* Copyright 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \file piglit-dispatch.h
+ *
+ * Dispatch mechanism providing Piglit with access to:
+ *
+ * - Enum values defined by OpenGL, GLES, and extensions. The enums
+ * are declared as simple #defines.
+ *
+ * - Functions defined by OpenGL, GLES, and extensions. Each function
+ * is represented by a function pointer, which initially points to a
+ * stub function. When the stub function is called, it looks up the
+ * appropriate function in the GL or GLES implementation, and
+ * updates the function pointer to point to it. Then it defers to
+ * that function.
+ *
+ * The dispatch mechanism understands function aliases. So, for
+ * example, since glMapBuffer and glMapBufferARB are synonymous, you
+ * may safely call either function. The dispatch mechanism will
+ * transparently map to whichever function the implementation
+ * supports.
+ *
+ * You may also translate a function name to a function pointer at run
+ * time by calling piglit_dispatch_resolve_function().
+ *
+ * The dispatch mechanism must be initialized before its first use.
+ * The initialization function, piglit_dispatch_init(), allows the
+ * caller to specify which API is in use, how to look up function
+ * pointers, what to do in the event of an error, and what to do if an
+ * unsupported function is requested.
+ */
+
+#ifndef __piglit_dispatch_h__
+#define __piglit_dispatch_h__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* APIENTRY and GLAPIENTRY are not used on Linux or Mac. */
+#define APIENTRY
+#define GLAPIENTRY
+
+typedef unsigned int GLenum;
+typedef unsigned int GLbitfield;
+typedef unsigned int GLuint;
+typedef int GLint;
+typedef int GLsizei;
+typedef unsigned char GLboolean;
+typedef signed char GLbyte;
+typedef short GLshort;
+typedef unsigned char GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned long GLulong;
+typedef float GLfloat;
+typedef float GLclampf;
+typedef double GLdouble;
+typedef double GLclampd;
+typedef void GLvoid;
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+typedef GLint64EXT GLint64;
+typedef GLuint64EXT GLuint64;
+typedef struct __GLsync *GLsync;
+
+typedef char GLchar;
+
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+
+typedef char GLcharARB;
+typedef unsigned int GLhandleARB;
+
+struct _cl_context;
+struct _cl_event;
+
+typedef GLintptr GLvdpauSurfaceNV;
+typedef unsigned short GLhalfNV;
+
+typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+
+typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+
+typedef void (APIENTRY *piglit_dispatch_function_ptr)(void);
+
+typedef piglit_dispatch_function_ptr (*piglit_get_proc_address_function_ptr)(const char *);
+
+typedef piglit_dispatch_function_ptr (*piglit_dispatch_resolver_ptr)();
+
+typedef void (*piglit_error_function_ptr)(const char *);
+
+typedef enum {
+ PIGLIT_DISPATCH_GL,
+ PIGLIT_DISPATCH_GL_FWD,
+ PIGLIT_DISPATCH_ES1,
+ PIGLIT_DISPATCH_ES2
+} piglit_dispatch_api;
+
+void piglit_dispatch_init(piglit_dispatch_api api,
+ piglit_get_proc_address_function_ptr get_core_proc,
+ piglit_get_proc_address_function_ptr get_ext_proc,
+ piglit_error_function_ptr unsupported_proc,
+ piglit_error_function_ptr failure_proc);
+
+piglit_dispatch_function_ptr
+piglit_dispatch_resolve_function(const char *name);
+
+#include "generated_dispatch.h"
+
+void piglit_dispatch_default_init();
+
+/* Prevent gl.h from being included, since it will attempt to define
+ * the functions we've already defined.
+ */
+#define __gl_h_
+#define __gltypes_h_
+#define __glext_h_
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* __piglit_dispatch_h__ */
--
1.7.7.6
More information about the Piglit
mailing list