blob: cb2645c148e3f042118d18c03b8b352f405cf61f [file] [log] [blame]
Ben Clayton654540e2019-02-01 13:08:23 +00001// 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
23#elif defined(__linux__)
24# include "dlfcn.h"
25# define OS_LINUX 1
26#else
27# error Unimplemented platform
28#endif
29
30Driver::Driver() : vk_icdGetInstanceProcAddr(nullptr), dll(nullptr)
31{
32#define VK_GLOBAL(N, R, ...) N = nullptr;
33#include "VkGlobalFuncs.hpp"
34#undef VK_GLOBAL
35
36#define VK_INSTANCE(N, R, ...) N = nullptr;
37#include "VkInstanceFuncs.hpp"
38#undef VK_INSTANCE
39}
40
41Driver::~Driver()
42{
43 unload();
44}
45
46bool Driver::loadSwiftShader()
47{
48#if OS_WINDOWS
49# if defined(NDEBUG)
50 return load("../../out/Release_x64/vk_swiftshader.dll");
51# else
52 return load("../../out/Debug_x64/vk_swiftshader.dll");
53# endif
54#elif OS_MAC
55 return load("./out/Darwin/libvk_swiftshader.dylib");
56#elif OS_LINUX
57 return load("./out/Linux/libvk_swiftshader.so");
58#else
59# error Unimplemented platform
60#endif
61}
62
63bool Driver::loadSystem()
64{
65#if OS_LINUX
66 return load("libvulkan.so.1");
67#else
68 return false;
69#endif
70}
71
72bool Driver::load(const char* path)
73{
74#if OS_WINDOWS
75 dll = LoadLibraryA(path);
76#elif(OS_MAC || OS_LINUX)
77 dll = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
78#else
79 return false;
80#endif
81 if(dll == nullptr)
82 {
83 return false;
84 }
85
86 // Is the driver an ICD?
87 if(!lookup(&vk_icdGetInstanceProcAddr, "vk_icdGetInstanceProcAddr"))
88 {
89 // Nope, attempt to use the loader version.
90 if(!lookup(&vk_icdGetInstanceProcAddr, "vkGetInstanceProcAddr"))
91 {
92 return false;
93 }
94 }
95
96#define VK_GLOBAL(N, R, ...) \
97 if(auto pfn = vk_icdGetInstanceProcAddr(nullptr, #N)) \
98 { \
99 N = reinterpret_cast<decltype(N)>(pfn); \
100 }
101#include "VkGlobalFuncs.hpp"
102#undef VK_GLOBAL
103
104 return true;
105}
106
107void Driver::unload()
108{
109 if(!isLoaded())
110 {
111 return;
112 }
113
114#if OS_WINDOWS
115 FreeLibrary((HMODULE)dll);
116#elif OS_LINUX
117 dlclose(dll);
118#endif
119
120#define VK_GLOBAL(N, R, ...) N = nullptr;
121#include "VkGlobalFuncs.hpp"
122#undef VK_GLOBAL
123
124#define VK_INSTANCE(N, R, ...) N = nullptr;
125#include "VkInstanceFuncs.hpp"
126#undef VK_INSTANCE
127}
128
129bool Driver::isLoaded() const
130{
131 return dll != nullptr;
132}
133
134bool Driver::resolve(VkInstance instance)
135{
136 if(!isLoaded())
137 {
138 return false;
139 }
140
141#define VK_INSTANCE(N, R, ...) \
142 if(auto pfn = vk_icdGetInstanceProcAddr(instance, #N)) \
143 { \
144 N = reinterpret_cast<decltype(N)>(pfn); \
145 } \
146 else \
147 { \
148 return false; \
149 }
150#include "VkInstanceFuncs.hpp"
151#undef VK_INSTANCE
152
153 return true;
154}
155
156void* Driver::lookup(const char* name)
157{
158#if OS_WINDOWS
159 return GetProcAddress((HMODULE)dll, name);
160#elif(OS_MAC || OS_LINUX)
161 return dlsym(dll, name);
162#else
163 return nullptr;
164#endif
165}