Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/vulkan/util/vk_instance.c
7099 views
1
/*
2
* Copyright © 2021 Intel Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "vk_instance.h"
25
26
#include "vk_alloc.h"
27
#include "vk_common_entrypoints.h"
28
#include "vk_util.h"
29
30
#include "compiler/glsl_types.h"
31
32
VkResult
33
vk_instance_init(struct vk_instance *instance,
34
const struct vk_instance_extension_table *supported_extensions,
35
const struct vk_instance_dispatch_table *dispatch_table,
36
const VkInstanceCreateInfo *pCreateInfo,
37
const VkAllocationCallbacks *alloc)
38
{
39
memset(instance, 0, sizeof(*instance));
40
vk_object_base_init(NULL, &instance->base, VK_OBJECT_TYPE_INSTANCE);
41
instance->alloc = *alloc;
42
43
instance->app_info = (struct vk_app_info) { .api_version = 0 };
44
if (pCreateInfo->pApplicationInfo) {
45
const VkApplicationInfo *app = pCreateInfo->pApplicationInfo;
46
47
instance->app_info.app_name =
48
vk_strdup(&instance->alloc, app->pApplicationName,
49
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
50
instance->app_info.app_version = app->applicationVersion;
51
52
instance->app_info.engine_name =
53
vk_strdup(&instance->alloc, app->pEngineName,
54
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
55
instance->app_info.engine_version = app->engineVersion;
56
57
instance->app_info.api_version = app->apiVersion;
58
}
59
60
if (instance->app_info.api_version == 0)
61
instance->app_info.api_version = VK_API_VERSION_1_0;
62
63
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
64
int idx;
65
for (idx = 0; idx < VK_INSTANCE_EXTENSION_COUNT; idx++) {
66
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
67
vk_instance_extensions[idx].extensionName) == 0)
68
break;
69
}
70
71
if (idx >= VK_INSTANCE_EXTENSION_COUNT)
72
return VK_ERROR_EXTENSION_NOT_PRESENT;
73
74
if (!supported_extensions->extensions[idx])
75
return VK_ERROR_EXTENSION_NOT_PRESENT;
76
77
#ifdef ANDROID
78
if (!vk_android_allowed_instance_extensions.extensions[idx])
79
return VK_ERROR_EXTENSION_NOT_PRESENT;
80
#endif
81
82
instance->enabled_extensions.extensions[idx] = true;
83
}
84
85
instance->dispatch_table = *dispatch_table;
86
87
/* Add common entrypoints without overwriting driver-provided ones. */
88
vk_instance_dispatch_table_from_entrypoints(
89
&instance->dispatch_table, &vk_common_instance_entrypoints, false);
90
91
if (mtx_init(&instance->debug_report.callbacks_mutex, mtx_plain) != 0)
92
return VK_ERROR_INITIALIZATION_FAILED;
93
94
list_inithead(&instance->debug_report.callbacks);
95
96
glsl_type_singleton_init_or_ref();
97
98
return VK_SUCCESS;
99
}
100
101
void
102
vk_instance_finish(struct vk_instance *instance)
103
{
104
glsl_type_singleton_decref();
105
mtx_destroy(&instance->debug_report.callbacks_mutex);
106
vk_free(&instance->alloc, (char *)instance->app_info.app_name);
107
vk_free(&instance->alloc, (char *)instance->app_info.engine_name);
108
vk_object_base_finish(&instance->base);
109
}
110
111
VkResult
112
vk_enumerate_instance_extension_properties(
113
const struct vk_instance_extension_table *supported_extensions,
114
uint32_t *pPropertyCount,
115
VkExtensionProperties *pProperties)
116
{
117
VK_OUTARRAY_MAKE_TYPED(VkExtensionProperties, out, pProperties, pPropertyCount);
118
119
for (int i = 0; i < VK_INSTANCE_EXTENSION_COUNT; i++) {
120
if (!supported_extensions->extensions[i])
121
continue;
122
123
#ifdef ANDROID
124
if (!vk_android_allowed_instance_extensions.extensions[i])
125
continue;
126
#endif
127
128
vk_outarray_append_typed(VkExtensionProperties, &out, prop) {
129
*prop = vk_instance_extensions[i];
130
}
131
}
132
133
return vk_outarray_status(&out);
134
}
135
136
PFN_vkVoidFunction
137
vk_instance_get_proc_addr(const struct vk_instance *instance,
138
const struct vk_instance_entrypoint_table *entrypoints,
139
const char *name)
140
{
141
PFN_vkVoidFunction func;
142
143
/* The Vulkan 1.0 spec for vkGetInstanceProcAddr has a table of exactly
144
* when we have to return valid function pointers, NULL, or it's left
145
* undefined. See the table for exact details.
146
*/
147
if (name == NULL)
148
return NULL;
149
150
#define LOOKUP_VK_ENTRYPOINT(entrypoint) \
151
if (strcmp(name, "vk" #entrypoint) == 0) \
152
return (PFN_vkVoidFunction)entrypoints->entrypoint
153
154
LOOKUP_VK_ENTRYPOINT(EnumerateInstanceExtensionProperties);
155
LOOKUP_VK_ENTRYPOINT(EnumerateInstanceLayerProperties);
156
LOOKUP_VK_ENTRYPOINT(EnumerateInstanceVersion);
157
LOOKUP_VK_ENTRYPOINT(CreateInstance);
158
159
/* GetInstanceProcAddr() can also be called with a NULL instance.
160
* See https://gitlab.khronos.org/vulkan/vulkan/issues/2057
161
*/
162
LOOKUP_VK_ENTRYPOINT(GetInstanceProcAddr);
163
164
#undef LOOKUP_VK_ENTRYPOINT
165
166
if (instance == NULL)
167
return NULL;
168
169
func = vk_instance_dispatch_table_get_if_supported(&instance->dispatch_table,
170
name,
171
instance->app_info.api_version,
172
&instance->enabled_extensions);
173
if (func != NULL)
174
return func;
175
176
func = vk_physical_device_dispatch_table_get_if_supported(&vk_physical_device_trampolines,
177
name,
178
instance->app_info.api_version,
179
&instance->enabled_extensions);
180
if (func != NULL)
181
return func;
182
183
func = vk_device_dispatch_table_get_if_supported(&vk_device_trampolines,
184
name,
185
instance->app_info.api_version,
186
&instance->enabled_extensions,
187
NULL);
188
if (func != NULL)
189
return func;
190
191
return NULL;
192
}
193
194
PFN_vkVoidFunction
195
vk_instance_get_proc_addr_unchecked(const struct vk_instance *instance,
196
const char *name)
197
{
198
PFN_vkVoidFunction func;
199
200
if (instance == NULL || name == NULL)
201
return NULL;
202
203
func = vk_instance_dispatch_table_get(&instance->dispatch_table, name);
204
if (func != NULL)
205
return func;
206
207
func = vk_physical_device_dispatch_table_get(
208
&vk_physical_device_trampolines, name);
209
if (func != NULL)
210
return func;
211
212
func = vk_device_dispatch_table_get(&vk_device_trampolines, name);
213
if (func != NULL)
214
return func;
215
216
return NULL;
217
}
218
219
PFN_vkVoidFunction
220
vk_instance_get_physical_device_proc_addr(const struct vk_instance *instance,
221
const char *name)
222
{
223
if (instance == NULL || name == NULL)
224
return NULL;
225
226
return vk_physical_device_dispatch_table_get_if_supported(&vk_physical_device_trampolines,
227
name,
228
instance->app_info.api_version,
229
&instance->enabled_extensions);
230
}
231
232