You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
4.9 KiB
204 lines
4.9 KiB
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "Driver.hpp"
|
|
|
|
#if defined(_WIN32)
|
|
# include "Windows.h"
|
|
# define OS_WINDOWS 1
|
|
#elif defined(__APPLE__)
|
|
# include "dlfcn.h"
|
|
# define OS_MAC 1
|
|
#elif defined(__ANDROID__)
|
|
# include "dlfcn.h"
|
|
# define OS_ANDROID 1
|
|
#elif defined(__linux__)
|
|
# include "dlfcn.h"
|
|
# define OS_LINUX 1
|
|
#elif defined(__Fuchsia__)
|
|
# include <zircon/dlfcn.h>
|
|
# define OS_FUCHSIA 1
|
|
#else
|
|
# error Unimplemented platform
|
|
#endif
|
|
|
|
Driver::Driver()
|
|
: vk_icdGetInstanceProcAddr(nullptr)
|
|
, dll(nullptr){
|
|
#define VK_GLOBAL(N, R, ...) N = nullptr
|
|
#include "VkGlobalFuncs.hpp"
|
|
#undef VK_GLOBAL
|
|
|
|
#define VK_INSTANCE(N, R, ...) N = nullptr
|
|
#include "VkInstanceFuncs.hpp"
|
|
#undef VK_INSTANCE
|
|
}
|
|
|
|
Driver::~Driver()
|
|
{
|
|
unload();
|
|
}
|
|
|
|
bool Driver::loadSwiftShader()
|
|
{
|
|
#if OS_WINDOWS
|
|
# if !defined(STANDALONE)
|
|
// The DLL is delay loaded (see BUILD.gn), so we can load
|
|
// the correct ones from Chrome's swiftshader subdirectory.
|
|
HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll");
|
|
EXPECT_NE((HMODULE)NULL, libvulkan);
|
|
return true;
|
|
# elif defined(NDEBUG)
|
|
# if defined(_WIN64)
|
|
return load("./build/Release_x64/vk_swiftshader.dll") ||
|
|
load("./build/Release/vk_swiftshader.dll") ||
|
|
load("./vk_swiftshader.dll");
|
|
# else
|
|
return load("./build/Release_Win32/vk_swiftshader.dll") ||
|
|
load("./build/Release/vk_swiftshader.dll") ||
|
|
load("./vk_swiftshader.dll");
|
|
# endif
|
|
# else
|
|
# if defined(_WIN64)
|
|
return load("./build/Debug_x64/vk_swiftshader.dll") ||
|
|
load("./build/Debug/vk_swiftshader.dll") ||
|
|
load("./vk_swiftshader.dll");
|
|
# else
|
|
return load("./build/Debug_Win32/vk_swiftshader.dll") ||
|
|
load("./build/Debug/vk_swiftshader.dll") ||
|
|
load("./vk_swiftshader.dll");
|
|
# endif
|
|
# endif
|
|
#elif OS_MAC
|
|
return load("./build/Darwin/libvk_swiftshader.dylib") ||
|
|
load("swiftshader/libvk_swiftshader.dylib") ||
|
|
load("libvk_swiftshader.dylib");
|
|
#elif OS_LINUX
|
|
return load("./build/Linux/libvk_swiftshader.so") ||
|
|
load("swiftshader/libvk_swiftshader.so") ||
|
|
load("./libvk_swiftshader.so") ||
|
|
load("libvk_swiftshader.so");
|
|
#elif OS_ANDROID || OS_FUCHSIA
|
|
return load("libvk_swiftshader.so");
|
|
#else
|
|
# error Unimplemented platform
|
|
#endif
|
|
}
|
|
|
|
bool Driver::loadSystem()
|
|
{
|
|
#if OS_LINUX
|
|
return load("libvulkan.so.1");
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool Driver::load(const char *path)
|
|
{
|
|
#if OS_WINDOWS
|
|
dll = LoadLibraryA(path);
|
|
#elif(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA)
|
|
dll = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
|
|
#else
|
|
return false;
|
|
#endif
|
|
if(dll == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Is the driver an ICD?
|
|
if(!lookup(&vk_icdGetInstanceProcAddr, "vk_icdGetInstanceProcAddr"))
|
|
{
|
|
// Nope, attempt to use the loader version.
|
|
if(!lookup(&vk_icdGetInstanceProcAddr, "vkGetInstanceProcAddr"))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#define VK_GLOBAL(N, R, ...) \
|
|
if(auto pfn = vk_icdGetInstanceProcAddr(nullptr, #N)) \
|
|
{ \
|
|
N = reinterpret_cast<decltype(N)>(pfn); \
|
|
}
|
|
#include "VkGlobalFuncs.hpp"
|
|
#undef VK_GLOBAL
|
|
|
|
return true;
|
|
}
|
|
|
|
void Driver::unload()
|
|
{
|
|
if(!isLoaded())
|
|
{
|
|
return;
|
|
}
|
|
|
|
#if OS_WINDOWS
|
|
FreeLibrary((HMODULE)dll);
|
|
#elif(OS_LINUX || OS_FUCHSIA)
|
|
dlclose(dll);
|
|
#endif
|
|
|
|
dll = nullptr;
|
|
|
|
#define VK_GLOBAL(N, R, ...) N = nullptr
|
|
#include "VkGlobalFuncs.hpp"
|
|
#undef VK_GLOBAL
|
|
|
|
#define VK_INSTANCE(N, R, ...) N = nullptr
|
|
#include "VkInstanceFuncs.hpp"
|
|
#undef VK_INSTANCE
|
|
}
|
|
|
|
bool Driver::isLoaded() const
|
|
{
|
|
return dll != nullptr;
|
|
}
|
|
|
|
bool Driver::resolve(VkInstance instance)
|
|
{
|
|
if(!isLoaded())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#define VK_INSTANCE(N, R, ...) \
|
|
if(auto pfn = vk_icdGetInstanceProcAddr(instance, #N)) \
|
|
{ \
|
|
N = reinterpret_cast<decltype(N)>(pfn); \
|
|
} \
|
|
else \
|
|
{ \
|
|
return false; \
|
|
}
|
|
#include "VkInstanceFuncs.hpp"
|
|
#undef VK_INSTANCE
|
|
|
|
return true;
|
|
}
|
|
|
|
void *Driver::lookup(const char *name)
|
|
{
|
|
#if OS_WINDOWS
|
|
return GetProcAddress((HMODULE)dll, name);
|
|
#elif(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA)
|
|
return dlsym(dll, name);
|
|
#else
|
|
return nullptr;
|
|
#endif
|
|
}
|