1 /*
2 * Copyright (c) 2015-2016 The Khronos Group Inc.
3 * Copyright (c) 2015-2016 Valve Corporation
4 * Copyright (c) 2015-2016 LunarG, Inc.
5 * Copyright (c) 2015-2016 Google, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * Author: Tobin Ehlis <tobine@google.com>
20 * Author: Mark Lobodzinski <mark@lunarg.com>
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unordered_map>
27 #include <vector>
28 #include <list>
29 #include <memory>
30
31 #include "vk_loader_platform.h"
32 #include "vulkan/vk_layer.h"
33 #include "vk_layer_config.h"
34 #include "vk_layer_extension_utils.h"
35 #include "vk_layer_utils.h"
36 #include "vk_layer_table.h"
37 #include "vk_layer_logging.h"
38 #include "unique_objects.h"
39 #include "vk_dispatch_table_helper.h"
40 #include "vk_struct_string_helper_cpp.h"
41 #include "vk_layer_data.h"
42 #include "vk_layer_utils.h"
43
44 #include "unique_objects_wrappers.h"
45
46 namespace unique_objects {
47
initUniqueObjects(layer_data * instance_data,const VkAllocationCallbacks * pAllocator)48 static void initUniqueObjects(layer_data *instance_data, const VkAllocationCallbacks *pAllocator) {
49 layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "google_unique_objects");
50 }
51
52 // Handle CreateInstance Extensions
checkInstanceRegisterExtensions(const VkInstanceCreateInfo * pCreateInfo,VkInstance instance)53 static void checkInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
54 uint32_t i;
55 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
56 VkLayerInstanceDispatchTable *disp_table = instance_data->instance_dispatch_table;
57 instance_ext_map[disp_table] = {};
58
59 for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
60 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
61 instance_ext_map[disp_table].wsi_enabled = true;
62 }
63 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
64 instance_ext_map[disp_table].display_enabled = true;
65 }
66 #ifdef VK_USE_PLATFORM_XLIB_KHR
67 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
68 instance_ext_map[disp_table].xlib_enabled = true;
69 }
70 #endif
71 #ifdef VK_USE_PLATFORM_XCB_KHR
72 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
73 instance_ext_map[disp_table].xcb_enabled = true;
74 }
75 #endif
76 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
77 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
78 instance_ext_map[disp_table].wayland_enabled = true;
79 }
80 #endif
81 #ifdef VK_USE_PLATFORM_MIR_KHR
82 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
83 instance_ext_map[disp_table].mir_enabled = true;
84 }
85 #endif
86 #ifdef VK_USE_PLATFORM_ANDROID_KHR
87 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
88 instance_ext_map[disp_table].android_enabled = true;
89 }
90 #endif
91 #ifdef VK_USE_PLATFORM_WIN32_KHR
92 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
93 instance_ext_map[disp_table].win32_enabled = true;
94 }
95 #endif
96
97 // Check for recognized instance extensions
98 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
99 if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kUniqueObjectsSupportedInstanceExtensions)) {
100 log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
101 0, "UniqueObjects",
102 "Instance Extension %s is not supported by this layer. Using this extension may adversely affect "
103 "validation results and/or produce undefined behavior.",
104 pCreateInfo->ppEnabledExtensionNames[i]);
105 }
106 }
107 }
108
109 // Handle CreateDevice Extensions
createDeviceRegisterExtensions(const VkDeviceCreateInfo * pCreateInfo,VkDevice device)110 static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
111 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
112 VkLayerDispatchTable *disp_table = device_data->device_dispatch_table;
113 PFN_vkGetDeviceProcAddr gpa = disp_table->GetDeviceProcAddr;
114
115 device_data->device_dispatch_table->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
116 disp_table->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
117 disp_table->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
118 disp_table->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
119 disp_table->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
120 device_data->wsi_enabled = false;
121
122 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
123 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
124 device_data->wsi_enabled = true;
125 }
126 // Check for recognized device extensions
127 if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kUniqueObjectsSupportedDeviceExtensions)) {
128 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
129 0, "UniqueObjects",
130 "Device Extension %s is not supported by this layer. Using this extension may adversely affect "
131 "validation results and/or produce undefined behavior.",
132 pCreateInfo->ppEnabledExtensionNames[i]);
133 }
134 }
135 }
136
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)137 VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
138 VkInstance *pInstance) {
139 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
140
141 assert(chain_info->u.pLayerInfo);
142 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
143 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
144 if (fpCreateInstance == NULL) {
145 return VK_ERROR_INITIALIZATION_FAILED;
146 }
147
148 // Advance the link info for the next element on the chain
149 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
150
151 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
152 if (result != VK_SUCCESS) {
153 return result;
154 }
155
156 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
157 instance_data->instance = *pInstance;
158 instance_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
159 layer_init_instance_dispatch_table(*pInstance, instance_data->instance_dispatch_table, fpGetInstanceProcAddr);
160
161 instance_data->instance = *pInstance;
162 instance_data->report_data =
163 debug_report_create_instance(instance_data->instance_dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount,
164 pCreateInfo->ppEnabledExtensionNames);
165
166 // Set up temporary debug callbacks to output messages at CreateInstance-time
167 if (!layer_copy_tmp_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_callbacks, &instance_data->tmp_dbg_create_infos,
168 &instance_data->tmp_callbacks)) {
169 if (instance_data->num_tmp_callbacks > 0) {
170 if (layer_enable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks,
171 instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks)) {
172 layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
173 instance_data->num_tmp_callbacks = 0;
174 }
175 }
176 }
177
178 initUniqueObjects(instance_data, pAllocator);
179 checkInstanceRegisterExtensions(pCreateInfo, *pInstance);
180
181 // Disable and free tmp callbacks, no longer necessary
182 if (instance_data->num_tmp_callbacks > 0) {
183 layer_disable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks, instance_data->tmp_callbacks);
184 layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
185 instance_data->num_tmp_callbacks = 0;
186 }
187
188 return result;
189 }
190
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)191 VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
192 dispatch_key key = get_dispatch_key(instance);
193 layer_data *instance_data = get_my_data_ptr(key, layer_data_map);
194 VkLayerInstanceDispatchTable *disp_table = instance_data->instance_dispatch_table;
195 instance_ext_map.erase(disp_table);
196 disp_table->DestroyInstance(instance, pAllocator);
197
198 // Clean up logging callback, if any
199 while (instance_data->logging_callback.size() > 0) {
200 VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
201 layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
202 instance_data->logging_callback.pop_back();
203 }
204
205 layer_debug_report_destroy_instance(instance_data->report_data);
206 layer_data_map.erase(key);
207 }
208
CreateDevice(VkPhysicalDevice gpu,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)209 VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
210 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
211 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
212 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
213
214 assert(chain_info->u.pLayerInfo);
215 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
216 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
217 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
218 if (fpCreateDevice == NULL) {
219 return VK_ERROR_INITIALIZATION_FAILED;
220 }
221
222 // Advance the link info for the next element on the chain
223 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
224
225 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
226 if (result != VK_SUCCESS) {
227 return result;
228 }
229
230 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
231 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
232
233 // Setup layer's device dispatch table
234 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
235 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
236
237 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
238 // Set gpu for this device in order to get at any objects mapped at instance level
239
240 my_device_data->gpu = gpu;
241
242 return result;
243 }
244
DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)245 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
246 dispatch_key key = get_dispatch_key(device);
247 layer_data *dev_data = get_my_data_ptr(key, layer_data_map);
248
249 layer_debug_report_destroy_device(device);
250 dev_data->device_dispatch_table->DestroyDevice(device, pAllocator);
251 layer_data_map.erase(key);
252 }
253
254 static const VkLayerProperties globalLayerProps = {"VK_LAYER_GOOGLE_unique_objects",
255 VK_LAYER_API_VERSION, // specVersion
256 1, // implementationVersion
257 "Google Validation Layer"};
258
layer_intercept_proc(const char * name)259 static inline PFN_vkVoidFunction layer_intercept_proc(const char *name) {
260 for (int i = 0; i < sizeof(procmap) / sizeof(procmap[0]); i++) {
261 if (!strcmp(name, procmap[i].name))
262 return procmap[i].pFunc;
263 }
264 return NULL;
265 }
266
EnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)267 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
268 return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);
269 }
270
EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)271 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
272 VkLayerProperties *pProperties) {
273 return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);
274 }
275
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)276 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
277 VkExtensionProperties *pProperties) {
278 if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))
279 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
280
281 return VK_ERROR_LAYER_NOT_PRESENT;
282 }
283
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)284 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
285 uint32_t *pCount, VkExtensionProperties *pProperties) {
286 if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))
287 return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
288
289 assert(physicalDevice);
290
291 dispatch_key key = get_dispatch_key(physicalDevice);
292 layer_data *instance_data = get_my_data_ptr(key, layer_data_map);
293 return instance_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
294 }
295
GetDeviceProcAddr(VkDevice device,const char * funcName)296 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
297 PFN_vkVoidFunction addr;
298 assert(device);
299 addr = layer_intercept_proc(funcName);
300 if (addr) {
301 return addr;
302 }
303
304 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
305 VkLayerDispatchTable *disp_table = dev_data->device_dispatch_table;
306 if (disp_table->GetDeviceProcAddr == NULL) {
307 return NULL;
308 }
309 return disp_table->GetDeviceProcAddr(device, funcName);
310 }
311
GetInstanceProcAddr(VkInstance instance,const char * funcName)312 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
313 PFN_vkVoidFunction addr;
314
315 addr = layer_intercept_proc(funcName);
316 if (addr) {
317 return addr;
318 }
319 assert(instance);
320
321 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
322 addr = debug_report_get_instance_proc_addr(instance_data->report_data, funcName);
323 if (addr) {
324 return addr;
325 }
326
327 VkLayerInstanceDispatchTable *disp_table = instance_data->instance_dispatch_table;
328 if (disp_table->GetInstanceProcAddr == NULL) {
329 return NULL;
330 }
331 return disp_table->GetInstanceProcAddr(instance, funcName);
332 }
333
AllocateMemory(VkDevice device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMemory)334 VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
335 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
336 const VkMemoryAllocateInfo *input_allocate_info = pAllocateInfo;
337 std::unique_ptr<safe_VkMemoryAllocateInfo> safe_allocate_info;
338 std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV> safe_dedicated_allocate_info;
339 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
340
341 if ((pAllocateInfo != nullptr) &&
342 ContainsExtStruct(pAllocateInfo, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)) {
343 // Assuming there is only one extension struct of this type in the list for now
344 safe_dedicated_allocate_info =
345 std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV>(new safe_VkDedicatedAllocationMemoryAllocateInfoNV);
346 safe_allocate_info = std::unique_ptr<safe_VkMemoryAllocateInfo>(new safe_VkMemoryAllocateInfo(pAllocateInfo));
347 input_allocate_info = reinterpret_cast<const VkMemoryAllocateInfo *>(safe_allocate_info.get());
348
349 const GenericHeader *orig_pnext = reinterpret_cast<const GenericHeader *>(pAllocateInfo->pNext);
350 GenericHeader *input_pnext = reinterpret_cast<GenericHeader *>(safe_allocate_info.get());
351 while (orig_pnext != nullptr) {
352 if (orig_pnext->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV) {
353 safe_dedicated_allocate_info->initialize(
354 reinterpret_cast<const VkDedicatedAllocationMemoryAllocateInfoNV *>(orig_pnext));
355
356 std::unique_lock<std::mutex> lock(global_lock);
357
358 if (safe_dedicated_allocate_info->buffer != VK_NULL_HANDLE) {
359 uint64_t local_buffer = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->buffer);
360 safe_dedicated_allocate_info->buffer =
361 reinterpret_cast<VkBuffer &>(device_data->unique_id_mapping[local_buffer]);
362 }
363
364 if (safe_dedicated_allocate_info->image != VK_NULL_HANDLE) {
365 uint64_t local_image = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->image);
366 safe_dedicated_allocate_info->image = reinterpret_cast<VkImage &>(device_data->unique_id_mapping[local_image]);
367 }
368
369 lock.unlock();
370
371 input_pnext->pNext = reinterpret_cast<GenericHeader *>(safe_dedicated_allocate_info.get());
372 input_pnext = reinterpret_cast<GenericHeader *>(input_pnext->pNext);
373 } else {
374 // TODO: generic handling of pNext copies
375 }
376
377 orig_pnext = reinterpret_cast<const GenericHeader *>(orig_pnext->pNext);
378 }
379 }
380
381 VkResult result = device_data->device_dispatch_table->AllocateMemory(device, input_allocate_info, pAllocator, pMemory);
382
383 if (VK_SUCCESS == result) {
384 std::lock_guard<std::mutex> lock(global_lock);
385 uint64_t unique_id = global_unique_id++;
386 device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pMemory);
387 *pMemory = reinterpret_cast<VkDeviceMemory &>(unique_id);
388 }
389
390 return result;
391 }
392
CreateComputePipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)393 VKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
394 const VkComputePipelineCreateInfo *pCreateInfos,
395 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
396 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
397 safe_VkComputePipelineCreateInfo *local_pCreateInfos = NULL;
398 if (pCreateInfos) {
399 std::lock_guard<std::mutex> lock(global_lock);
400 local_pCreateInfos = new safe_VkComputePipelineCreateInfo[createInfoCount];
401 for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
402 local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
403 if (pCreateInfos[idx0].basePipelineHandle) {
404 local_pCreateInfos[idx0].basePipelineHandle =
405 (VkPipeline)my_device_data
406 ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].basePipelineHandle)];
407 }
408 if (pCreateInfos[idx0].layout) {
409 local_pCreateInfos[idx0].layout =
410 (VkPipelineLayout)
411 my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].layout)];
412 }
413 if (pCreateInfos[idx0].stage.module) {
414 local_pCreateInfos[idx0].stage.module =
415 (VkShaderModule)
416 my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].stage.module)];
417 }
418 }
419 }
420 if (pipelineCache) {
421 std::lock_guard<std::mutex> lock(global_lock);
422 pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(pipelineCache)];
423 }
424
425 VkResult result = my_device_data->device_dispatch_table->CreateComputePipelines(
426 device, pipelineCache, createInfoCount, (const VkComputePipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
427 delete[] local_pCreateInfos;
428 if (VK_SUCCESS == result) {
429 uint64_t unique_id = 0;
430 std::lock_guard<std::mutex> lock(global_lock);
431 for (uint32_t i = 0; i < createInfoCount; ++i) {
432 unique_id = global_unique_id++;
433 my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pPipelines[i]);
434 pPipelines[i] = reinterpret_cast<VkPipeline &>(unique_id);
435 }
436 }
437 return result;
438 }
439
CreateGraphicsPipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)440 VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
441 const VkGraphicsPipelineCreateInfo *pCreateInfos,
442 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
443 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
444 safe_VkGraphicsPipelineCreateInfo *local_pCreateInfos = NULL;
445 if (pCreateInfos) {
446 local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount];
447 std::lock_guard<std::mutex> lock(global_lock);
448 for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
449 local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
450 if (pCreateInfos[idx0].basePipelineHandle) {
451 local_pCreateInfos[idx0].basePipelineHandle =
452 (VkPipeline)my_device_data
453 ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].basePipelineHandle)];
454 }
455 if (pCreateInfos[idx0].layout) {
456 local_pCreateInfos[idx0].layout =
457 (VkPipelineLayout)
458 my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].layout)];
459 }
460 if (pCreateInfos[idx0].pStages) {
461 for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
462 if (pCreateInfos[idx0].pStages[idx1].module) {
463 local_pCreateInfos[idx0].pStages[idx1].module =
464 (VkShaderModule)my_device_data
465 ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].pStages[idx1].module)];
466 }
467 }
468 }
469 if (pCreateInfos[idx0].renderPass) {
470 local_pCreateInfos[idx0].renderPass =
471 (VkRenderPass)
472 my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].renderPass)];
473 }
474 }
475 }
476 if (pipelineCache) {
477 std::lock_guard<std::mutex> lock(global_lock);
478 pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(pipelineCache)];
479 }
480
481 VkResult result = my_device_data->device_dispatch_table->CreateGraphicsPipelines(
482 device, pipelineCache, createInfoCount, (const VkGraphicsPipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
483 delete[] local_pCreateInfos;
484 if (VK_SUCCESS == result) {
485 uint64_t unique_id = 0;
486 std::lock_guard<std::mutex> lock(global_lock);
487 for (uint32_t i = 0; i < createInfoCount; ++i) {
488 unique_id = global_unique_id++;
489 my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pPipelines[i]);
490 pPipelines[i] = reinterpret_cast<VkPipeline &>(unique_id);
491 }
492 }
493 return result;
494 }
495
CreateDebugReportCallbackEXT(VkInstance instance,const VkDebugReportCallbackCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugReportCallbackEXT * pMsgCallback)496 VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
497 const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
498 const VkAllocationCallbacks *pAllocator,
499 VkDebugReportCallbackEXT *pMsgCallback) {
500 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
501 VkResult result =
502 instance_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
503
504 if (VK_SUCCESS == result) {
505 result = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
506 }
507 return result;
508 }
509
DestroyDebugReportCallbackEXT(VkInstance instance,VkDebugReportCallbackEXT callback,const VkAllocationCallbacks * pAllocator)510 VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
511 const VkAllocationCallbacks *pAllocator) {
512 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
513 instance_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
514 layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
515 }
516
DebugReportMessageEXT(VkInstance instance,VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT objType,uint64_t object,size_t location,int32_t msgCode,const char * pLayerPrefix,const char * pMsg)517 VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
518 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
519 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
520 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
521 instance_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
522 pMsg);
523 }
524
CreateSwapchainKHR(VkDevice device,const VkSwapchainCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchain)525 VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
526 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
527 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
528 safe_VkSwapchainCreateInfoKHR *local_pCreateInfo = NULL;
529 if (pCreateInfo) {
530 std::lock_guard<std::mutex> lock(global_lock);
531 local_pCreateInfo = new safe_VkSwapchainCreateInfoKHR(pCreateInfo);
532 local_pCreateInfo->oldSwapchain =
533 (VkSwapchainKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->oldSwapchain)];
534 // Need to pull surface mapping from the instance-level map
535 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(my_map_data->gpu), layer_data_map);
536 local_pCreateInfo->surface =
537 (VkSurfaceKHR)instance_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->surface)];
538 }
539
540 VkResult result = my_map_data->device_dispatch_table->CreateSwapchainKHR(
541 device, (const VkSwapchainCreateInfoKHR *)local_pCreateInfo, pAllocator, pSwapchain);
542 if (local_pCreateInfo) {
543 delete local_pCreateInfo;
544 }
545 if (VK_SUCCESS == result) {
546 std::lock_guard<std::mutex> lock(global_lock);
547 uint64_t unique_id = global_unique_id++;
548 my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pSwapchain);
549 *pSwapchain = reinterpret_cast<VkSwapchainKHR &>(unique_id);
550 }
551 return result;
552 }
553
GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR swapchain,uint32_t * pSwapchainImageCount,VkImage * pSwapchainImages)554 VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
555 VkImage *pSwapchainImages) {
556 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
557 if (VK_NULL_HANDLE != swapchain) {
558 std::lock_guard<std::mutex> lock(global_lock);
559 swapchain = (VkSwapchainKHR)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(swapchain)];
560 }
561 VkResult result =
562 my_device_data->device_dispatch_table->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
563 // TODO : Need to add corresponding code to delete these images
564 if (VK_SUCCESS == result) {
565 if ((*pSwapchainImageCount > 0) && pSwapchainImages) {
566 uint64_t unique_id = 0;
567 std::lock_guard<std::mutex> lock(global_lock);
568 for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) {
569 unique_id = global_unique_id++;
570 my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pSwapchainImages[i]);
571 pSwapchainImages[i] = reinterpret_cast<VkImage &>(unique_id);
572 }
573 }
574 }
575 return result;
576 }
577
578 #ifndef __ANDROID__
GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkDisplayPropertiesKHR * pProperties)579 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
580 VkDisplayPropertiesKHR *pProperties) {
581 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
582 safe_VkDisplayPropertiesKHR *local_pProperties = NULL;
583 {
584 std::lock_guard<std::mutex> lock(global_lock);
585 if (pProperties) {
586 local_pProperties = new safe_VkDisplayPropertiesKHR[*pPropertyCount];
587 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
588 local_pProperties[idx0].initialize(&pProperties[idx0]);
589 if (pProperties[idx0].display) {
590 local_pProperties[idx0].display =
591 (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pProperties[idx0].display)];
592 }
593 }
594 }
595 }
596
597 VkResult result = my_map_data->instance_dispatch_table->GetPhysicalDeviceDisplayPropertiesKHR(
598 physicalDevice, pPropertyCount, (VkDisplayPropertiesKHR *)local_pProperties);
599 if (result == VK_SUCCESS && pProperties) {
600 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
601 std::lock_guard<std::mutex> lock(global_lock);
602
603 uint64_t unique_id = global_unique_id++;
604 my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].display);
605 pProperties[idx0].display = reinterpret_cast<VkDisplayKHR &>(unique_id);
606 pProperties[idx0].displayName = local_pProperties[idx0].displayName;
607 pProperties[idx0].physicalDimensions = local_pProperties[idx0].physicalDimensions;
608 pProperties[idx0].physicalResolution = local_pProperties[idx0].physicalResolution;
609 pProperties[idx0].supportedTransforms = local_pProperties[idx0].supportedTransforms;
610 pProperties[idx0].planeReorderPossible = local_pProperties[idx0].planeReorderPossible;
611 pProperties[idx0].persistentContent = local_pProperties[idx0].persistentContent;
612 }
613 }
614 if (local_pProperties) {
615 delete[] local_pProperties;
616 }
617 return result;
618 }
619
GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,uint32_t planeIndex,uint32_t * pDisplayCount,VkDisplayKHR * pDisplays)620 VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
621 uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
622 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
623 VkResult result = my_map_data->instance_dispatch_table->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex,
624 pDisplayCount, pDisplays);
625 if (VK_SUCCESS == result) {
626 if ((*pDisplayCount > 0) && pDisplays) {
627 std::lock_guard<std::mutex> lock(global_lock);
628 for (uint32_t i = 0; i < *pDisplayCount; i++) {
629 auto it = my_map_data->unique_id_mapping.find(reinterpret_cast<const uint64_t &>(pDisplays[i]));
630 assert(it != my_map_data->unique_id_mapping.end());
631 pDisplays[i] = reinterpret_cast<VkDisplayKHR &>(it->second);
632 }
633 }
634 }
635 return result;
636 }
637
GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,VkDisplayKHR display,uint32_t * pPropertyCount,VkDisplayModePropertiesKHR * pProperties)638 VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
639 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
640 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
641 safe_VkDisplayModePropertiesKHR *local_pProperties = NULL;
642 {
643 std::lock_guard<std::mutex> lock(global_lock);
644 display = (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t &>(display)];
645 if (pProperties) {
646 local_pProperties = new safe_VkDisplayModePropertiesKHR[*pPropertyCount];
647 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
648 local_pProperties[idx0].initialize(&pProperties[idx0]);
649 }
650 }
651 }
652
653 VkResult result = my_map_data->instance_dispatch_table->GetDisplayModePropertiesKHR(
654 physicalDevice, display, pPropertyCount, (VkDisplayModePropertiesKHR *)local_pProperties);
655 if (result == VK_SUCCESS && pProperties) {
656 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
657 std::lock_guard<std::mutex> lock(global_lock);
658
659 uint64_t unique_id = global_unique_id++;
660 my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].displayMode);
661 pProperties[idx0].displayMode = reinterpret_cast<VkDisplayModeKHR &>(unique_id);
662 pProperties[idx0].parameters.visibleRegion.width = local_pProperties[idx0].parameters.visibleRegion.width;
663 pProperties[idx0].parameters.visibleRegion.height = local_pProperties[idx0].parameters.visibleRegion.height;
664 pProperties[idx0].parameters.refreshRate = local_pProperties[idx0].parameters.refreshRate;
665 }
666 }
667 if (local_pProperties) {
668 delete[] local_pProperties;
669 }
670 return result;
671 }
672 #endif
673
674 } // namespace unique_objects
675
676 // vk_layer_logging.h expects these to be defined
vkCreateDebugReportCallbackEXT(VkInstance instance,const VkDebugReportCallbackCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugReportCallbackEXT * pMsgCallback)677 VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instance,
678 const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
679 const VkAllocationCallbacks *pAllocator,
680 VkDebugReportCallbackEXT *pMsgCallback) {
681 return unique_objects::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
682 }
683
vkDestroyDebugReportCallbackEXT(VkInstance instance,VkDebugReportCallbackEXT msgCallback,const VkAllocationCallbacks * pAllocator)684 VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
685 const VkAllocationCallbacks *pAllocator) {
686 unique_objects::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
687 }
688
vkDebugReportMessageEXT(VkInstance instance,VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT objType,uint64_t object,size_t location,int32_t msgCode,const char * pLayerPrefix,const char * pMsg)689 VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
690 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
691 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
692 unique_objects::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
693 }
694
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)695 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
696 VkExtensionProperties *pProperties) {
697 return unique_objects::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
698 }
699
vkEnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)700 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
701 VkLayerProperties *pProperties) {
702 return unique_objects::EnumerateInstanceLayerProperties(pCount, pProperties);
703 }
704
vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)705 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
706 VkLayerProperties *pProperties) {
707 assert(physicalDevice == VK_NULL_HANDLE);
708 return unique_objects::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
709 }
710
vkGetDeviceProcAddr(VkDevice dev,const char * funcName)711 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
712 return unique_objects::GetDeviceProcAddr(dev, funcName);
713 }
714
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)715 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
716 return unique_objects::GetInstanceProcAddr(instance, funcName);
717 }
718
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)719 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
720 const char *pLayerName, uint32_t *pCount,
721 VkExtensionProperties *pProperties) {
722 assert(physicalDevice == VK_NULL_HANDLE);
723 return unique_objects::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
724 }
725