summaryrefslogtreecommitdiff
path: root/deimos/vulkan/vulkan_loader.cpp
blob: 0760c6748919a04d40354dac852e6c9fd5e01428 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "deimos/vulkan/vulkan.h"

#include <deimos/core/api_registry.h>
#include <deimos/core/allocator.h>
#include <deimos/core/os.h>
#include <deimos/core/log.h>

static deimos::OsApi* os_api;
static deimos::LogApi* log_api;

namespace deimos
{

class VulkanLoaderImpl : public VulkanLoaderApi
{
    Allocator*            m_allocator;
    gsl::owner<OsDll*>    m_vulkan_dll{};
    
public:
    explicit VulkanLoaderImpl(Allocator* allocator) : m_allocator{allocator} {}
    
    VulkanApi* LoadEntry() override
    {
        if (m_vulkan_dll == nullptr)
        {
            m_vulkan_dll = os_api->dll->Open("vulkan-1.dll");
            if (m_vulkan_dll != nullptr)
            {
                log_api->LogInfo("Vulkan DLL loaded");
            }
            else
            {
                deimos_Panic("Couldn't load Vulkan DLL");
            }
        }

        VulkanApi* api = m_allocator->New<VulkanApi>();
        
#define FN(NAME) api->NAME = (PFN_vk##NAME)os_api->dll->GetSymbol(m_vulkan_dll, "vk" #NAME);
#include "deimos/vulkan/vulkan_bootstrap_functions.inc"
#undef FN

#define FN(NAME) api->NAME = (PFN_vk##NAME)api->GetInstanceProcAddr(VK_NULL_HANDLE, "vk" #NAME);
#include "deimos/vulkan/vulkan_entry_functions.inc"
#undef FN

        return api;
    }
    
    void LoadInstance(VulkanApi* api, VkInstance instance) override
    {
        Expects(api != nullptr);
        Expects(instance != VK_NULL_HANDLE);
        Expects(api->GetInstanceProcAddr != nullptr);
        
#define FN(NAME) api->NAME = (PFN_vk##NAME)api->GetInstanceProcAddr(instance, "vk" #NAME);
#include "deimos/vulkan/vulkan_instance_functions.inc"
#undef FN
    }
};

void RegisterVulkanLoaderApi(ApiRegistry* registry)
{
    os_api = registry->Get<OsApi>();
    log_api = registry->Get<LogApi>();

    auto* allocator_api = registry->Get<AllocatorApi>();
    auto* allocator = allocator_api->CreateChild(allocator_api->system, "Vulkan");

    auto* impl = allocator->New<VulkanLoaderImpl>(allocator);
    registry->Set(impl);
    
    log_api->LogInfo("Vulkan loader API registered");
}

} // namespace deimos