1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2019 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include <string.h>
25*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
26*61046927SAndroid Build Coastguard Worker #include <assert.h>
27*61046927SAndroid Build Coastguard Worker #include <stdio.h>
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker #include <vulkan/vulkan.h>
30*61046927SAndroid Build Coastguard Worker #include <vulkan/vk_layer.h>
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
33*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
34*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
35*61046927SAndroid Build Coastguard Worker #include "util/simple_mtx.h"
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker #include "vk_dispatch_table.h"
38*61046927SAndroid Build Coastguard Worker #include "vk_enum_to_str.h"
39*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker struct instance_data {
42*61046927SAndroid Build Coastguard Worker struct vk_instance_dispatch_table vtable;
43*61046927SAndroid Build Coastguard Worker VkInstance instance;
44*61046927SAndroid Build Coastguard Worker };
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker struct device_data {
47*61046927SAndroid Build Coastguard Worker struct instance_data *instance;
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker PFN_vkSetDeviceLoaderData set_device_loader_data;
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker struct vk_device_dispatch_table vtable;
52*61046927SAndroid Build Coastguard Worker VkPhysicalDevice physical_device;
53*61046927SAndroid Build Coastguard Worker VkDevice device;
54*61046927SAndroid Build Coastguard Worker };
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker static struct hash_table_u64 *vk_object_to_data = NULL;
57*61046927SAndroid Build Coastguard Worker static simple_mtx_t vk_object_to_data_mutex = SIMPLE_MTX_INITIALIZER;
58*61046927SAndroid Build Coastguard Worker
ensure_vk_object_map(void)59*61046927SAndroid Build Coastguard Worker static inline void ensure_vk_object_map(void)
60*61046927SAndroid Build Coastguard Worker {
61*61046927SAndroid Build Coastguard Worker if (!vk_object_to_data)
62*61046927SAndroid Build Coastguard Worker vk_object_to_data = _mesa_hash_table_u64_create(NULL);
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker #define HKEY(obj) ((uintptr_t)(obj))
66*61046927SAndroid Build Coastguard Worker #define FIND(type, obj) ((type *)find_object_data(HKEY(obj)))
67*61046927SAndroid Build Coastguard Worker
find_object_data(uint64_t obj)68*61046927SAndroid Build Coastguard Worker static void *find_object_data(uint64_t obj)
69*61046927SAndroid Build Coastguard Worker {
70*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&vk_object_to_data_mutex);
71*61046927SAndroid Build Coastguard Worker ensure_vk_object_map();
72*61046927SAndroid Build Coastguard Worker void *data = _mesa_hash_table_u64_search(vk_object_to_data, obj);
73*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&vk_object_to_data_mutex);
74*61046927SAndroid Build Coastguard Worker return data;
75*61046927SAndroid Build Coastguard Worker }
76*61046927SAndroid Build Coastguard Worker
map_object(uint64_t obj,void * data)77*61046927SAndroid Build Coastguard Worker static void map_object(uint64_t obj, void *data)
78*61046927SAndroid Build Coastguard Worker {
79*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&vk_object_to_data_mutex);
80*61046927SAndroid Build Coastguard Worker ensure_vk_object_map();
81*61046927SAndroid Build Coastguard Worker _mesa_hash_table_u64_insert(vk_object_to_data, obj, data);
82*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&vk_object_to_data_mutex);
83*61046927SAndroid Build Coastguard Worker }
84*61046927SAndroid Build Coastguard Worker
unmap_object(uint64_t obj)85*61046927SAndroid Build Coastguard Worker static void unmap_object(uint64_t obj)
86*61046927SAndroid Build Coastguard Worker {
87*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&vk_object_to_data_mutex);
88*61046927SAndroid Build Coastguard Worker _mesa_hash_table_u64_remove(vk_object_to_data, obj);
89*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&vk_object_to_data_mutex);
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker /**/
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker #define VK_CHECK(expr) \
95*61046927SAndroid Build Coastguard Worker do { \
96*61046927SAndroid Build Coastguard Worker VkResult __result = (expr); \
97*61046927SAndroid Build Coastguard Worker if (__result != VK_SUCCESS) { \
98*61046927SAndroid Build Coastguard Worker fprintf(stderr, "'%s' line %i failed with %s\n", \
99*61046927SAndroid Build Coastguard Worker #expr, __LINE__, vk_Result_to_str(__result)); \
100*61046927SAndroid Build Coastguard Worker } \
101*61046927SAndroid Build Coastguard Worker } while (0)
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker /**/
104*61046927SAndroid Build Coastguard Worker
override_queue(struct device_data * device_data,VkDevice device,uint32_t queue_family_index,VkQueue queue)105*61046927SAndroid Build Coastguard Worker static void override_queue(struct device_data *device_data,
106*61046927SAndroid Build Coastguard Worker VkDevice device,
107*61046927SAndroid Build Coastguard Worker uint32_t queue_family_index,
108*61046927SAndroid Build Coastguard Worker VkQueue queue)
109*61046927SAndroid Build Coastguard Worker {
110*61046927SAndroid Build Coastguard Worker VkCommandPoolCreateInfo cmd_buffer_pool_info = {
111*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
112*61046927SAndroid Build Coastguard Worker .queueFamilyIndex = queue_family_index,
113*61046927SAndroid Build Coastguard Worker };
114*61046927SAndroid Build Coastguard Worker VkCommandPool cmd_pool;
115*61046927SAndroid Build Coastguard Worker VK_CHECK(device_data->vtable.CreateCommandPool(device,
116*61046927SAndroid Build Coastguard Worker &cmd_buffer_pool_info,
117*61046927SAndroid Build Coastguard Worker NULL, &cmd_pool));
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker VkCommandBufferAllocateInfo cmd_buffer_info = {
121*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
122*61046927SAndroid Build Coastguard Worker .commandPool = cmd_pool,
123*61046927SAndroid Build Coastguard Worker .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
124*61046927SAndroid Build Coastguard Worker .commandBufferCount = 1,
125*61046927SAndroid Build Coastguard Worker };
126*61046927SAndroid Build Coastguard Worker VkCommandBuffer cmd_buffer;
127*61046927SAndroid Build Coastguard Worker VK_CHECK(device_data->vtable.AllocateCommandBuffers(device,
128*61046927SAndroid Build Coastguard Worker &cmd_buffer_info,
129*61046927SAndroid Build Coastguard Worker &cmd_buffer));
130*61046927SAndroid Build Coastguard Worker VK_CHECK(device_data->set_device_loader_data(device, cmd_buffer));
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker VkCommandBufferBeginInfo buffer_begin_info = {
133*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
134*61046927SAndroid Build Coastguard Worker };
135*61046927SAndroid Build Coastguard Worker device_data->vtable.BeginCommandBuffer(cmd_buffer, &buffer_begin_info);
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker VkPerformanceOverrideInfoINTEL override_info = {
138*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL,
139*61046927SAndroid Build Coastguard Worker .type = VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL,
140*61046927SAndroid Build Coastguard Worker .enable = VK_TRUE,
141*61046927SAndroid Build Coastguard Worker };
142*61046927SAndroid Build Coastguard Worker device_data->vtable.CmdSetPerformanceOverrideINTEL(cmd_buffer, &override_info);
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker device_data->vtable.EndCommandBuffer(cmd_buffer);
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker VkSubmitInfo submit_info = {
147*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
148*61046927SAndroid Build Coastguard Worker .commandBufferCount = 1,
149*61046927SAndroid Build Coastguard Worker .pCommandBuffers = &cmd_buffer,
150*61046927SAndroid Build Coastguard Worker };
151*61046927SAndroid Build Coastguard Worker VK_CHECK(device_data->vtable.QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE));
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker VK_CHECK(device_data->vtable.QueueWaitIdle(queue));
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker device_data->vtable.DestroyCommandPool(device, cmd_pool, NULL);
156*61046927SAndroid Build Coastguard Worker }
157*61046927SAndroid Build Coastguard Worker
device_override_queues(struct device_data * device_data,const VkDeviceCreateInfo * pCreateInfo)158*61046927SAndroid Build Coastguard Worker static void device_override_queues(struct device_data *device_data,
159*61046927SAndroid Build Coastguard Worker const VkDeviceCreateInfo *pCreateInfo)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
162*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0; j < pCreateInfo->pQueueCreateInfos[i].queueCount; j++) {
163*61046927SAndroid Build Coastguard Worker VkQueue queue;
164*61046927SAndroid Build Coastguard Worker device_data->vtable.GetDeviceQueue(device_data->device,
165*61046927SAndroid Build Coastguard Worker pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex,
166*61046927SAndroid Build Coastguard Worker j, &queue);
167*61046927SAndroid Build Coastguard Worker
168*61046927SAndroid Build Coastguard Worker VK_CHECK(device_data->set_device_loader_data(device_data->device, queue));
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker override_queue(device_data, device_data->device,
171*61046927SAndroid Build Coastguard Worker pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex, queue);
172*61046927SAndroid Build Coastguard Worker }
173*61046927SAndroid Build Coastguard Worker }
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker
get_device_chain_info(const VkDeviceCreateInfo * pCreateInfo,VkLayerFunction func)176*61046927SAndroid Build Coastguard Worker static VkLayerDeviceCreateInfo *get_device_chain_info(const VkDeviceCreateInfo *pCreateInfo,
177*61046927SAndroid Build Coastguard Worker VkLayerFunction func)
178*61046927SAndroid Build Coastguard Worker {
179*61046927SAndroid Build Coastguard Worker vk_foreach_struct_const(item, pCreateInfo->pNext) {
180*61046927SAndroid Build Coastguard Worker if (item->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO &&
181*61046927SAndroid Build Coastguard Worker ((VkLayerDeviceCreateInfo *) item)->function == func)
182*61046927SAndroid Build Coastguard Worker return (VkLayerDeviceCreateInfo *)item;
183*61046927SAndroid Build Coastguard Worker }
184*61046927SAndroid Build Coastguard Worker unreachable("device chain info not found");
185*61046927SAndroid Build Coastguard Worker return NULL;
186*61046927SAndroid Build Coastguard Worker }
187*61046927SAndroid Build Coastguard Worker
new_device_data(VkDevice device,struct instance_data * instance)188*61046927SAndroid Build Coastguard Worker static struct device_data *new_device_data(VkDevice device, struct instance_data *instance)
189*61046927SAndroid Build Coastguard Worker {
190*61046927SAndroid Build Coastguard Worker struct device_data *data = calloc(1, sizeof(*data));
191*61046927SAndroid Build Coastguard Worker data->instance = instance;
192*61046927SAndroid Build Coastguard Worker data->device = device;
193*61046927SAndroid Build Coastguard Worker map_object(HKEY(data->device), data);
194*61046927SAndroid Build Coastguard Worker return data;
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker
destroy_device_data(struct device_data * data)197*61046927SAndroid Build Coastguard Worker static void destroy_device_data(struct device_data *data)
198*61046927SAndroid Build Coastguard Worker {
199*61046927SAndroid Build Coastguard Worker unmap_object(HKEY(data->device));
200*61046927SAndroid Build Coastguard Worker free(data);
201*61046927SAndroid Build Coastguard Worker }
202*61046927SAndroid Build Coastguard Worker
nullhw_CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)203*61046927SAndroid Build Coastguard Worker static VkResult nullhw_CreateDevice(
204*61046927SAndroid Build Coastguard Worker VkPhysicalDevice physicalDevice,
205*61046927SAndroid Build Coastguard Worker const VkDeviceCreateInfo* pCreateInfo,
206*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator,
207*61046927SAndroid Build Coastguard Worker VkDevice* pDevice)
208*61046927SAndroid Build Coastguard Worker {
209*61046927SAndroid Build Coastguard Worker VkLayerDeviceCreateInfo *chain_info =
210*61046927SAndroid Build Coastguard Worker get_device_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker assert(chain_info->u.pLayerInfo);
213*61046927SAndroid Build Coastguard Worker PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
214*61046927SAndroid Build Coastguard Worker PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
215*61046927SAndroid Build Coastguard Worker PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
216*61046927SAndroid Build Coastguard Worker if (fpCreateDevice == NULL) {
217*61046927SAndroid Build Coastguard Worker return VK_ERROR_INITIALIZATION_FAILED;
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker // Advance the link info for the next element on the chain
221*61046927SAndroid Build Coastguard Worker chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker VkDeviceCreateInfo device_info = *pCreateInfo;
224*61046927SAndroid Build Coastguard Worker const char **extensions = calloc(device_info.enabledExtensionCount + 1, sizeof(*extensions));
225*61046927SAndroid Build Coastguard Worker bool found = false;
226*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < device_info.enabledExtensionCount; i++) {
227*61046927SAndroid Build Coastguard Worker if (!strcmp(device_info.ppEnabledExtensionNames[i], "VK_INTEL_performance_query")) {
228*61046927SAndroid Build Coastguard Worker found = true;
229*61046927SAndroid Build Coastguard Worker break;
230*61046927SAndroid Build Coastguard Worker }
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker if (!found) {
233*61046927SAndroid Build Coastguard Worker memcpy(extensions, device_info.ppEnabledExtensionNames,
234*61046927SAndroid Build Coastguard Worker sizeof(*extensions) * device_info.enabledExtensionCount);
235*61046927SAndroid Build Coastguard Worker extensions[device_info.enabledExtensionCount++] = "VK_INTEL_performance_query";
236*61046927SAndroid Build Coastguard Worker device_info.ppEnabledExtensionNames = extensions;
237*61046927SAndroid Build Coastguard Worker }
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker VkResult result = fpCreateDevice(physicalDevice, &device_info, pAllocator, pDevice);
240*61046927SAndroid Build Coastguard Worker free(extensions);
241*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) return result;
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker struct instance_data *instance_data = FIND(struct instance_data, physicalDevice);
244*61046927SAndroid Build Coastguard Worker struct device_data *device_data = new_device_data(*pDevice, instance_data);
245*61046927SAndroid Build Coastguard Worker device_data->physical_device = physicalDevice;
246*61046927SAndroid Build Coastguard Worker vk_device_dispatch_table_load(&device_data->vtable, fpGetDeviceProcAddr, *pDevice);
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker VkLayerDeviceCreateInfo *load_data_info =
249*61046927SAndroid Build Coastguard Worker get_device_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK);
250*61046927SAndroid Build Coastguard Worker device_data->set_device_loader_data = load_data_info->u.pfnSetDeviceLoaderData;
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker device_override_queues(device_data, pCreateInfo);
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker return result;
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker
nullhw_DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)257*61046927SAndroid Build Coastguard Worker static void nullhw_DestroyDevice(
258*61046927SAndroid Build Coastguard Worker VkDevice device,
259*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator)
260*61046927SAndroid Build Coastguard Worker {
261*61046927SAndroid Build Coastguard Worker struct device_data *device_data = FIND(struct device_data, device);
262*61046927SAndroid Build Coastguard Worker device_data->vtable.DestroyDevice(device, pAllocator);
263*61046927SAndroid Build Coastguard Worker destroy_device_data(device_data);
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker
new_instance_data(VkInstance instance)266*61046927SAndroid Build Coastguard Worker static struct instance_data *new_instance_data(VkInstance instance)
267*61046927SAndroid Build Coastguard Worker {
268*61046927SAndroid Build Coastguard Worker struct instance_data *data = calloc(1, sizeof(*data));
269*61046927SAndroid Build Coastguard Worker data->instance = instance;
270*61046927SAndroid Build Coastguard Worker map_object(HKEY(data->instance), data);
271*61046927SAndroid Build Coastguard Worker return data;
272*61046927SAndroid Build Coastguard Worker }
273*61046927SAndroid Build Coastguard Worker
destroy_instance_data(struct instance_data * data)274*61046927SAndroid Build Coastguard Worker static void destroy_instance_data(struct instance_data *data)
275*61046927SAndroid Build Coastguard Worker {
276*61046927SAndroid Build Coastguard Worker unmap_object(HKEY(data->instance));
277*61046927SAndroid Build Coastguard Worker free(data);
278*61046927SAndroid Build Coastguard Worker }
279*61046927SAndroid Build Coastguard Worker
get_instance_chain_info(const VkInstanceCreateInfo * pCreateInfo,VkLayerFunction func)280*61046927SAndroid Build Coastguard Worker static VkLayerInstanceCreateInfo *get_instance_chain_info(const VkInstanceCreateInfo *pCreateInfo,
281*61046927SAndroid Build Coastguard Worker VkLayerFunction func)
282*61046927SAndroid Build Coastguard Worker {
283*61046927SAndroid Build Coastguard Worker vk_foreach_struct_const(item, pCreateInfo->pNext) {
284*61046927SAndroid Build Coastguard Worker if (item->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO &&
285*61046927SAndroid Build Coastguard Worker ((VkLayerInstanceCreateInfo *) item)->function == func)
286*61046927SAndroid Build Coastguard Worker return (VkLayerInstanceCreateInfo *) item;
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker unreachable("instance chain info not found");
289*61046927SAndroid Build Coastguard Worker return NULL;
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker
nullhw_CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)292*61046927SAndroid Build Coastguard Worker static VkResult nullhw_CreateInstance(
293*61046927SAndroid Build Coastguard Worker const VkInstanceCreateInfo* pCreateInfo,
294*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator,
295*61046927SAndroid Build Coastguard Worker VkInstance* pInstance)
296*61046927SAndroid Build Coastguard Worker {
297*61046927SAndroid Build Coastguard Worker VkLayerInstanceCreateInfo *chain_info =
298*61046927SAndroid Build Coastguard Worker get_instance_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker assert(chain_info->u.pLayerInfo);
301*61046927SAndroid Build Coastguard Worker PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
302*61046927SAndroid Build Coastguard Worker chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
303*61046927SAndroid Build Coastguard Worker PFN_vkCreateInstance fpCreateInstance =
304*61046927SAndroid Build Coastguard Worker (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
305*61046927SAndroid Build Coastguard Worker if (fpCreateInstance == NULL) {
306*61046927SAndroid Build Coastguard Worker return VK_ERROR_INITIALIZATION_FAILED;
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker
309*61046927SAndroid Build Coastguard Worker // Advance the link info for the next element on the chain
310*61046927SAndroid Build Coastguard Worker chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
313*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) return result;
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker struct instance_data *instance_data = new_instance_data(*pInstance);
316*61046927SAndroid Build Coastguard Worker vk_instance_dispatch_table_load(&instance_data->vtable,
317*61046927SAndroid Build Coastguard Worker fpGetInstanceProcAddr,
318*61046927SAndroid Build Coastguard Worker instance_data->instance);
319*61046927SAndroid Build Coastguard Worker
320*61046927SAndroid Build Coastguard Worker return result;
321*61046927SAndroid Build Coastguard Worker }
322*61046927SAndroid Build Coastguard Worker
nullhw_DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)323*61046927SAndroid Build Coastguard Worker static void nullhw_DestroyInstance(
324*61046927SAndroid Build Coastguard Worker VkInstance instance,
325*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator)
326*61046927SAndroid Build Coastguard Worker {
327*61046927SAndroid Build Coastguard Worker struct instance_data *instance_data = FIND(struct instance_data, instance);
328*61046927SAndroid Build Coastguard Worker instance_data->vtable.DestroyInstance(instance, pAllocator);
329*61046927SAndroid Build Coastguard Worker destroy_instance_data(instance_data);
330*61046927SAndroid Build Coastguard Worker }
331*61046927SAndroid Build Coastguard Worker
332*61046927SAndroid Build Coastguard Worker static const struct {
333*61046927SAndroid Build Coastguard Worker const char *name;
334*61046927SAndroid Build Coastguard Worker void *ptr;
335*61046927SAndroid Build Coastguard Worker } name_to_funcptr_map[] = {
336*61046927SAndroid Build Coastguard Worker { "vkGetDeviceProcAddr", (void *) vkGetDeviceProcAddr },
337*61046927SAndroid Build Coastguard Worker #define ADD_HOOK(fn) { "vk" # fn, (void *) nullhw_ ## fn }
338*61046927SAndroid Build Coastguard Worker ADD_HOOK(CreateInstance),
339*61046927SAndroid Build Coastguard Worker ADD_HOOK(DestroyInstance),
340*61046927SAndroid Build Coastguard Worker ADD_HOOK(CreateDevice),
341*61046927SAndroid Build Coastguard Worker ADD_HOOK(DestroyDevice),
342*61046927SAndroid Build Coastguard Worker };
343*61046927SAndroid Build Coastguard Worker
find_ptr(const char * name)344*61046927SAndroid Build Coastguard Worker static void *find_ptr(const char *name)
345*61046927SAndroid Build Coastguard Worker {
346*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(name_to_funcptr_map); i++) {
347*61046927SAndroid Build Coastguard Worker if (strcmp(name, name_to_funcptr_map[i].name) == 0)
348*61046927SAndroid Build Coastguard Worker return name_to_funcptr_map[i].ptr;
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker
351*61046927SAndroid Build Coastguard Worker return NULL;
352*61046927SAndroid Build Coastguard Worker }
353*61046927SAndroid Build Coastguard Worker
vkGetDeviceProcAddr(VkDevice dev,const char * funcName)354*61046927SAndroid Build Coastguard Worker PUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev,
355*61046927SAndroid Build Coastguard Worker const char *funcName)
356*61046927SAndroid Build Coastguard Worker {
357*61046927SAndroid Build Coastguard Worker void *ptr = find_ptr(funcName);
358*61046927SAndroid Build Coastguard Worker if (ptr) return (PFN_vkVoidFunction)(ptr);
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker if (dev == NULL) return NULL;
361*61046927SAndroid Build Coastguard Worker
362*61046927SAndroid Build Coastguard Worker struct device_data *device_data = FIND(struct device_data, dev);
363*61046927SAndroid Build Coastguard Worker if (device_data->vtable.GetDeviceProcAddr == NULL) return NULL;
364*61046927SAndroid Build Coastguard Worker return device_data->vtable.GetDeviceProcAddr(dev, funcName);
365*61046927SAndroid Build Coastguard Worker }
366*61046927SAndroid Build Coastguard Worker
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)367*61046927SAndroid Build Coastguard Worker PUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
368*61046927SAndroid Build Coastguard Worker const char *funcName)
369*61046927SAndroid Build Coastguard Worker {
370*61046927SAndroid Build Coastguard Worker void *ptr = find_ptr(funcName);
371*61046927SAndroid Build Coastguard Worker if (ptr) return (PFN_vkVoidFunction) ptr;
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker struct instance_data *instance_data = FIND(struct instance_data, instance);
374*61046927SAndroid Build Coastguard Worker if (instance_data->vtable.GetInstanceProcAddr == NULL) return NULL;
375*61046927SAndroid Build Coastguard Worker return instance_data->vtable.GetInstanceProcAddr(instance, funcName);
376*61046927SAndroid Build Coastguard Worker }
377