change project name to Kazan and reformat code
[kazan.git] / src / vulkan_icd / vulkan_icd.h
1 /*
2 * Copyright 2017 Jacob Lifshay
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 */
23 #ifndef VULKAN_ICD_VULKAN_ICD_H_
24 #define VULKAN_ICD_VULKAN_ICD_H_
25
26 #include "vulkan/vulkan.h"
27 #include "vulkan/vk_icd.h"
28 #include "vulkan/api_objects.h"
29 #include <type_traits>
30 #include <cstdint>
31 #include <cassert>
32 #include <initializer_list>
33 #include <memory>
34 #include <stdexcept>
35 #include <new>
36
37 extern "C" VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance,
38 const char *pName);
39
40 typedef PFN_vkVoidFunction (*VKAPI_PTR PFN_vk_icdGetInstanceProcAddr)(VkInstance instance,
41 const char *pName);
42
43 namespace kazan
44 {
45 namespace vulkan_icd
46 {
47 class Vulkan_loader_interface
48 {
49 public:
50 enum class Version : std::uint32_t
51 {
52 Version_0 = 0,
53 Version_1 = 1,
54 Version_2 = 2,
55 Version_3 = 3,
56 Version_4 = 4,
57 Version_5 = 5,
58 };
59
60 public:
61 static Vulkan_loader_interface *get() noexcept;
62
63 private:
64 constexpr Vulkan_loader_interface() noexcept
65 {
66 }
67
68 public:
69 constexpr Version get_negotiated_version() const noexcept
70 {
71 return negotiated_version;
72 }
73
74 public:
75 enum class Procedure_address_scope
76 {
77 Library,
78 Instance,
79 Device
80 };
81 PFN_vkVoidFunction get_procedure_address(const char *name,
82 Procedure_address_scope scope) noexcept;
83 PFN_vkVoidFunction get_instance_proc_addr(VkInstance instance, const char *name) noexcept;
84 VkResult create_instance(const VkInstanceCreateInfo *create_info,
85 const VkAllocationCallbacks *allocator,
86 VkInstance *instance) noexcept;
87 VkResult enumerate_instance_extension_properties(const char *layer_name,
88 uint32_t *property_count,
89 VkExtensionProperties *properties) noexcept;
90 VkResult enumerate_device_extension_properties(VkPhysicalDevice physical_device,
91 const char *layer_name,
92 uint32_t *property_count,
93 VkExtensionProperties *properties) noexcept;
94
95 private:
96 Version negotiated_version = Version::Version_0;
97 };
98
99 static_assert(std::is_trivially_destructible<Vulkan_loader_interface>::value, "");
100 static_assert(std::is_literal_type<Vulkan_loader_interface>::value, "");
101
102 template <typename T>
103 VkResult vulkan_enumerate_list_helper(std::uint32_t *api_value_count,
104 T *api_values,
105 const T *generated_values,
106 std::size_t generated_value_count) noexcept
107 {
108 static_assert(std::is_trivially_copyable<T>::value, "");
109 assert(api_value_count);
110 assert(static_cast<std::uint32_t>(generated_value_count) == generated_value_count);
111 if(!api_values)
112 {
113 *api_value_count = generated_value_count;
114 return VK_SUCCESS;
115 }
116 auto api_values_length = *api_value_count;
117 auto copy_length = api_values_length;
118 if(copy_length > generated_value_count)
119 copy_length = generated_value_count;
120 for(std::size_t i = 0; i < copy_length; i++)
121 api_values[i] = generated_values[i];
122 *api_value_count = copy_length;
123 if(copy_length < generated_value_count)
124 return VK_INCOMPLETE;
125 return VK_SUCCESS;
126 }
127
128 template <typename T>
129 VkResult vulkan_enumerate_list_helper(std::uint32_t *api_value_count,
130 T *api_values,
131 std::initializer_list<T> generated_values) noexcept
132 {
133 return vulkan_enumerate_list_helper(
134 api_value_count, api_values, generated_values.begin(), generated_values.size());
135 }
136
137 void print_exception(std::exception &e) noexcept;
138
139 template <typename Fn>
140 VkResult catch_exceptions_and_return_result(Fn &&fn) noexcept
141 {
142 try
143 {
144 return std::forward<Fn>(fn)();
145 }
146 catch(std::bad_alloc &)
147 {
148 return VK_ERROR_OUT_OF_HOST_MEMORY;
149 }
150 catch(std::exception &e)
151 {
152 print_exception(e);
153 throw; // send to std::terminate
154 }
155 // explicitly don't catch other exceptions and let std::terminate handle them
156 }
157 }
158 }
159
160 #endif // VULKAN_ICD_VULKAN_ICD_H_