• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(_WIN32)
18 #	include "Windows.h"
19 #	define OS_WINDOWS 1
20 #elif defined(__APPLE__)
21 #	include "dlfcn.h"
22 #	define OS_MAC 1
23 #elif defined(__ANDROID__)
24 #	include "dlfcn.h"
25 #	define OS_ANDROID 1
26 #elif defined(__linux__)
27 #	include "dlfcn.h"
28 #	define OS_LINUX 1
29 #elif defined(__Fuchsia__)
30 #	include <zircon/dlfcn.h>
31 #	define OS_FUCHSIA 1
32 #else
33 #	error Unimplemented platform
34 #endif
35 
Driver()36 Driver::Driver()
37     : vk_icdGetInstanceProcAddr(nullptr)
38     , dll(nullptr){
39 #define VK_GLOBAL(N, R, ...) N = nullptr
40 #include "VkGlobalFuncs.hpp"
41 #undef VK_GLOBAL
42 
43 #define VK_INSTANCE(N, R, ...) N = nullptr
44 #include "VkInstanceFuncs.hpp"
45 #undef VK_INSTANCE
46     }
47 
~Driver()48     Driver::~Driver()
49 {
50 	unload();
51 }
52 
loadSwiftShader()53 bool Driver::loadSwiftShader()
54 {
55 #if OS_WINDOWS
56 #	if !defined(STANDALONE)
57 	// The DLL is delay loaded (see BUILD.gn), so we can load
58 	// the correct ones from Chrome's swiftshader subdirectory.
59 	HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll");
60 	EXPECT_NE((HMODULE)NULL, libvulkan);
61 	return true;
62 #	elif defined(NDEBUG)
63 #		if defined(_WIN64)
64 	return load("./build/Release_x64/vk_swiftshader.dll") ||
65 	       load("./build/Release/vk_swiftshader.dll") ||
66 	       load("./vk_swiftshader.dll");
67 #		else
68 	return load("./build/Release_Win32/vk_swiftshader.dll") ||
69 	       load("./build/Release/vk_swiftshader.dll") ||
70 	       load("./vk_swiftshader.dll");
71 #		endif
72 #	else
73 #		if defined(_WIN64)
74 	return load("./build/Debug_x64/vk_swiftshader.dll") ||
75 	       load("./build/Debug/vk_swiftshader.dll") ||
76 	       load("./vk_swiftshader.dll");
77 #		else
78 	return load("./build/Debug_Win32/vk_swiftshader.dll") ||
79 	       load("./build/Debug/vk_swiftshader.dll") ||
80 	       load("./vk_swiftshader.dll");
81 #		endif
82 #	endif
83 #elif OS_MAC
84 	return load("./build/Darwin/libvk_swiftshader.dylib") ||
85 	       load("swiftshader/libvk_swiftshader.dylib") ||
86 	       load("libvk_swiftshader.dylib");
87 #elif OS_LINUX
88 	return load("./build/Linux/libvk_swiftshader.so") ||
89 	       load("swiftshader/libvk_swiftshader.so") ||
90 	       load("./libvk_swiftshader.so") ||
91 	       load("libvk_swiftshader.so");
92 #elif OS_ANDROID || OS_FUCHSIA
93 	return load("libvk_swiftshader.so");
94 #else
95 #	error Unimplemented platform
96 #endif
97 }
98 
loadSystem()99 bool Driver::loadSystem()
100 {
101 #if OS_LINUX
102 	return load("libvulkan.so.1");
103 #else
104 	return false;
105 #endif
106 }
107 
load(const char * path)108 bool Driver::load(const char *path)
109 {
110 #if OS_WINDOWS
111 	dll = LoadLibraryA(path);
112 #elif(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA)
113 	dll = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
114 #else
115 	return false;
116 #endif
117 	if(dll == nullptr)
118 	{
119 		return false;
120 	}
121 
122 	// Is the driver an ICD?
123 	if(!lookup(&vk_icdGetInstanceProcAddr, "vk_icdGetInstanceProcAddr"))
124 	{
125 		// Nope, attempt to use the loader version.
126 		if(!lookup(&vk_icdGetInstanceProcAddr, "vkGetInstanceProcAddr"))
127 		{
128 			return false;
129 		}
130 	}
131 
132 #define VK_GLOBAL(N, R, ...)                              \
133 	if(auto pfn = vk_icdGetInstanceProcAddr(nullptr, #N)) \
134 	{                                                     \
135 		N = reinterpret_cast<decltype(N)>(pfn);           \
136 	}
137 #include "VkGlobalFuncs.hpp"
138 #undef VK_GLOBAL
139 
140 	return true;
141 }
142 
unload()143 void Driver::unload()
144 {
145 	if(!isLoaded())
146 	{
147 		return;
148 	}
149 
150 #if OS_WINDOWS
151 	FreeLibrary((HMODULE)dll);
152 #elif(OS_LINUX || OS_FUCHSIA)
153 	dlclose(dll);
154 #endif
155 
156 #define VK_GLOBAL(N, R, ...) N = nullptr
157 #include "VkGlobalFuncs.hpp"
158 #undef VK_GLOBAL
159 
160 #define VK_INSTANCE(N, R, ...) N = nullptr
161 #include "VkInstanceFuncs.hpp"
162 #undef VK_INSTANCE
163 }
164 
isLoaded() const165 bool Driver::isLoaded() const
166 {
167 	return dll != nullptr;
168 }
169 
resolve(VkInstance instance)170 bool Driver::resolve(VkInstance instance)
171 {
172 	if(!isLoaded())
173 	{
174 		return false;
175 	}
176 
177 #define VK_INSTANCE(N, R, ...)                             \
178 	if(auto pfn = vk_icdGetInstanceProcAddr(instance, #N)) \
179 	{                                                      \
180 		N = reinterpret_cast<decltype(N)>(pfn);            \
181 	}                                                      \
182 	else                                                   \
183 	{                                                      \
184 		return false;                                      \
185 	}
186 #include "VkInstanceFuncs.hpp"
187 #undef VK_INSTANCE
188 
189 	return true;
190 }
191 
lookup(const char * name)192 void *Driver::lookup(const char *name)
193 {
194 #if OS_WINDOWS
195 	return GetProcAddress((HMODULE)dll, name);
196 #elif(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA)
197 	return dlsym(dll, name);
198 #else
199 	return nullptr;
200 #endif
201 }
202