aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--icd/CMakeLists.txt5
-rw-r--r--icd/README4
-rw-r--r--icd/common/CMakeLists.txt13
-rw-r--r--icd/common/icd.c278
-rw-r--r--icd/common/icd.h65
-rwxr-xr-xxgl-generate.py36
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: