aboutsummaryrefslogtreecommitdiff
path: root/loader/loader_platform.h
diff options
context:
space:
mode:
authorIan Elliott <ian@LunarG.com>2015-01-13 17:52:38 -0700
committerCourtney Goeltzenleuchter <courtney@LunarG.com>2015-02-04 17:58:11 -0700
commit08dd2294cf50d9282134bcf968d9f2eb0e3abd67 (patch)
treec663dad2b00a96460a938ab893cde6ec895b0318 /loader/loader_platform.h
parent50aeba51c159d41c3f3ccfbdd7edb7b5e5e0b162 (diff)
downloadusermoji-08dd2294cf50d9282134bcf968d9f2eb0e3abd67.tar.xz
Can compile "loader" and "layers" on Windows and Linux ...
These directories build and are partially turned-on on Windows, using the "tri" demo (follow-on commit) and a "NULL driver" that was created out of the sample/Intel driver. The GetProcAddress() is not yet finding symbols in the NULL driver. For now: - "C:\Windows\System32" is the default XGL driver directory. The getenv() isn't yet working. I suggest creating your own #define in order to point to where a driver is. - In order to recognize a Windows driver, we must look at both its prefix and suffix (i.e. it is named "XGL_*.dll", e.g. "XGL_i965.dll). - We autogenerate Windows ".def" files for the layers. Additional info is: - This is necessary in order for a DLL to export symbols that can be queried using GetProcAddress(). We can't use the normal Windows approach of declaring these functions using "__declspec(dllexport)", because these functions are declared in "xgl.h". - This involves adding and running the new "xgl-win-def-file-generate.py" file. - NOTE: Layers don't have the xglInitAndEnumerateGpus() entrypoint, just the xglGetProcAddr() entrypoint (and now the xglEnumerateLayers() entrypoint). Generating them is pretty simple. NOTE: In order to build on a 64-bit Windows 7/8 system, I did the following: - Install VisualStudio 2013 Professional - Install CMake from: http://www.cmake.org/cmake/resources/software.html - I let it add itself to the system PATH environment variable. - Install Python 3 from: https://www.python.org/downloads - I let it add itself to the system PATH environment variable. - Obtain the Git repository, checkout the "ian-150127-WinBuild" branch. - Using a Cygwin shell: I did the following: - "cd" to the top-level directory (i.e. the one that contains the ".git" directory). - "mkdir _out64" - "cd _out64" - "cmake -G "Visual Studio 12 Win64" .." - At this point, I used WindowsExplorer to open the "XGL.sln" file. I can build. CMake causes the build shortcut to be "Ctrl-Shift-B" instead of the normal "F7". I had to right-click the "ALL_BUILD" project, go to Properties->Debugging and change the debug Command and Working Directory to point to "tri.exe" and where the executable are. At this point, I can debug (using the normal "F5" shortcut).
Diffstat (limited to 'loader/loader_platform.h')
-rw-r--r--loader/loader_platform.h238
1 files changed, 238 insertions, 0 deletions
diff --git a/loader/loader_platform.h b/loader/loader_platform.h
new file mode 100644
index 00000000..a9cd4df1
--- /dev/null
+++ b/loader/loader_platform.h
@@ -0,0 +1,238 @@
+/*
+ * XGL
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ * Copyright 2014 Valve Software
+ * All Rights Reserved.
+ *
+ * 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.
+ *
+ * Authors:
+ * Ian Elliott <ian@lunarg.com>
+ */
+
+#ifndef LOADER_PLATFORM_H
+#define LOADER_PLATFORM_H
+
+#if defined(__linux__)
+/* Linux-specific common code: */
+
+// Headers:
+//#define _GNU_SOURCE 1
+// TBD: Are the contents of the following file used?
+#include <unistd.h>
+// Note: The following file is for dynamic loading:
+#include <dlfcn.h>
+#include <pthread.h>
+#include <assert.h>
+
+// C99:
+#define STATIC_INLINE static inline
+
+// Dynamic Loading:
+typedef void * loader_platform_dl_handle;
+static inline loader_platform_dl_handle loader_platform_open_library(const char* libPath)
+{
+ // NOTE: The prior (Linux only) loader code always used RTLD_LAZY. In one
+ // place, it used RTLD_DEEPBIND. It probably doesn't hurt to always use
+ // RTLD_DEEPBIND, and so that is what is being done.
+ return dlopen(libPath, RTLD_LAZY | RTLD_DEEPBIND | RTLD_LOCAL);
+}
+static inline char * loader_platform_open_library_error(const char* libPath)
+{
+ return dlerror();
+}
+static inline void loader_platform_close_library(loader_platform_dl_handle library)
+{
+ dlclose(library);
+}
+static inline void * loader_platform_get_proc_address(loader_platform_dl_handle library,
+ const char *name)
+{
+ assert(library);
+ assert(name);
+ return dlsym(library, name);
+}
+static inline char * loader_platform_get_proc_address_error(const char *name)
+{
+ return dlerror();
+}
+
+// Threads:
+typedef pthread_t loader_platform_thread;
+#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
+ pthread_once_t var = PTHREAD_ONCE_INIT;
+static inline void loader_platform_thread_once(void *ctl, void (* func) (void))
+{
+ assert(func != NULL);
+ assert(ctl != NULL);
+ pthread_once((pthread_once_t *) ctl, func);
+}
+
+// Thread IDs:
+typedef pthread_t loader_platform_thread_id;
+static inline loader_platform_thread_id loader_platform_get_thread_id()
+{
+ return pthread_self();
+}
+
+// Thread mutex:
+typedef pthread_mutex_t loader_platform_thread_mutex;
+static inline void loader_platform_thread_create_mutex(loader_platform_thread_mutex* pMutex)
+{
+ pthread_mutex_init(pMutex, NULL);
+}
+static inline void loader_platform_thread_lock_mutex(loader_platform_thread_mutex* pMutex)
+{
+ pthread_mutex_lock(pMutex);
+}
+static inline void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex* pMutex)
+{
+ pthread_mutex_unlock(pMutex);
+}
+static inline void loader_platform_thread_delete_mutex(loader_platform_thread_mutex* pMutex)
+{
+ pthread_mutex_destroy(pMutex);
+}
+
+
+#elif defined(_WIN32) // defined(__linux__)
+/* Windows-specific common code: */
+
+// Headers:
+#include <windows.h>
+#include <assert.h>
+#ifdef __cplusplus
+#include <iostream>
+#include <string>
+using namespace std;
+#endif // __cplusplus
+
+// C99:
+// Microsoft didn't implement C99 in Visual Studio; but started adding it with
+// VS2013. However, VS2013 still didn't have snprintf(). The following is a
+// work-around.
+#define snprintf _snprintf
+#define STATIC_INLINE static
+// Microsoft also doesn't have basename(). Paths are different on Windows, and
+// so this is just a temporary solution in order to get us compiling, so that we
+// can test some scenarios, and develop the correct solution for Windows.
+ // TODO: Develop a better, permanent solution for Windows, to replace this
+ // temporary code:
+static char *basename(char *pathname)
+{
+ char *current, *next;
+
+#define DIRECTORY_SYMBOL '\\'
+
+// TODO/TBD: Do we need to deal with the Windows's ":" character?
+
+ for (current = pathname; *current != '\0'; current = next) {
+ next = strchr(current, DIRECTORY_SYMBOL);
+ if (next == NULL) {
+ // No more DIRECTORY_SYMBOL's so return p:
+ return current;
+ } else {
+ // Point one character past the DIRECTORY_SYMBOL:
+ next++;
+ }
+ }
+}
+
+// Dynamic Loading:
+typedef HMODULE loader_platform_dl_handle;
+static loader_platform_dl_handle loader_platform_open_library(const char* libPath)
+{
+ return LoadLibrary(libPath);
+}
+static char * loader_platform_open_library_error(const char* libPath)
+{
+ static char errorMsg[120];
+ snprintf(errorMsg, 119, "Failed to open dynamic library \"%s\"", libPath);
+ return errorMsg;
+}
+static void loader_platform_close_library(loader_platform_dl_handle library)
+{
+ FreeLibrary(library);
+}
+static void * loader_platform_get_proc_address(loader_platform_dl_handle library,
+ const char *name)
+{
+ assert(library);
+ assert(name);
+ return GetProcAddress(library, name);
+}
+static char * loader_platform_get_proc_address_error(const char *name)
+{
+ static char errorMsg[120];
+ snprintf(errorMsg, 119, "Failed to find function \"%s\" in dynamic library", name);
+ return errorMsg;
+}
+
+// Threads:
+typedef HANDLE loader_platform_thread;
+#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
+ INIT_ONCE var = INIT_ONCE_STATIC_INIT;
+static void loader_platform_thread_once(void *ctl, void (* func) (void))
+{
+ assert(func != NULL);
+ assert(ctl != NULL);
+ InitOnceExecuteOnce((PINIT_ONCE) ctl, (PINIT_ONCE_FN) func, NULL, NULL);
+}
+
+// Thread IDs:
+typedef DWORD loader_platform_thread_id;
+static loader_platform_thread_id loader_platform_get_thread_id()
+{
+ return GetCurrentThreadId();
+}
+
+// Thread mutex:
+typedef CRITICAL_SECTION loader_platform_thread_mutex;
+static void loader_platform_thread_create_mutex(loader_platform_thread_mutex* pMutex)
+{
+ InitializeCriticalSection(pMutex);
+}
+static void loader_platform_thread_lock_mutex(loader_platform_thread_mutex* pMutex)
+{
+ EnterCriticalSection(pMutex);
+}
+static void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex* pMutex)
+{
+ LeaveCriticalSection(pMutex);
+}
+static void loader_platform_thread_delete_mutex(loader_platform_thread_mutex* pMutex)
+{
+ DeleteCriticalSection(pMutex);
+}
+
+#else // defined(_WIN32)
+
+#error The "loader_platform.h" file must be modified for this OS.
+
+// NOTE: In order to support another OS, an #elif needs to be added (above the
+// "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
+// contents of this file must be created.
+
+// NOTE: Other OS-specific changes are also needed for this OS. Search for
+// files with "WIN32" in it, as a quick way to find files that must be changed.
+
+#endif // defined(_WIN32)
+
+#endif /* LOADER_PLATFORM_H */