| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 1 | // Copyright 2019 The SwiftShader Authors. All Rights Reserved. | 
|  | 2 | // | 
|  | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 4 | // you may not use this file except in compliance with the License. | 
|  | 5 | // You may obtain a copy of the License at | 
|  | 6 | // | 
|  | 7 | //    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | // | 
|  | 9 | // Unless required by applicable law or agreed to in writing, software | 
|  | 10 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 | // See the License for the specific language governing permissions and | 
|  | 13 | // limitations under the License. | 
|  | 14 |  | 
|  | 15 | #include "Driver.hpp" | 
|  | 16 |  | 
|  | 17 | #if defined(_WIN64) | 
|  | 18 | #    include "Windows.h" | 
|  | 19 | #    define OS_WINDOWS 1 | 
|  | 20 | #elif defined(__APPLE__) | 
|  | 21 | #    include "dlfcn.h" | 
|  | 22 | #    define OS_MAC 1 | 
| Stephen White | e6ab01f | 2019-04-04 14:31:25 -0400 | [diff] [blame] | 23 | #elif defined(__ANDROID__) | 
|  | 24 | #    include "dlfcn.h" | 
|  | 25 | #    define OS_ANDROID 1 | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 26 | #elif defined(__linux__) | 
|  | 27 | #    include "dlfcn.h" | 
|  | 28 | #    define OS_LINUX 1 | 
|  | 29 | #else | 
|  | 30 | #    error Unimplemented platform | 
|  | 31 | #endif | 
|  | 32 |  | 
|  | 33 | Driver::Driver() : vk_icdGetInstanceProcAddr(nullptr), dll(nullptr) | 
|  | 34 | { | 
| Ben Clayton | bb50106 | 2019-04-24 20:23:29 +0100 | [diff] [blame] | 35 | #define VK_GLOBAL(N, R, ...) N = nullptr | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 36 | #include "VkGlobalFuncs.hpp" | 
|  | 37 | #undef VK_GLOBAL | 
|  | 38 |  | 
| Ben Clayton | bb50106 | 2019-04-24 20:23:29 +0100 | [diff] [blame] | 39 | #define VK_INSTANCE(N, R, ...) N = nullptr | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 40 | #include "VkInstanceFuncs.hpp" | 
|  | 41 | #undef VK_INSTANCE | 
|  | 42 | } | 
|  | 43 |  | 
|  | 44 | Driver::~Driver() | 
|  | 45 | { | 
|  | 46 | unload(); | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | bool Driver::loadSwiftShader() | 
|  | 50 | { | 
|  | 51 | #if OS_WINDOWS | 
|  | 52 | #    if defined(NDEBUG) | 
| Ben Clayton | 64b761a | 2019-04-13 10:20:37 -0400 | [diff] [blame] | 53 | return load("./build/Release/libvk_swiftshader.dll"); | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 54 | #    else | 
| Ben Clayton | 64b761a | 2019-04-13 10:20:37 -0400 | [diff] [blame] | 55 | return load("./build/Debug/libvk_swiftshader.dll"); | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 56 | #    endif | 
|  | 57 | #elif OS_MAC | 
| Dan Sinclair | 1b8cd2d | 2019-03-14 10:51:05 -0400 | [diff] [blame] | 58 | return load("./build/Darwin/libvk_swiftshader.dylib"); | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 59 | #elif OS_LINUX | 
| Dan Sinclair | 1b8cd2d | 2019-03-14 10:51:05 -0400 | [diff] [blame] | 60 | return load("./build/Linux/libvk_swiftshader.so"); | 
| Stephen White | e6ab01f | 2019-04-04 14:31:25 -0400 | [diff] [blame] | 61 | #elif OS_ANDROID | 
|  | 62 | return load("libvk_swiftshader.so"); | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 63 | #else | 
|  | 64 | #    error Unimplemented platform | 
|  | 65 | #endif | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | bool Driver::loadSystem() | 
|  | 69 | { | 
|  | 70 | #if OS_LINUX | 
|  | 71 | return load("libvulkan.so.1"); | 
|  | 72 | #else | 
|  | 73 | return false; | 
|  | 74 | #endif | 
|  | 75 | } | 
|  | 76 |  | 
|  | 77 | bool Driver::load(const char* path) | 
|  | 78 | { | 
|  | 79 | #if OS_WINDOWS | 
|  | 80 | dll = LoadLibraryA(path); | 
| Stephen White | e6ab01f | 2019-04-04 14:31:25 -0400 | [diff] [blame] | 81 | #elif(OS_MAC || OS_LINUX || OS_ANDROID) | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 82 | dll = dlopen(path, RTLD_LAZY | RTLD_LOCAL); | 
|  | 83 | #else | 
|  | 84 | return false; | 
|  | 85 | #endif | 
|  | 86 | if(dll == nullptr) | 
|  | 87 | { | 
|  | 88 | return false; | 
|  | 89 | } | 
|  | 90 |  | 
|  | 91 | // Is the driver an ICD? | 
|  | 92 | if(!lookup(&vk_icdGetInstanceProcAddr, "vk_icdGetInstanceProcAddr")) | 
|  | 93 | { | 
|  | 94 | // Nope, attempt to use the loader version. | 
|  | 95 | if(!lookup(&vk_icdGetInstanceProcAddr, "vkGetInstanceProcAddr")) | 
|  | 96 | { | 
|  | 97 | return false; | 
|  | 98 | } | 
|  | 99 | } | 
|  | 100 |  | 
|  | 101 | #define VK_GLOBAL(N, R, ...)                                             \ | 
|  | 102 | if(auto pfn = vk_icdGetInstanceProcAddr(nullptr, #N))                \ | 
|  | 103 | {                                                                    \ | 
|  | 104 | N = reinterpret_cast<decltype(N)>(pfn);                          \ | 
|  | 105 | } | 
|  | 106 | #include "VkGlobalFuncs.hpp" | 
|  | 107 | #undef VK_GLOBAL | 
|  | 108 |  | 
|  | 109 | return true; | 
|  | 110 | } | 
|  | 111 |  | 
|  | 112 | void Driver::unload() | 
|  | 113 | { | 
|  | 114 | if(!isLoaded()) | 
|  | 115 | { | 
|  | 116 | return; | 
|  | 117 | } | 
|  | 118 |  | 
|  | 119 | #if OS_WINDOWS | 
|  | 120 | FreeLibrary((HMODULE)dll); | 
|  | 121 | #elif OS_LINUX | 
|  | 122 | dlclose(dll); | 
|  | 123 | #endif | 
|  | 124 |  | 
| Ben Clayton | bb50106 | 2019-04-24 20:23:29 +0100 | [diff] [blame] | 125 | #define VK_GLOBAL(N, R, ...) N = nullptr | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 126 | #include "VkGlobalFuncs.hpp" | 
|  | 127 | #undef VK_GLOBAL | 
|  | 128 |  | 
| Ben Clayton | bb50106 | 2019-04-24 20:23:29 +0100 | [diff] [blame] | 129 | #define VK_INSTANCE(N, R, ...) N = nullptr | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 130 | #include "VkInstanceFuncs.hpp" | 
|  | 131 | #undef VK_INSTANCE | 
|  | 132 | } | 
|  | 133 |  | 
|  | 134 | bool Driver::isLoaded() const | 
|  | 135 | { | 
|  | 136 | return dll != nullptr; | 
|  | 137 | } | 
|  | 138 |  | 
|  | 139 | bool Driver::resolve(VkInstance instance) | 
|  | 140 | { | 
|  | 141 | if(!isLoaded()) | 
|  | 142 | { | 
|  | 143 | return false; | 
|  | 144 | } | 
|  | 145 |  | 
|  | 146 | #define VK_INSTANCE(N, R, ...)                             \ | 
|  | 147 | if(auto pfn = vk_icdGetInstanceProcAddr(instance, #N)) \ | 
|  | 148 | {                                                      \ | 
|  | 149 | N = reinterpret_cast<decltype(N)>(pfn);            \ | 
|  | 150 | }                                                      \ | 
|  | 151 | else                                                   \ | 
|  | 152 | {                                                      \ | 
|  | 153 | return false;                                      \ | 
|  | 154 | } | 
|  | 155 | #include "VkInstanceFuncs.hpp" | 
|  | 156 | #undef VK_INSTANCE | 
|  | 157 |  | 
|  | 158 | return true; | 
|  | 159 | } | 
|  | 160 |  | 
|  | 161 | void* Driver::lookup(const char* name) | 
|  | 162 | { | 
|  | 163 | #if OS_WINDOWS | 
|  | 164 | return GetProcAddress((HMODULE)dll, name); | 
| Stephen White | e6ab01f | 2019-04-04 14:31:25 -0400 | [diff] [blame] | 165 | #elif(OS_MAC || OS_LINUX || OS_ANDROID) | 
| Ben Clayton | 654540e | 2019-02-01 13:08:23 +0000 | [diff] [blame] | 166 | return dlsym(dll, name); | 
|  | 167 | #else | 
|  | 168 | return nullptr; | 
|  | 169 | #endif | 
|  | 170 | } |