blob: c53f1f774d644cb23d09207b0126540084d8cae1 [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
Stephen Whitee6ab01f2019-04-04 14:31:25 -040023#elif defined(__ANDROID__)
24# include "dlfcn.h"
25# define OS_ANDROID 1
Ben Clayton654540e2019-02-01 13:08:23 +000026#elif defined(__linux__)
27# include "dlfcn.h"
28# define OS_LINUX 1
29#else
30# error Unimplemented platform
31#endif
32
33Driver::Driver() : vk_icdGetInstanceProcAddr(nullptr), dll(nullptr)
34{
Ben Claytonbb501062019-04-24 20:23:29 +010035#define VK_GLOBAL(N, R, ...) N = nullptr
Ben Clayton654540e2019-02-01 13:08:23 +000036#include "VkGlobalFuncs.hpp"
37#undef VK_GLOBAL
38
Ben Claytonbb501062019-04-24 20:23:29 +010039#define VK_INSTANCE(N, R, ...) N = nullptr
Ben Clayton654540e2019-02-01 13:08:23 +000040#include "VkInstanceFuncs.hpp"
41#undef VK_INSTANCE
42}
43
44Driver::~Driver()
45{
46 unload();
47}
48
49bool Driver::loadSwiftShader()
50{
51#if OS_WINDOWS
52# if defined(NDEBUG)
Ben Clayton64b761a2019-04-13 10:20:37 -040053 return load("./build/Release/libvk_swiftshader.dll");
Ben Clayton654540e2019-02-01 13:08:23 +000054# else
Ben Clayton64b761a2019-04-13 10:20:37 -040055 return load("./build/Debug/libvk_swiftshader.dll");
Ben Clayton654540e2019-02-01 13:08:23 +000056# endif
57#elif OS_MAC
Dan Sinclair1b8cd2d2019-03-14 10:51:05 -040058 return load("./build/Darwin/libvk_swiftshader.dylib");
Ben Clayton654540e2019-02-01 13:08:23 +000059#elif OS_LINUX
Dan Sinclair1b8cd2d2019-03-14 10:51:05 -040060 return load("./build/Linux/libvk_swiftshader.so");
Stephen Whitee6ab01f2019-04-04 14:31:25 -040061#elif OS_ANDROID
62 return load("libvk_swiftshader.so");
Ben Clayton654540e2019-02-01 13:08:23 +000063#else
64# error Unimplemented platform
65#endif
66}
67
68bool Driver::loadSystem()
69{
70#if OS_LINUX
71 return load("libvulkan.so.1");
72#else
73 return false;
74#endif
75}
76
77bool Driver::load(const char* path)
78{
79#if OS_WINDOWS
80 dll = LoadLibraryA(path);
Stephen Whitee6ab01f2019-04-04 14:31:25 -040081#elif(OS_MAC || OS_LINUX || OS_ANDROID)
Ben Clayton654540e2019-02-01 13:08:23 +000082 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
112void 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 Claytonbb501062019-04-24 20:23:29 +0100125#define VK_GLOBAL(N, R, ...) N = nullptr
Ben Clayton654540e2019-02-01 13:08:23 +0000126#include "VkGlobalFuncs.hpp"
127#undef VK_GLOBAL
128
Ben Claytonbb501062019-04-24 20:23:29 +0100129#define VK_INSTANCE(N, R, ...) N = nullptr
Ben Clayton654540e2019-02-01 13:08:23 +0000130#include "VkInstanceFuncs.hpp"
131#undef VK_INSTANCE
132}
133
134bool Driver::isLoaded() const
135{
136 return dll != nullptr;
137}
138
139bool 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
161void* Driver::lookup(const char* name)
162{
163#if OS_WINDOWS
164 return GetProcAddress((HMODULE)dll, name);
Stephen Whitee6ab01f2019-04-04 14:31:25 -0400165#elif(OS_MAC || OS_LINUX || OS_ANDROID)
Ben Clayton654540e2019-02-01 13:08:23 +0000166 return dlsym(dll, name);
167#else
168 return nullptr;
169#endif
170}