blob: 3a0df024e10384aba84c4a487ac62b83cfcf487a [file] [log] [blame]
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -06001/*
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
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -070023#define NOMINMAX
John Zulauf0fe5bfe2018-05-23 09:36:00 -060024#define VALIDATION_ERROR_MAP_IMPL
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -070025
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unordered_map>
30#include <vector>
31#include <list>
32#include <memory>
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -070033#include <algorithm>
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060034
Mike Weiblen6a27de52016-12-09 17:36:28 -070035// For Windows, this #include must come before other Vk headers.
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060036#include "vk_loader_platform.h"
Mike Weiblen6a27de52016-12-09 17:36:28 -070037
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060038#include "unique_objects.h"
39#include "vk_dispatch_table_helper.h"
Mike Weiblen6a27de52016-12-09 17:36:28 -070040#include "vk_layer_config.h"
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060041#include "vk_layer_data.h"
Mike Weiblen6a27de52016-12-09 17:36:28 -070042#include "vk_layer_extension_utils.h"
43#include "vk_layer_logging.h"
44#include "vk_layer_table.h"
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060045#include "vk_layer_utils.h"
Mark Lobodzinski9acd2e32016-12-21 15:22:39 -070046#include "vk_enum_string_helper.h"
Mike Weiblen6a27de52016-12-09 17:36:28 -070047#include "vk_validation_error_messages.h"
Mark Lobodzinski2d9de652017-04-24 08:58:52 -060048#include "vk_object_types.h"
Mark Lobodzinski75a46312018-01-03 11:23:55 -070049#include "vk_extension_helper.h"
Mike Weiblen6a27de52016-12-09 17:36:28 -070050#include "vulkan/vk_layer.h"
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060051
Mike Stroyanb985fca2016-11-01 11:50:16 -060052// This intentionally includes a cpp file
53#include "vk_safe_struct.cpp"
54
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060055#include "unique_objects_wrappers.h"
56
Tobin Ehlis7cbe99b2018-06-21 14:22:01 -060057using mutex_t = std::mutex;
58using lock_guard_t = std::lock_guard<mutex_t>;
59
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060060namespace unique_objects {
61
Mark Young39389872017-01-19 21:10:49 -070062static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
63
Chris Forbes5279a8c2017-05-02 16:26:23 -070064static void initUniqueObjects(instance_layer_data *instance_data, const VkAllocationCallbacks *pAllocator) {
Mark Young6ba8abe2017-11-09 10:37:04 -070065 layer_debug_report_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "google_unique_objects");
66 layer_debug_messenger_actions(instance_data->report_data, instance_data->logging_messenger, pAllocator,
67 "google_unique_objects");
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060068}
69
Mark Lobodzinskic0141472017-06-09 09:51:34 -060070// Check enabled instance extensions against supported instance extension whitelist
71static void InstanceExtensionWhitelist(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
Chris Forbes5279a8c2017-05-02 16:26:23 -070072 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060073
Mark Lobodzinski38686e92017-06-07 16:04:50 -060074 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060075 // Check for recognized instance extensions
Mark Lobodzinski75a46312018-01-03 11:23:55 -070076 if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kInstanceExtensionNames)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -060077 log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Mark Lobodzinski88529492018-04-01 10:38:15 -060078 VALIDATION_ERROR_UNDEFINED,
Dave Houltona9df0ce2018-02-07 10:51:23 -070079 "Instance Extension %s is not supported by this layer. Using this extension may adversely affect validation "
80 "results and/or produce undefined behavior.",
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060081 pCreateInfo->ppEnabledExtensionNames[i]);
82 }
83 }
84}
85
Mark Lobodzinskic0141472017-06-09 09:51:34 -060086// Check enabled device extensions against supported device extension whitelist
87static void DeviceExtensionWhitelist(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
Tobin Ehlis8d6acde2017-02-08 07:40:40 -070088 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060089
90 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060091 // Check for recognized device extensions
Mark Lobodzinski75a46312018-01-03 11:23:55 -070092 if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kDeviceExtensionNames)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -060093 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Mark Lobodzinski88529492018-04-01 10:38:15 -060094 VALIDATION_ERROR_UNDEFINED,
Dave Houltona9df0ce2018-02-07 10:51:23 -070095 "Device Extension %s is not supported by this layer. Using this extension may adversely affect validation "
96 "results and/or produce undefined behavior.",
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -060097 pCreateInfo->ppEnabledExtensionNames[i]);
98 }
99 }
100}
101
102VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
103 VkInstance *pInstance) {
104 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
105
106 assert(chain_info->u.pLayerInfo);
107 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
108 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
109 if (fpCreateInstance == NULL) {
110 return VK_ERROR_INITIALIZATION_FAILED;
111 }
112
113 // Advance the link info for the next element on the chain
114 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
115
116 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
117 if (result != VK_SUCCESS) {
118 return result;
119 }
120
Chris Forbes5279a8c2017-05-02 16:26:23 -0700121 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), instance_layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600122 instance_data->instance = *pInstance;
Chris Forbes44c05302017-05-02 16:42:55 -0700123 layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600124
125 instance_data->instance = *pInstance;
Mark Young6ba8abe2017-11-09 10:37:04 -0700126 instance_data->report_data = debug_utils_create_instance(
Dave Houltona9df0ce2018-02-07 10:51:23 -0700127 &instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600128
129 // Set up temporary debug callbacks to output messages at CreateInstance-time
Mark Young6ba8abe2017-11-09 10:37:04 -0700130 if (!layer_copy_tmp_debug_messengers(pCreateInfo->pNext, &instance_data->num_tmp_debug_messengers,
131 &instance_data->tmp_messenger_create_infos, &instance_data->tmp_debug_messengers)) {
132 if (instance_data->num_tmp_debug_messengers > 0) {
133 if (layer_enable_tmp_debug_messengers(instance_data->report_data, instance_data->num_tmp_debug_messengers,
134 instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers)) {
135 layer_free_tmp_debug_messengers(instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers);
136 instance_data->num_tmp_debug_messengers = 0;
137 }
138 }
139 }
140 if (!layer_copy_tmp_report_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_report_callbacks,
141 &instance_data->tmp_report_create_infos, &instance_data->tmp_report_callbacks)) {
142 if (instance_data->num_tmp_report_callbacks > 0) {
143 if (layer_enable_tmp_report_callbacks(instance_data->report_data, instance_data->num_tmp_report_callbacks,
144 instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks)) {
145 layer_free_tmp_report_callbacks(instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks);
146 instance_data->num_tmp_report_callbacks = 0;
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600147 }
148 }
149 }
150
151 initUniqueObjects(instance_data, pAllocator);
Mark Lobodzinskic0141472017-06-09 09:51:34 -0600152 InstanceExtensionWhitelist(pCreateInfo, *pInstance);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600153
154 // Disable and free tmp callbacks, no longer necessary
Mark Young6ba8abe2017-11-09 10:37:04 -0700155 if (instance_data->num_tmp_debug_messengers > 0) {
156 layer_disable_tmp_debug_messengers(instance_data->report_data, instance_data->num_tmp_debug_messengers,
157 instance_data->tmp_debug_messengers);
158 layer_free_tmp_debug_messengers(instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers);
159 instance_data->num_tmp_debug_messengers = 0;
160 }
161 if (instance_data->num_tmp_report_callbacks > 0) {
162 layer_disable_tmp_report_callbacks(instance_data->report_data, instance_data->num_tmp_report_callbacks,
163 instance_data->tmp_report_callbacks);
164 layer_free_tmp_report_callbacks(instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks);
165 instance_data->num_tmp_report_callbacks = 0;
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600166 }
167
168 return result;
169}
170
171VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
172 dispatch_key key = get_dispatch_key(instance);
Chris Forbes5279a8c2017-05-02 16:26:23 -0700173 instance_layer_data *instance_data = GetLayerDataPtr(key, instance_layer_data_map);
Chris Forbes44c05302017-05-02 16:42:55 -0700174 VkLayerInstanceDispatchTable *disp_table = &instance_data->dispatch_table;
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600175 disp_table->DestroyInstance(instance, pAllocator);
176
177 // Clean up logging callback, if any
Mark Young6ba8abe2017-11-09 10:37:04 -0700178 while (instance_data->logging_messenger.size() > 0) {
179 VkDebugUtilsMessengerEXT messenger = instance_data->logging_messenger.back();
180 layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
181 instance_data->logging_messenger.pop_back();
182 }
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600183 while (instance_data->logging_callback.size() > 0) {
184 VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
Mark Young6ba8abe2017-11-09 10:37:04 -0700185 layer_destroy_report_callback(instance_data->report_data, callback, pAllocator);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600186 instance_data->logging_callback.pop_back();
187 }
188
Mark Young6ba8abe2017-11-09 10:37:04 -0700189 layer_debug_utils_destroy_instance(instance_data->report_data);
Gabríel Arthúr Pétursson2c5e7502017-06-03 23:27:59 +0000190 FreeLayerDataPtr(key, instance_layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600191}
192
193VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
194 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Chris Forbes5279a8c2017-05-02 16:26:23 -0700195 instance_layer_data *my_instance_data = GetLayerDataPtr(get_dispatch_key(gpu), instance_layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600196 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
197
198 assert(chain_info->u.pLayerInfo);
199 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
200 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
201 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
202 if (fpCreateDevice == NULL) {
203 return VK_ERROR_INITIALIZATION_FAILED;
204 }
205
206 // Advance the link info for the next element on the chain
207 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
208
209 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
210 if (result != VK_SUCCESS) {
211 return result;
212 }
213
Tobin Ehlis8d6acde2017-02-08 07:40:40 -0700214 layer_data *my_device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
Mark Young6ba8abe2017-11-09 10:37:04 -0700215 my_device_data->report_data = layer_debug_utils_create_device(my_instance_data->report_data, *pDevice);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600216
217 // Setup layer's device dispatch table
Chris Forbes44c05302017-05-02 16:42:55 -0700218 layer_init_device_dispatch_table(*pDevice, &my_device_data->dispatch_table, fpGetDeviceProcAddr);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600219
Mark Lobodzinskic0141472017-06-09 09:51:34 -0600220 DeviceExtensionWhitelist(pCreateInfo, *pDevice);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600221
Mark Lobodzinskic0141472017-06-09 09:51:34 -0600222 // Set gpu for this device in order to get at any objects mapped at instance level
Chris Forbes7fcfde12017-05-02 16:54:24 -0700223 my_device_data->instance_data = my_instance_data;
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600224
225 return result;
226}
227
228VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
229 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis8d6acde2017-02-08 07:40:40 -0700230 layer_data *dev_data = GetLayerDataPtr(key, layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600231
Mark Young6ba8abe2017-11-09 10:37:04 -0700232 layer_debug_utils_destroy_device(device);
Chris Forbes44c05302017-05-02 16:42:55 -0700233 dev_data->dispatch_table.DestroyDevice(device, pAllocator);
Gabríel Arthúr Pétursson2c5e7502017-06-03 23:27:59 +0000234
235 FreeLayerDataPtr(key, layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600236}
237
238static const VkLayerProperties globalLayerProps = {"VK_LAYER_GOOGLE_unique_objects",
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700239 VK_LAYER_API_VERSION, // specVersion
240 1, // implementationVersion
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600241 "Google Validation Layer"};
242
Mark Young39389872017-01-19 21:10:49 -0700243/// Declare prototype for these functions
244VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName);
245
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600246VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
247 return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);
248}
249
250VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
251 VkLayerProperties *pProperties) {
252 return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);
253}
254
255VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
256 VkExtensionProperties *pProperties) {
257 if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))
258 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
259
260 return VK_ERROR_LAYER_NOT_PRESENT;
261}
262
263VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
264 uint32_t *pCount, VkExtensionProperties *pProperties) {
265 if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))
266 return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
267
268 assert(physicalDevice);
269
270 dispatch_key key = get_dispatch_key(physicalDevice);
Chris Forbes5279a8c2017-05-02 16:26:23 -0700271 instance_layer_data *instance_data = GetLayerDataPtr(key, instance_layer_data_map);
Chris Forbes44c05302017-05-02 16:42:55 -0700272 return instance_data->dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600273}
274
275VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
Mark Lobodzinski38686e92017-06-07 16:04:50 -0600276 const auto item = name_to_funcptr_map.find(funcName);
277 if (item != name_to_funcptr_map.end()) {
278 return reinterpret_cast<PFN_vkVoidFunction>(item->second);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600279 }
280
Mark Lobodzinski38686e92017-06-07 16:04:50 -0600281 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
282 const auto &table = device_data->dispatch_table;
283 if (!table.GetDeviceProcAddr) return nullptr;
284 return table.GetDeviceProcAddr(device, funcName);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600285}
286
287VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
Mark Lobodzinski38686e92017-06-07 16:04:50 -0600288 const auto item = name_to_funcptr_map.find(funcName);
289 if (item != name_to_funcptr_map.end()) {
290 return reinterpret_cast<PFN_vkVoidFunction>(item->second);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600291 }
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600292
Chris Forbes5279a8c2017-05-02 16:26:23 -0700293 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
Mark Lobodzinski38686e92017-06-07 16:04:50 -0600294 const auto &table = instance_data->dispatch_table;
295 if (!table.GetInstanceProcAddr) return nullptr;
296 return table.GetInstanceProcAddr(instance, funcName);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600297}
298
Mark Lobodzinski38686e92017-06-07 16:04:50 -0600299VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) {
Chris Forbes5279a8c2017-05-02 16:26:23 -0700300 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
Chris Forbes44c05302017-05-02 16:42:55 -0700301 VkLayerInstanceDispatchTable *disp_table = &instance_data->dispatch_table;
Mark Young39389872017-01-19 21:10:49 -0700302 if (disp_table->GetPhysicalDeviceProcAddr == NULL) {
303 return NULL;
304 }
305 return disp_table->GetPhysicalDeviceProcAddr(instance, funcName);
306}
307
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600308VKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
309 const VkComputePipelineCreateInfo *pCreateInfos,
310 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
Chris Forbes6956a312017-05-02 17:36:28 -0700311 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600312 safe_VkComputePipelineCreateInfo *local_pCreateInfos = NULL;
313 if (pCreateInfos) {
314 std::lock_guard<std::mutex> lock(global_lock);
315 local_pCreateInfos = new safe_VkComputePipelineCreateInfo[createInfoCount];
316 for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
317 local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
318 if (pCreateInfos[idx0].basePipelineHandle) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700319 local_pCreateInfos[idx0].basePipelineHandle = Unwrap(pCreateInfos[idx0].basePipelineHandle);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600320 }
321 if (pCreateInfos[idx0].layout) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700322 local_pCreateInfos[idx0].layout = Unwrap(pCreateInfos[idx0].layout);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600323 }
324 if (pCreateInfos[idx0].stage.module) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700325 local_pCreateInfos[idx0].stage.module = Unwrap(pCreateInfos[idx0].stage.module);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600326 }
327 }
328 }
329 if (pipelineCache) {
330 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700331 pipelineCache = Unwrap(pipelineCache);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600332 }
333
Dave Houltona9df0ce2018-02-07 10:51:23 -0700334 VkResult result = device_data->dispatch_table.CreateComputePipelines(device, pipelineCache, createInfoCount,
335 local_pCreateInfos->ptr(), pAllocator, pPipelines);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600336 delete[] local_pCreateInfos;
Maciej Jesionowski42200702016-11-23 10:44:34 +0100337 {
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600338 std::lock_guard<std::mutex> lock(global_lock);
339 for (uint32_t i = 0; i < createInfoCount; ++i) {
Maciej Jesionowski42200702016-11-23 10:44:34 +0100340 if (pPipelines[i] != VK_NULL_HANDLE) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700341 pPipelines[i] = WrapNew(pPipelines[i]);
Maciej Jesionowski42200702016-11-23 10:44:34 +0100342 }
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600343 }
344 }
345 return result;
346}
347
348VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
349 const VkGraphicsPipelineCreateInfo *pCreateInfos,
350 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
Chris Forbes6956a312017-05-02 17:36:28 -0700351 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
352 safe_VkGraphicsPipelineCreateInfo *local_pCreateInfos = nullptr;
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600353 if (pCreateInfos) {
354 local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount];
355 std::lock_guard<std::mutex> lock(global_lock);
356 for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
Petr Krause91f7a12017-12-14 20:57:36 +0100357 bool uses_color_attachment = false;
358 bool uses_depthstencil_attachment = false;
359 {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700360 const auto subpasses_uses_it = device_data->renderpasses_states.find(Unwrap(pCreateInfos[idx0].renderPass));
Petr Krause91f7a12017-12-14 20:57:36 +0100361 if (subpasses_uses_it != device_data->renderpasses_states.end()) {
362 const auto &subpasses_uses = subpasses_uses_it->second;
363 if (subpasses_uses.subpasses_using_color_attachment.count(pCreateInfos[idx0].subpass))
364 uses_color_attachment = true;
365 if (subpasses_uses.subpasses_using_depthstencil_attachment.count(pCreateInfos[idx0].subpass))
366 uses_depthstencil_attachment = true;
367 }
368 }
369
370 local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0], uses_color_attachment, uses_depthstencil_attachment);
371
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600372 if (pCreateInfos[idx0].basePipelineHandle) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700373 local_pCreateInfos[idx0].basePipelineHandle = Unwrap(pCreateInfos[idx0].basePipelineHandle);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600374 }
375 if (pCreateInfos[idx0].layout) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700376 local_pCreateInfos[idx0].layout = Unwrap(pCreateInfos[idx0].layout);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600377 }
378 if (pCreateInfos[idx0].pStages) {
379 for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
380 if (pCreateInfos[idx0].pStages[idx1].module) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700381 local_pCreateInfos[idx0].pStages[idx1].module = Unwrap(pCreateInfos[idx0].pStages[idx1].module);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600382 }
383 }
384 }
385 if (pCreateInfos[idx0].renderPass) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700386 local_pCreateInfos[idx0].renderPass = Unwrap(pCreateInfos[idx0].renderPass);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600387 }
388 }
389 }
390 if (pipelineCache) {
391 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700392 pipelineCache = Unwrap(pipelineCache);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600393 }
394
Dave Houltona9df0ce2018-02-07 10:51:23 -0700395 VkResult result = device_data->dispatch_table.CreateGraphicsPipelines(device, pipelineCache, createInfoCount,
396 local_pCreateInfos->ptr(), pAllocator, pPipelines);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600397 delete[] local_pCreateInfos;
Maciej Jesionowski42200702016-11-23 10:44:34 +0100398 {
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600399 std::lock_guard<std::mutex> lock(global_lock);
400 for (uint32_t i = 0; i < createInfoCount; ++i) {
Maciej Jesionowski42200702016-11-23 10:44:34 +0100401 if (pPipelines[i] != VK_NULL_HANDLE) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700402 pPipelines[i] = WrapNew(pPipelines[i]);
Maciej Jesionowski42200702016-11-23 10:44:34 +0100403 }
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600404 }
405 }
406 return result;
407}
408
Petr Krause91f7a12017-12-14 20:57:36 +0100409static void PostCallCreateRenderPass(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, VkRenderPass renderPass) {
410 auto &renderpass_state = dev_data->renderpasses_states[renderPass];
411
412 for (uint32_t subpass = 0; subpass < pCreateInfo->subpassCount; ++subpass) {
413 bool uses_color = false;
414 for (uint32_t i = 0; i < pCreateInfo->pSubpasses[subpass].colorAttachmentCount && !uses_color; ++i)
415 if (pCreateInfo->pSubpasses[subpass].pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true;
416
417 bool uses_depthstencil = false;
418 if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment)
419 if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
420 uses_depthstencil = true;
421
422 if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpass);
423 if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpass);
424 }
425}
426
427VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
428 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
429 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
430 VkResult result = dev_data->dispatch_table.CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
431 if (VK_SUCCESS == result) {
432 std::lock_guard<std::mutex> lock(global_lock);
433
434 PostCallCreateRenderPass(dev_data, pCreateInfo, *pRenderPass);
435
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700436 *pRenderPass = WrapNew(*pRenderPass);
Petr Krause91f7a12017-12-14 20:57:36 +0100437 }
438 return result;
439}
440
441static void PostCallDestroyRenderPass(layer_data *dev_data, VkRenderPass renderPass) {
442 dev_data->renderpasses_states.erase(renderPass);
443}
444
445VKAPI_ATTR void VKAPI_CALL DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
446 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
447 std::unique_lock<std::mutex> lock(global_lock);
448 uint64_t renderPass_id = reinterpret_cast<uint64_t &>(renderPass);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700449 renderPass = (VkRenderPass)unique_id_mapping[renderPass_id];
450 unique_id_mapping.erase(renderPass_id);
Petr Krause91f7a12017-12-14 20:57:36 +0100451 lock.unlock();
452 dev_data->dispatch_table.DestroyRenderPass(device, renderPass, pAllocator);
453
454 lock.lock();
455 PostCallDestroyRenderPass(dev_data, renderPass);
456}
457
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600458VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
459 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
Tobin Ehlis8d6acde2017-02-08 07:40:40 -0700460 layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600461 safe_VkSwapchainCreateInfoKHR *local_pCreateInfo = NULL;
462 if (pCreateInfo) {
463 std::lock_guard<std::mutex> lock(global_lock);
464 local_pCreateInfo = new safe_VkSwapchainCreateInfoKHR(pCreateInfo);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700465 local_pCreateInfo->oldSwapchain = Unwrap(pCreateInfo->oldSwapchain);
Chris Forbes6956a312017-05-02 17:36:28 -0700466 // Surface is instance-level object
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700467 local_pCreateInfo->surface = Unwrap(pCreateInfo->surface);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600468 }
469
Dave Houltona9df0ce2018-02-07 10:51:23 -0700470 VkResult result = my_map_data->dispatch_table.CreateSwapchainKHR(device, local_pCreateInfo->ptr(), pAllocator, pSwapchain);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000471 delete local_pCreateInfo;
472
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600473 if (VK_SUCCESS == result) {
474 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700475 *pSwapchain = WrapNew(*pSwapchain);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600476 }
477 return result;
478}
479
Dustin Graves9a6eb052017-03-28 14:18:54 -0600480VKAPI_ATTR VkResult VKAPI_CALL CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
481 const VkSwapchainCreateInfoKHR *pCreateInfos,
482 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains) {
483 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
484 safe_VkSwapchainCreateInfoKHR *local_pCreateInfos = NULL;
485 {
486 std::lock_guard<std::mutex> lock(global_lock);
487 if (pCreateInfos) {
Dustin Graves9a6eb052017-03-28 14:18:54 -0600488 local_pCreateInfos = new safe_VkSwapchainCreateInfoKHR[swapchainCount];
489 for (uint32_t i = 0; i < swapchainCount; ++i) {
490 local_pCreateInfos[i].initialize(&pCreateInfos[i]);
491 if (pCreateInfos[i].surface) {
Chris Forbes6956a312017-05-02 17:36:28 -0700492 // Surface is instance-level object
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700493 local_pCreateInfos[i].surface = Unwrap(pCreateInfos[i].surface);
Dustin Graves9a6eb052017-03-28 14:18:54 -0600494 }
495 if (pCreateInfos[i].oldSwapchain) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700496 local_pCreateInfos[i].oldSwapchain = Unwrap(pCreateInfos[i].oldSwapchain);
Dustin Graves9a6eb052017-03-28 14:18:54 -0600497 }
498 }
499 }
500 }
Dave Houltona9df0ce2018-02-07 10:51:23 -0700501 VkResult result = dev_data->dispatch_table.CreateSharedSwapchainsKHR(device, swapchainCount, local_pCreateInfos->ptr(),
502 pAllocator, pSwapchains);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000503 delete[] local_pCreateInfos;
Dustin Graves9a6eb052017-03-28 14:18:54 -0600504 if (VK_SUCCESS == result) {
505 std::lock_guard<std::mutex> lock(global_lock);
506 for (uint32_t i = 0; i < swapchainCount; i++) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700507 pSwapchains[i] = WrapNew(pSwapchains[i]);
Dustin Graves9a6eb052017-03-28 14:18:54 -0600508 }
509 }
510 return result;
511}
512
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600513VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
514 VkImage *pSwapchainImages) {
Tobin Ehlis8d6acde2017-02-08 07:40:40 -0700515 layer_data *my_device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski2eb39bc2018-02-16 11:24:21 -0700516 VkSwapchainKHR wrapped_swapchain_handle = swapchain;
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600517 if (VK_NULL_HANDLE != swapchain) {
518 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700519 swapchain = Unwrap(swapchain);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600520 }
521 VkResult result =
Chris Forbes44c05302017-05-02 16:42:55 -0700522 my_device_data->dispatch_table.GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
Mark Lobodzinski2eb39bc2018-02-16 11:24:21 -0700523 if ((VK_SUCCESS == result) || (VK_INCOMPLETE == result)) {
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600524 if ((*pSwapchainImageCount > 0) && pSwapchainImages) {
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600525 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski2eb39bc2018-02-16 11:24:21 -0700526 auto &wrapped_swapchain_image_handles = my_device_data->swapchain_wrapped_image_handle_map[wrapped_swapchain_handle];
527 for (uint32_t i = static_cast<uint32_t>(wrapped_swapchain_image_handles.size()); i < *pSwapchainImageCount; i++) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700528 wrapped_swapchain_image_handles.emplace_back(WrapNew(pSwapchainImages[i]));
Mark Lobodzinski2eb39bc2018-02-16 11:24:21 -0700529 }
530 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
531 pSwapchainImages[i] = wrapped_swapchain_image_handles[i];
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600532 }
533 }
534 }
535 return result;
536}
537
Mark Lobodzinski1ce83f42018-02-16 09:58:07 -0700538VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
539 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
540 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinski2eb39bc2018-02-16 11:24:21 -0700541
542 auto &image_array = dev_data->swapchain_wrapped_image_handle_map[swapchain];
543 for (auto &image_handle : image_array) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700544 unique_id_mapping.erase(HandleToUint64(image_handle));
Mark Lobodzinski2eb39bc2018-02-16 11:24:21 -0700545 }
546 dev_data->swapchain_wrapped_image_handle_map.erase(swapchain);
547
548 uint64_t swapchain_id = HandleToUint64(swapchain);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700549 swapchain = (VkSwapchainKHR)unique_id_mapping[swapchain_id];
550 unique_id_mapping.erase(swapchain_id);
Mark Lobodzinski1ce83f42018-02-16 09:58:07 -0700551 lock.unlock();
552 dev_data->dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator);
553}
554
Chris Forbes0f507f22017-04-16 13:13:17 +1200555VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
556 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map);
557 safe_VkPresentInfoKHR *local_pPresentInfo = NULL;
558 {
559 std::lock_guard<std::mutex> lock(global_lock);
560 if (pPresentInfo) {
561 local_pPresentInfo = new safe_VkPresentInfoKHR(pPresentInfo);
562 if (local_pPresentInfo->pWaitSemaphores) {
563 for (uint32_t index1 = 0; index1 < local_pPresentInfo->waitSemaphoreCount; ++index1) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700564 local_pPresentInfo->pWaitSemaphores[index1] = Unwrap(pPresentInfo->pWaitSemaphores[index1]);
Chris Forbes0f507f22017-04-16 13:13:17 +1200565 }
566 }
567 if (local_pPresentInfo->pSwapchains) {
568 for (uint32_t index1 = 0; index1 < local_pPresentInfo->swapchainCount; ++index1) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700569 local_pPresentInfo->pSwapchains[index1] = Unwrap(pPresentInfo->pSwapchains[index1]);
Chris Forbes0f507f22017-04-16 13:13:17 +1200570 }
571 }
572 }
573 }
Chris Forbes6956a312017-05-02 17:36:28 -0700574 VkResult result = dev_data->dispatch_table.QueuePresentKHR(queue, local_pPresentInfo->ptr());
Chris Forbes0f507f22017-04-16 13:13:17 +1200575
576 // pResults is an output array embedded in a structure. The code generator neglects to copy back from the safe_* version,
577 // so handle it as a special case here:
578 if (pPresentInfo && pPresentInfo->pResults) {
579 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
580 pPresentInfo->pResults[i] = local_pPresentInfo->pResults[i];
581 }
582 }
583
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000584 delete local_pPresentInfo;
Chris Forbes0f507f22017-04-16 13:13:17 +1200585 return result;
586}
587
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600588// This is the core version of this routine. The extension version is below.
589VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplate(VkDevice device,
590 const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo,
591 const VkAllocationCallbacks *pAllocator,
592 VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate) {
593 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
594 safe_VkDescriptorUpdateTemplateCreateInfo *local_create_info = NULL;
595 {
596 std::lock_guard<std::mutex> lock(global_lock);
597 if (pCreateInfo) {
598 local_create_info = new safe_VkDescriptorUpdateTemplateCreateInfo(pCreateInfo);
599 if (pCreateInfo->descriptorSetLayout) {
Mark Lobodzinski4bed0252018-02-28 14:04:56 -0700600 local_create_info->descriptorSetLayout = Unwrap(pCreateInfo->descriptorSetLayout);
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600601 }
602 if (pCreateInfo->pipelineLayout) {
Mark Lobodzinski4bed0252018-02-28 14:04:56 -0700603 local_create_info->pipelineLayout = Unwrap(pCreateInfo->pipelineLayout);
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600604 }
605 }
606 }
607 VkResult result = dev_data->dispatch_table.CreateDescriptorUpdateTemplate(device, local_create_info->ptr(), pAllocator,
608 pDescriptorUpdateTemplate);
609 if (VK_SUCCESS == result) {
610 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski4bed0252018-02-28 14:04:56 -0700611 *pDescriptorUpdateTemplate = WrapNew(*pDescriptorUpdateTemplate);
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600612
613 // Shadow template createInfo for later updates
614 std::unique_ptr<TEMPLATE_STATE> template_state(new TEMPLATE_STATE(*pDescriptorUpdateTemplate, local_create_info));
615 dev_data->desc_template_map[(uint64_t)*pDescriptorUpdateTemplate] = std::move(template_state);
616 }
617 return result;
618}
619
620// This is the extension version of this routine. The core version is above.
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700621VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device,
622 const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo,
623 const VkAllocationCallbacks *pAllocator,
624 VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate) {
625 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskief4da502017-09-28 15:18:18 -0600626 safe_VkDescriptorUpdateTemplateCreateInfo *local_create_info = NULL;
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700627 {
628 std::lock_guard<std::mutex> lock(global_lock);
629 if (pCreateInfo) {
Mark Lobodzinskief4da502017-09-28 15:18:18 -0600630 local_create_info = new safe_VkDescriptorUpdateTemplateCreateInfo(pCreateInfo);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700631 if (pCreateInfo->descriptorSetLayout) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700632 local_create_info->descriptorSetLayout = Unwrap(pCreateInfo->descriptorSetLayout);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700633 }
634 if (pCreateInfo->pipelineLayout) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700635 local_create_info->pipelineLayout = Unwrap(pCreateInfo->pipelineLayout);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700636 }
637 }
638 }
Dave Houltona9df0ce2018-02-07 10:51:23 -0700639 VkResult result = dev_data->dispatch_table.CreateDescriptorUpdateTemplateKHR(device, local_create_info->ptr(), pAllocator,
640 pDescriptorUpdateTemplate);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700641 if (VK_SUCCESS == result) {
642 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700643 *pDescriptorUpdateTemplate = WrapNew(*pDescriptorUpdateTemplate);
Mark Lobodzinski4f3ce672017-03-03 10:28:21 -0700644
645 // Shadow template createInfo for later updates
Mark Lobodzinski94d9e8c2017-03-06 16:18:19 -0700646 std::unique_ptr<TEMPLATE_STATE> template_state(new TEMPLATE_STATE(*pDescriptorUpdateTemplate, local_create_info));
Chris Forbes6956a312017-05-02 17:36:28 -0700647 dev_data->desc_template_map[(uint64_t)*pDescriptorUpdateTemplate] = std::move(template_state);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700648 }
649 return result;
650}
651
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600652// This is the core version of this routine. The extension version is below.
653VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
654 const VkAllocationCallbacks *pAllocator) {
655 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
656 std::unique_lock<std::mutex> lock(global_lock);
657 uint64_t descriptor_update_template_id = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
658 dev_data->desc_template_map.erase(descriptor_update_template_id);
Mark Lobodzinski4bed0252018-02-28 14:04:56 -0700659 descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)unique_id_mapping[descriptor_update_template_id];
660 unique_id_mapping.erase(descriptor_update_template_id);
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600661 lock.unlock();
662 dev_data->dispatch_table.DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
663}
664
665// This is the extension version of this routine. The core version is above.
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700666VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device,
667 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
668 const VkAllocationCallbacks *pAllocator) {
669 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
670 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinski94d9e8c2017-03-06 16:18:19 -0700671 uint64_t descriptor_update_template_id = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
672 dev_data->desc_template_map.erase(descriptor_update_template_id);
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600673 descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)unique_id_mapping[descriptor_update_template_id];
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700674 unique_id_mapping.erase(descriptor_update_template_id);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700675 lock.unlock();
Chris Forbes44c05302017-05-02 16:42:55 -0700676 dev_data->dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700677}
678
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700679void *BuildUnwrappedUpdateTemplateBuffer(layer_data *dev_data, uint64_t descriptorUpdateTemplate, const void *pData) {
680 auto const template_map_entry = dev_data->desc_template_map.find(descriptorUpdateTemplate);
681 if (template_map_entry == dev_data->desc_template_map.end()) {
682 assert(0);
683 }
684 auto const &create_info = template_map_entry->second->create_info;
685 size_t allocation_size = 0;
Mark Lobodzinski2d9de652017-04-24 08:58:52 -0600686 std::vector<std::tuple<size_t, VulkanObjectType, void *>> template_entries;
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700687
688 for (uint32_t i = 0; i < create_info.descriptorUpdateEntryCount; i++) {
689 for (uint32_t j = 0; j < create_info.pDescriptorUpdateEntries[i].descriptorCount; j++) {
690 size_t offset = create_info.pDescriptorUpdateEntries[i].offset + j * create_info.pDescriptorUpdateEntries[i].stride;
691 char *update_entry = (char *)(pData) + offset;
692
693 switch (create_info.pDescriptorUpdateEntries[i].descriptorType) {
694 case VK_DESCRIPTOR_TYPE_SAMPLER:
695 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
696 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
697 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
698 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
699 auto image_entry = reinterpret_cast<VkDescriptorImageInfo *>(update_entry);
700 allocation_size = std::max(allocation_size, offset + sizeof(VkDescriptorImageInfo));
701
702 VkDescriptorImageInfo *wrapped_entry = new VkDescriptorImageInfo(*image_entry);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700703 wrapped_entry->sampler = Unwrap(image_entry->sampler);
704 wrapped_entry->imageView = Unwrap(image_entry->imageView);
Mark Lobodzinski2d9de652017-04-24 08:58:52 -0600705 template_entries.emplace_back(offset, kVulkanObjectTypeImage, reinterpret_cast<void *>(wrapped_entry));
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700706 } break;
707
708 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
709 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
710 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
711 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
712 auto buffer_entry = reinterpret_cast<VkDescriptorBufferInfo *>(update_entry);
713 allocation_size = std::max(allocation_size, offset + sizeof(VkDescriptorBufferInfo));
714
715 VkDescriptorBufferInfo *wrapped_entry = new VkDescriptorBufferInfo(*buffer_entry);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700716 wrapped_entry->buffer = Unwrap(buffer_entry->buffer);
Mark Lobodzinski2d9de652017-04-24 08:58:52 -0600717 template_entries.emplace_back(offset, kVulkanObjectTypeBuffer, reinterpret_cast<void *>(wrapped_entry));
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700718 } break;
719
720 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
721 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
Chris Forbes6956a312017-05-02 17:36:28 -0700722 auto buffer_view_handle = reinterpret_cast<VkBufferView *>(update_entry);
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700723 allocation_size = std::max(allocation_size, offset + sizeof(VkBufferView));
724
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700725 VkBufferView wrapped_entry = Unwrap(*buffer_view_handle);
Mark Lobodzinski2d9de652017-04-24 08:58:52 -0600726 template_entries.emplace_back(offset, kVulkanObjectTypeBufferView, reinterpret_cast<void *>(wrapped_entry));
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700727 } break;
728 default:
729 assert(0);
730 break;
731 }
732 }
733 }
734 // Allocate required buffer size and populate with source/unwrapped data
735 void *unwrapped_data = malloc(allocation_size);
736 for (auto &this_entry : template_entries) {
Mark Lobodzinski2d9de652017-04-24 08:58:52 -0600737 VulkanObjectType type = std::get<1>(this_entry);
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700738 void *destination = (char *)unwrapped_data + std::get<0>(this_entry);
739 void *source = (char *)std::get<2>(this_entry);
740
741 switch (type) {
Mark Lobodzinski2d9de652017-04-24 08:58:52 -0600742 case kVulkanObjectTypeImage:
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700743 *(reinterpret_cast<VkDescriptorImageInfo *>(destination)) = *(reinterpret_cast<VkDescriptorImageInfo *>(source));
744 delete reinterpret_cast<VkDescriptorImageInfo *>(source);
745 break;
Mark Lobodzinski2d9de652017-04-24 08:58:52 -0600746 case kVulkanObjectTypeBuffer:
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700747 *(reinterpret_cast<VkDescriptorBufferInfo *>(destination)) = *(reinterpret_cast<VkDescriptorBufferInfo *>(source));
748 delete reinterpret_cast<VkDescriptorBufferInfo *>(source);
749 break;
Mark Lobodzinski2d9de652017-04-24 08:58:52 -0600750 case kVulkanObjectTypeBufferView:
Mark Lobodzinskid5197d02017-03-15 13:13:49 -0600751 *(reinterpret_cast<VkBufferView *>(destination)) = reinterpret_cast<VkBufferView>(source);
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700752 break;
753 default:
754 assert(0);
755 break;
756 }
757 }
758 return (void *)unwrapped_data;
759}
760
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600761// This is the core version of this routine. The extension version is below.
762VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
763 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
764 const void *pData) {
765 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
766 uint64_t template_handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
767 {
768 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski4bed0252018-02-28 14:04:56 -0700769 descriptorSet = Unwrap(descriptorSet);
770 descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)unique_id_mapping[template_handle];
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600771 }
772 void *unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(dev_data, template_handle, pData);
773 dev_data->dispatch_table.UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, unwrapped_buffer);
774 free(unwrapped_buffer);
775}
776
777// This is the extension version of this routine. The core version is above.
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700778VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
779 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
780 const void *pData) {
781 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski94d9e8c2017-03-06 16:18:19 -0700782 uint64_t template_handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
Mark Lobodzinskic8a0c9b2017-11-13 09:42:58 -0700783 void *unwrapped_buffer = nullptr;
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700784 {
785 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700786 descriptorSet = Unwrap(descriptorSet);
Mark Lobodzinskiab9a8752017-10-25 16:56:42 -0600787 descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)unique_id_mapping[template_handle];
Mark Lobodzinskic8a0c9b2017-11-13 09:42:58 -0700788 unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(dev_data, template_handle, pData);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700789 }
Dave Houltona9df0ce2018-02-07 10:51:23 -0700790 dev_data->dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, unwrapped_buffer);
Mark Lobodzinskib523f7c2017-03-06 09:00:21 -0700791 free(unwrapped_buffer);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700792}
793
794VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
795 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
796 VkPipelineLayout layout, uint32_t set, const void *pData) {
797 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski1c471262017-03-28 16:22:56 -0600798 uint64_t template_handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
Mark Lobodzinskic8a0c9b2017-11-13 09:42:58 -0700799 void *unwrapped_buffer = nullptr;
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700800 {
801 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700802 descriptorUpdateTemplate = Unwrap(descriptorUpdateTemplate);
803 layout = Unwrap(layout);
Mark Lobodzinskic8a0c9b2017-11-13 09:42:58 -0700804 unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(dev_data, template_handle, pData);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700805 }
Chris Forbes44c05302017-05-02 16:42:55 -0700806 dev_data->dispatch_table.CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set,
Dave Houltona9df0ce2018-02-07 10:51:23 -0700807 unwrapped_buffer);
Mark Lobodzinski1c471262017-03-28 16:22:56 -0600808 free(unwrapped_buffer);
Mark Lobodzinski71703a52017-03-03 08:40:16 -0700809}
810
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600811VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
812 VkDisplayPropertiesKHR *pProperties) {
Chris Forbes5279a8c2017-05-02 16:26:23 -0700813 instance_layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600814
Dave Houltona9df0ce2018-02-07 10:51:23 -0700815 VkResult result =
816 my_map_data->dispatch_table.GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
Chris Forbesf1e49bf2017-05-02 17:36:57 -0700817 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
818 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600819 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700820 pProperties[idx0].display = WrapNew(pProperties[idx0].display);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600821 }
822 }
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600823 return result;
824}
825
Mike Schuchardt3b093d72018-06-06 11:58:06 -0600826VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
827 VkDisplayProperties2KHR *pProperties) {
828 instance_layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
829
830 VkResult result =
831 my_map_data->dispatch_table.GetPhysicalDeviceDisplayProperties2KHR(physicalDevice, pPropertyCount, pProperties);
832 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
833 std::lock_guard<std::mutex> lock(global_lock);
834 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
835 pProperties[idx0].displayProperties.display = WrapNew(pProperties[idx0].displayProperties.display);
836 }
837 }
838 return result;
839}
840
841VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
842 VkDisplayPlanePropertiesKHR *pProperties) {
843 instance_layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
844
845 VkResult result =
846 my_map_data->dispatch_table.GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
847 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
848 std::lock_guard<std::mutex> lock(global_lock);
849 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
Petr Kraus49ce0ec2018-06-07 01:16:09 +0200850 VkDisplayKHR &opt_display = pProperties[idx0].currentDisplay;
851 if (opt_display) opt_display = WrapNew(opt_display);
Mike Schuchardt3b093d72018-06-06 11:58:06 -0600852 }
853 }
854 return result;
855}
856
857VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
858 uint32_t *pPropertyCount,
859 VkDisplayPlaneProperties2KHR *pProperties) {
860 instance_layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
861
862 VkResult result =
863 my_map_data->dispatch_table.GetPhysicalDeviceDisplayPlaneProperties2KHR(physicalDevice, pPropertyCount, pProperties);
864 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
865 std::lock_guard<std::mutex> lock(global_lock);
866 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
Petr Kraus49ce0ec2018-06-07 01:16:09 +0200867 VkDisplayKHR &opt_display = pProperties[idx0].displayPlaneProperties.currentDisplay;
868 if (opt_display) opt_display = WrapNew(opt_display);
Mike Schuchardt3b093d72018-06-06 11:58:06 -0600869 }
870 }
871 return result;
872}
873
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600874VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
875 uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
Chris Forbes5279a8c2017-05-02 16:26:23 -0700876 instance_layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
Dave Houltona9df0ce2018-02-07 10:51:23 -0700877 VkResult result =
878 my_map_data->dispatch_table.GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
Petr Kraus49ce0ec2018-06-07 01:16:09 +0200879 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pDisplays) {
880 std::lock_guard<std::mutex> lock(global_lock);
881 for (uint32_t i = 0; i < *pDisplayCount; ++i) {
882 // TODO: this looks like it really wants a /reverse/ mapping. What's going on here?
883 auto it = unique_id_mapping.find(reinterpret_cast<const uint64_t &>(pDisplays[i]));
884 assert(it != unique_id_mapping.end());
885 pDisplays[i] = reinterpret_cast<VkDisplayKHR &>(it->second);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600886 }
887 }
888 return result;
889}
890
891VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
892 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
Chris Forbes5279a8c2017-05-02 16:26:23 -0700893 instance_layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600894 {
895 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700896 display = Unwrap(display);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600897 }
898
Dave Houltona9df0ce2018-02-07 10:51:23 -0700899 VkResult result = my_map_data->dispatch_table.GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
Petr Kraus49ce0ec2018-06-07 01:16:09 +0200900 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
Chris Forbesef35afd2017-05-02 17:45:45 -0700901 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600902 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700903 pProperties[idx0].displayMode = WrapNew(pProperties[idx0].displayMode);
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600904 }
905 }
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -0600906 return result;
907}
Norbert Nopper1dec9a52016-11-25 07:55:13 +0100908
Mike Schuchardt3b093d72018-06-06 11:58:06 -0600909VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
910 uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties) {
911 instance_layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
912 {
913 std::lock_guard<std::mutex> lock(global_lock);
914 display = Unwrap(display);
915 }
916
917 VkResult result =
918 my_map_data->dispatch_table.GetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount, pProperties);
Petr Kraus49ce0ec2018-06-07 01:16:09 +0200919 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
Mike Schuchardt3b093d72018-06-06 11:58:06 -0600920 std::lock_guard<std::mutex> lock(global_lock);
921 for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
922 pProperties[idx0].displayModeProperties.displayMode = WrapNew(pProperties[idx0].displayModeProperties.displayMode);
923 }
924 }
925 return result;
926}
927
Mark Lobodzinskie4f2c5f2017-07-17 14:26:47 -0600928VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT *pTagInfo) {
Mark Lobodzinskia096c122017-03-16 11:54:35 -0600929 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000930 safe_VkDebugMarkerObjectTagInfoEXT local_tag_info(pTagInfo);
Mark Lobodzinskia096c122017-03-16 11:54:35 -0600931 {
932 std::lock_guard<std::mutex> lock(global_lock);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000933 auto it = unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_tag_info.object));
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700934 if (it != unique_id_mapping.end()) {
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000935 local_tag_info.object = it->second;
Mark Lobodzinskia096c122017-03-16 11:54:35 -0600936 }
937 }
Chris Forbes44c05302017-05-02 16:42:55 -0700938 VkResult result = device_data->dispatch_table.DebugMarkerSetObjectTagEXT(
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000939 device, reinterpret_cast<VkDebugMarkerObjectTagInfoEXT *>(&local_tag_info));
Mark Lobodzinskia096c122017-03-16 11:54:35 -0600940 return result;
941}
942
Mark Lobodzinskie4f2c5f2017-07-17 14:26:47 -0600943VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
Mark Lobodzinskia096c122017-03-16 11:54:35 -0600944 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000945 safe_VkDebugMarkerObjectNameInfoEXT local_name_info(pNameInfo);
Mark Lobodzinskia096c122017-03-16 11:54:35 -0600946 {
947 std::lock_guard<std::mutex> lock(global_lock);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000948 auto it = unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_name_info.object));
Mark Lobodzinskic7eda922018-02-28 13:38:45 -0700949 if (it != unique_id_mapping.end()) {
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000950 local_name_info.object = it->second;
Mark Lobodzinskia096c122017-03-16 11:54:35 -0600951 }
952 }
Chris Forbes44c05302017-05-02 16:42:55 -0700953 VkResult result = device_data->dispatch_table.DebugMarkerSetObjectNameEXT(
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000954 device, reinterpret_cast<VkDebugMarkerObjectNameInfoEXT *>(&local_name_info));
Mark Lobodzinskia096c122017-03-16 11:54:35 -0600955 return result;
956}
957
Mark Young6ba8abe2017-11-09 10:37:04 -0700958// VK_EXT_debug_utils
959VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) {
960 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000961 safe_VkDebugUtilsObjectTagInfoEXT local_tag_info(pTagInfo);
Mark Young6ba8abe2017-11-09 10:37:04 -0700962 {
963 std::lock_guard<std::mutex> lock(global_lock);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000964 auto it = unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_tag_info.objectHandle));
Mark Lobodzinski4bed0252018-02-28 14:04:56 -0700965 if (it != unique_id_mapping.end()) {
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000966 local_tag_info.objectHandle = it->second;
Mark Young6ba8abe2017-11-09 10:37:04 -0700967 }
968 }
969 VkResult result = device_data->dispatch_table.SetDebugUtilsObjectTagEXT(
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000970 device, reinterpret_cast<const VkDebugUtilsObjectTagInfoEXT *>(&local_tag_info));
Mark Young6ba8abe2017-11-09 10:37:04 -0700971 return result;
972}
973
974VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
975 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000976 safe_VkDebugUtilsObjectNameInfoEXT local_name_info(pNameInfo);
Mark Young6ba8abe2017-11-09 10:37:04 -0700977 {
978 std::lock_guard<std::mutex> lock(global_lock);
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000979 auto it = unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_name_info.objectHandle));
Mark Lobodzinski4bed0252018-02-28 14:04:56 -0700980 if (it != unique_id_mapping.end()) {
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000981 local_name_info.objectHandle = it->second;
Mark Young6ba8abe2017-11-09 10:37:04 -0700982 }
983 }
984 VkResult result = device_data->dispatch_table.SetDebugUtilsObjectNameEXT(
Gabríel Arthúr Pétursson06c5f0d2018-03-20 21:37:56 +0000985 device, reinterpret_cast<const VkDebugUtilsObjectNameInfoEXT *>(&local_name_info));
Mark Young6ba8abe2017-11-09 10:37:04 -0700986 return result;
987}
988
Tobin Ehlis7cbe99b2018-06-21 14:22:01 -0600989// VK_EXT_debug_utils commands
990VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(VkInstance instance,
991 const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
992 const VkAllocationCallbacks *pAllocator,
993 VkDebugUtilsMessengerEXT *pMessenger) {
994 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
995 VkResult result = instance_data->dispatch_table.CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
996
997 if (VK_SUCCESS == result) {
998 result = layer_create_messenger_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMessenger);
999 }
1000 return result;
1001}
1002
1003VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
1004 const VkAllocationCallbacks *pAllocator) {
1005 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
1006 instance_data->dispatch_table.DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
1007 layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
1008}
1009
1010VKAPI_ATTR void VKAPI_CALL SubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
1011 VkDebugUtilsMessageTypeFlagsEXT messageTypes,
1012 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
1013 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
1014 instance_data->dispatch_table.SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
1015}
1016
1017// VK_EXT_debug_report commands
1018VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
1019 const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
1020 const VkAllocationCallbacks *pAllocator,
1021 VkDebugReportCallbackEXT *pMsgCallback) {
1022 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
1023 VkResult res = instance_data->dispatch_table.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
1024 if (VK_SUCCESS == res) {
1025 lock_guard_t lock(global_lock);
1026 res = layer_create_report_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
1027 }
1028 return res;
1029}
1030
1031VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
1032 const VkAllocationCallbacks *pAllocator) {
1033 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
1034 instance_data->dispatch_table.DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
1035 lock_guard_t lock(global_lock);
1036 layer_destroy_report_callback(instance_data->report_data, msgCallback, pAllocator);
1037}
1038
1039VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
1040 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
1041 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
1042 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
1043 instance_data->dispatch_table.DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
1044}
1045
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07001046} // namespace unique_objects
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -06001047
Tobin Ehlis7cbe99b2018-06-21 14:22:01 -06001048VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(VkInstance instance,
1049 const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
1050 const VkAllocationCallbacks *pAllocator,
1051 VkDebugUtilsMessengerEXT *pMessenger) {
1052 return unique_objects::CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
1053}
1054
1055VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
1056 const VkAllocationCallbacks *pAllocator) {
1057 unique_objects::DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
1058}
1059
1060VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
1061 VkDebugUtilsMessageTypeFlagsEXT messageTypes,
1062 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
1063 unique_objects::SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
1064}
1065
1066VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instance,
1067 const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
1068 const VkAllocationCallbacks *pAllocator,
1069 VkDebugReportCallbackEXT *pMsgCallback) {
1070 return unique_objects::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
1071}
1072
1073VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
1074 const VkAllocationCallbacks *pAllocator) {
1075 unique_objects::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
1076}
1077
1078VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
1079 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
1080 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
1081 unique_objects::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
1082}
1083
Mark Lobodzinskidc3bd852016-09-06 16:12:23 -06001084VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
1085 VkExtensionProperties *pProperties) {
1086 return unique_objects::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
1087}
1088
1089VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
1090 VkLayerProperties *pProperties) {
1091 return unique_objects::EnumerateInstanceLayerProperties(pCount, pProperties);
1092}
1093
1094VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
1095 VkLayerProperties *pProperties) {
1096 assert(physicalDevice == VK_NULL_HANDLE);
1097 return unique_objects::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
1098}
1099
1100VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
1101 return unique_objects::GetDeviceProcAddr(dev, funcName);
1102}
1103
1104VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
1105 return unique_objects::GetInstanceProcAddr(instance, funcName);
1106}
1107
1108VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
1109 const char *pLayerName, uint32_t *pCount,
1110 VkExtensionProperties *pProperties) {
1111 assert(physicalDevice == VK_NULL_HANDLE);
1112 return unique_objects::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
1113}
Mark Young39389872017-01-19 21:10:49 -07001114
Mark Lobodzinski729a8d32017-01-26 12:16:30 -07001115VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance,
1116 const char *funcName) {
Mark Young39389872017-01-19 21:10:49 -07001117 return unique_objects::GetPhysicalDeviceProcAddr(instance, funcName);
1118}
1119
1120VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct) {
1121 assert(pVersionStruct != NULL);
1122 assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT);
1123
1124 // Fill in the function pointers if our version is at least capable of having the structure contain them.
1125 if (pVersionStruct->loaderLayerInterfaceVersion >= 2) {
1126 pVersionStruct->pfnGetInstanceProcAddr = vkGetInstanceProcAddr;
1127 pVersionStruct->pfnGetDeviceProcAddr = vkGetDeviceProcAddr;
1128 pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr;
1129 }
1130
1131 if (pVersionStruct->loaderLayerInterfaceVersion < CURRENT_LOADER_LAYER_INTERFACE_VERSION) {
1132 unique_objects::loader_layer_if_version = pVersionStruct->loaderLayerInterfaceVersion;
1133 } else if (pVersionStruct->loaderLayerInterfaceVersion > CURRENT_LOADER_LAYER_INTERFACE_VERSION) {
1134 pVersionStruct->loaderLayerInterfaceVersion = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
1135 }
1136
1137 return VK_SUCCESS;
1138}