// 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") ||
		#else
			return load("./build/Release_Win32/vk_swiftshader.dll") ||
		#endif
			       load("./build/Release/libvk_swiftshader.dll") ||
	#else
		#if defined(_WIN64)
			return load("./build/Debug_x64/vk_swiftshader.dll") ||
		#else
			return load("./build/Debug_Win32/vk_swiftshader.dll") ||
		#endif
			       load("./build/Debug/libvk_swiftshader.dll") ||
	#endif
			       load("./libvk_swiftshader.dll");
#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");
#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

#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
}
