diff options
| -rw-r--r-- | icd/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | icd/README | 4 | ||||
| -rw-r--r-- | icd/common/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | icd/common/icd.c | 278 | ||||
| -rw-r--r-- | icd/common/icd.h | 65 | ||||
| -rwxr-xr-x | xgl-generate.py | 36 |
6 files changed, 400 insertions, 1 deletions
diff --git a/icd/CMakeLists.txt b/icd/CMakeLists.txt index 4469ff61..d7ceb38f 100644 --- a/icd/CMakeLists.txt +++ b/icd/CMakeLists.txt @@ -1 +1,4 @@ -add_subdirectory (intel) +include_directories("common") + +add_subdirectory(common) +add_subdirectory(intel) diff --git a/icd/README b/icd/README new file mode 100644 index 00000000..29b1e1fe --- /dev/null +++ b/icd/README @@ -0,0 +1,4 @@ +common/ provides helper and utility functions, as well as all XGL entry points +except xglInitAndEnumerateGpus. Hardware drivers are required to provide that +function, and to embed a "struct icd_dispatch_table *" as the first member of +XGL_PHYSICAL_GPU and all XGL_BASE_OBJECT. diff --git a/icd/common/CMakeLists.txt b/icd/common/CMakeLists.txt new file mode 100644 index 00000000..45d2ad8f --- /dev/null +++ b/icd/common/CMakeLists.txt @@ -0,0 +1,13 @@ +# the use of CMAKE_CURRENT_SOURCE_DIR pollutes the source tree +add_custom_command(OUTPUT icd-dispatch-table.h + COMMAND ${PROJECT_SOURCE_DIR}/xgl-generate.py icd-dispatch-table > ${CMAKE_CURRENT_SOURCE_DIR}/icd-dispatch-table.h + DEPENDS ${PROJECT_SOURCE_DIR}/xgl-generate.py + ${PROJECT_SOURCE_DIR}/xgl.py) + +add_custom_command(OUTPUT icd-dispatch-entrypoints.c + COMMAND ${PROJECT_SOURCE_DIR}/xgl-generate.py icd-dispatch-entrypoints icd-dispatch-table.h > icd-dispatch-entrypoints.c + DEPENDS ${PROJECT_SOURCE_DIR}/xgl-generate.py + ${PROJECT_SOURCE_DIR}/xgl.py) + +add_library(icd OBJECT icd.c icd-dispatch-entrypoints.c icd-dispatch-table.h) +set_target_properties(icd PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/icd/common/icd.c b/icd/common/icd.c new file mode 100644 index 00000000..3ec751cf --- /dev/null +++ b/icd/common/icd.c @@ -0,0 +1,278 @@ +/* + * XGL + * + * Copyright (C) 2014 LunarG, Inc. + * + * 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 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. + */ + +#define _ISOC11_SOURCE /* for aligned_alloc */ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdbool.h> +#include <string.h> +#include <assert.h> + +#include <xgl.h> +#include <xglDbg.h> + +#include "icd.h" + +struct icd_msg_callback { + XGL_DBG_MSG_CALLBACK_FUNCTION func; + XGL_VOID *data; + + struct icd_msg_callback *next; +}; + +struct icd { + struct icd_msg_callback *msg_callbacks; + + bool debug_echo_enable; + bool break_on_error; + bool break_on_warning; + + XGL_ALLOC_CALLBACKS alloc_callbacks; + bool alloc_callbacks_initialized; +}; + +static XGL_VOID *default_alloc(XGL_VOID *user_data, + XGL_SIZE size, + XGL_SIZE alignment, + XGL_SYSTEM_ALLOC_TYPE allocType); + +static XGL_VOID default_free(XGL_VOID *user_data, + XGL_VOID *mem); + +static struct icd icd = { + .alloc_callbacks = { + .pfnAlloc = default_alloc, + .pfnFree = default_free, + } +}; + +void icd_msg(XGL_DBG_MSG_TYPE msg_type, + XGL_VALIDATION_LEVEL validation_level, + XGL_BASE_OBJECT src_object, + XGL_SIZE location, + XGL_INT msg_code, + const char *msg) +{ + const struct icd_msg_callback *cb = icd.msg_callbacks; + + if (icd.debug_echo_enable || !cb) { + fputs(msg, stderr); + fputc('\n', stderr); + } + + while (cb) { + cb->func(msg_type, XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, + msg_code, (const XGL_CHAR *) msg, cb->data); + cb = cb->next; + } + + switch (msg_type) { + case XGL_DBG_MSG_ERROR: + if (icd.break_on_error) { + exit(1); + } + /* fall through */ + case XGL_DBG_MSG_WARNING: + if (icd.break_on_warning) { + exit(1); + } + break; + default: + break; + } +} + +void icd_vlog(XGL_DBG_MSG_TYPE msg_type, + XGL_VALIDATION_LEVEL validation_level, + XGL_BASE_OBJECT src_object, + XGL_SIZE location, + XGL_INT msg_code, + const char *format, va_list ap) +{ + char msg[256]; + int ret; + + ret = vsnprintf(msg, sizeof(msg), format, ap); + if (ret >= sizeof(msg) || ret < 0) { + msg[sizeof(msg) - 1] = '\0'; + } + + icd_msg(msg_type, validation_level, src_object, location, msg_code, msg); +} + +void icd_log(XGL_DBG_MSG_TYPE msg_type, + XGL_VALIDATION_LEVEL validation_level, + XGL_BASE_OBJECT src_object, + XGL_SIZE location, + XGL_INT msg_code, + const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + icd_vlog(msg_type, validation_level, src_object, + location, msg_code, format, ap); + va_end(ap); +} + +void icd_clear_msg_callbacks(void) +{ + struct icd_msg_callback *cb = icd.msg_callbacks; + + while (cb) { + struct icd_msg_callback *next = cb->next; + free(cb); + cb = next; + } + + icd.msg_callbacks = NULL; +} + +XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, XGL_VOID* pUserData) +{ + struct icd_msg_callback *cb; + + cb = malloc(sizeof(*cb)); + if (!cb) + return XGL_ERROR_OUT_OF_MEMORY; + + cb->func = pfnMsgCallback; + cb->data = pUserData; + + cb->next = icd.msg_callbacks; + icd.msg_callbacks = cb; + + return XGL_SUCCESS; +} + +XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback) +{ + struct icd_msg_callback *cb = icd.msg_callbacks; + + /* + * Find the first match (last registered). + * + * XXX What if the same callback function is registered more than once? + */ + while (cb) { + if (cb->func == pfnMsgCallback) { + break; + } + + cb = cb->next; + } + + if (!cb) + return XGL_ERROR_INVALID_POINTER; + + free(cb); + + return XGL_SUCCESS; +} + +XGL_RESULT XGLAPI xglDbgSetGlobalOption(XGL_DBG_GLOBAL_OPTION dbgOption, XGL_SIZE dataSize, const XGL_VOID* pData) +{ + XGL_RESULT res = XGL_SUCCESS; + + if (dataSize == 0) + return XGL_ERROR_INVALID_VALUE; + + switch (dbgOption) { + case XGL_DBG_OPTION_DEBUG_ECHO_ENABLE: + icd.debug_echo_enable = *((const bool *) pData); + break; + case XGL_DBG_OPTION_BREAK_ON_ERROR: + icd.break_on_error = *((const bool *) pData); + break; + case XGL_DBG_OPTION_BREAK_ON_WARNING: + icd.break_on_warning = *((const bool *) pData); + break; + default: + res = XGL_ERROR_INVALID_VALUE; + break; + } + + return res; +} + +XGL_RESULT icd_set_alloc_callbacks(const XGL_ALLOC_CALLBACKS *alloc_cb) +{ + if (icd.alloc_callbacks_initialized) { + return (memcmp(&icd.alloc_callbacks, alloc_cb, sizeof(*alloc_cb))) ? + XGL_ERROR_INVALID_POINTER : XGL_SUCCESS; + } + + if (alloc_cb) + icd.alloc_callbacks = *alloc_cb; + + icd.alloc_callbacks_initialized = true; + + return XGL_SUCCESS; +} + +void *icd_alloc(XGL_SIZE size, XGL_SIZE alignment, + XGL_SYSTEM_ALLOC_TYPE type) +{ + return icd.alloc_callbacks.pfnAlloc(icd.alloc_callbacks.pUserData, + size, alignment, type); +} + +void icd_free(void *mem) +{ + icd.alloc_callbacks.pfnFree(icd.alloc_callbacks.pUserData, mem); +} + +static bool is_power_of_two(XGL_SIZE v) +{ + return !(v & (v - 1)); +} + +static XGL_VOID *default_alloc(XGL_VOID *user_data, + XGL_SIZE size, + XGL_SIZE alignment, + XGL_SYSTEM_ALLOC_TYPE allocType) +{ + if (alignment <= 1) { + return malloc(size); + } else if (is_power_of_two(alignment)) { + if (alignment < sizeof(void *)) { + assert(is_power_of_two(sizeof(void *))); + alignment = sizeof(void *); + } + + size = (size + alignment - 1) & ~(alignment - 1); + + return aligned_alloc(alignment, size); + } + else { + return NULL; + } +} + +static XGL_VOID default_free(XGL_VOID *user_data, + XGL_VOID *mem) +{ + free(mem); +} diff --git a/icd/common/icd.h b/icd/common/icd.h new file mode 100644 index 00000000..18b47573 --- /dev/null +++ b/icd/common/icd.h @@ -0,0 +1,65 @@ +/* + * XGL + * + * Copyright (C) 2014 LunarG, Inc. + * + * 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 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. + */ + +#ifndef ICD_H +#define ICD_H + +#include <stdarg.h> + +#include <xgl.h> +#include <xglDbg.h> + +#include "icd-dispatch-table.h" + +void icd_msg(XGL_DBG_MSG_TYPE msg_type, + XGL_VALIDATION_LEVEL validation_level, + XGL_BASE_OBJECT src_object, + XGL_SIZE location, + XGL_INT msg_code, + const char *msg); + +void icd_vlog(XGL_DBG_MSG_TYPE msg_type, + XGL_VALIDATION_LEVEL validation_level, + XGL_BASE_OBJECT src_object, + XGL_SIZE location, + XGL_INT msg_code, + const char *format, va_list ap); + +void icd_log(XGL_DBG_MSG_TYPE msg_type, + XGL_VALIDATION_LEVEL validation_level, + XGL_BASE_OBJECT src_object, + XGL_SIZE location, + XGL_INT msg_code, + const char *format, ...); + +void icd_clear_msg_callbacks(void); + +XGL_RESULT icd_set_alloc_callbacks(const XGL_ALLOC_CALLBACKS *alloc_cb); + +void *icd_alloc(XGL_SIZE size, XGL_SIZE alignment, + XGL_SYSTEM_ALLOC_TYPE type); + +void icd_free(void *mem); + +#endif /* ICD_H */ diff --git a/xgl-generate.py b/xgl-generate.py index 73e1ec27..5ffa583f 100755 --- a/xgl-generate.py +++ b/xgl-generate.py @@ -145,10 +145,46 @@ class LoaderSubcommand(Subcommand): return "\n\n".join(body) +class IcdDispatchTableSubcommand(Subcommand): + def generate_header(self): + return "\n".join([ + "#include <xgl.h>", + "#include <xglDbg.h>"]) + + def generate_body(self): + return self._generate_icd_dispatch_table() + +class IcdDispatchTableSubcommand(Subcommand): + def generate_header(self): + return "\n".join([ + "#include <xgl.h>", + "#include <xglDbg.h>"]) + + def generate_body(self): + return self._generate_icd_dispatch_table() + +class IcdDispatchEntrypointsSubcommand(Subcommand): + def run(self): + if len(self.argv) != 1: + print("IcdDispatchEntrypointsSubcommand requires a header to include") + return + super().run() + + def generate_header(self): + return "\n".join([ + "#include <xgl.h>", + "#include <xglDbg.h>", + "#include \"%s\"" % self.argv[0]]) + + def generate_body(self): + return self._generate_icd_dispatch_entrypoints() + def main(): subcommands = { "pretty-dummy": PrettyDummySubcommand, "loader": LoaderSubcommand, + "icd-dispatch-table": IcdDispatchTableSubcommand, + "icd-dispatch-entrypoints": IcdDispatchEntrypointsSubcommand, } if len(sys.argv) < 2 or sys.argv[1] not in subcommands: |
