blob: 9d8f0333cc926c76df3136d22170315577091102 [file] [log] [blame]
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
4 * Copyright (C) 2015-2016 Google Inc.
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06005 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials
11 * are furnished to do so, subject to the following conditions:
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060012 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070013 * The above copyright notice(s) and this permission notice shall be included
14 * in all copies or substantial portions of the Materials.
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060015 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070016 * The Materials are Confidential Information as defined by the Khronos
17 * Membership Agreement until designated non-confidential by Khronos, at which
18 * point this condition clause shall be removed.
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060019 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070020 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060021 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070022 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 *
24 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
27 * USE OR OTHER DEALINGS IN THE MATERIALS
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060028 *
29 * Author: Mark Lobodzinski <mark@lunarg.com>
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070030 * Author: Mike Stroyan <mike@LunarG.com>
31 * Author: Tobin Ehlis <tobin@lunarg.com>
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060032 */
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unordered_map>
38#include <memory>
39
40#include "vk_loader_platform.h"
41#include "vk_dispatch_table_helper.h"
42#include "vk_struct_string_helper_cpp.h"
43#if defined(__GNUC__)
44#pragma GCC diagnostic ignored "-Wwrite-strings"
45#endif
46#if defined(__GNUC__)
47#pragma GCC diagnostic warning "-Wwrite-strings"
48#endif
49#include "vk_struct_size_helper.h"
50#include "device_limits.h"
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -070051#include "vulkan/vk_layer.h"
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060052#include "vk_layer_config.h"
Michael Lentine03107b42015-12-11 10:49:51 -080053#include "vulkan/vk_debug_marker_layer.h"
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060054#include "vk_layer_table.h"
55#include "vk_layer_debug_marker_table.h"
56#include "vk_layer_data.h"
57#include "vk_layer_logging.h"
58#include "vk_layer_extension_utils.h"
Mark Lobodzinski6f2274e2015-09-22 09:33:21 -060059#include "vk_layer_utils.h"
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060060
Tobin Ehlis1cb7f572015-10-06 09:09:24 -060061struct devExts {
62 bool debug_marker_enabled;
63};
Tobin Ehlis9da65002015-09-24 15:25:16 -060064
65// This struct will be stored in a map hashed by the dispatchable object
Cody Northrop55443ef2015-09-28 15:09:32 -060066struct layer_data {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070067 debug_report_data *report_data;
68 std::vector<VkDebugReportCallbackEXT> logging_callback;
69 VkLayerDispatchTable *device_dispatch_table;
70 VkLayerInstanceDispatchTable *instance_dispatch_table;
71 devExts device_extensions;
Tobin Ehlis9da65002015-09-24 15:25:16 -060072 // Track state of each instance
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070073 unique_ptr<INSTANCE_STATE> instanceState;
74 unique_ptr<PHYSICAL_DEVICE_STATE> physicalDeviceState;
75 VkPhysicalDeviceFeatures actualPhysicalDeviceFeatures;
76 VkPhysicalDeviceFeatures requestedPhysicalDeviceFeatures;
Mark Lobodzinski941aea92016-01-13 10:23:15 -070077 unordered_map<VkDevice, VkPhysicalDeviceProperties> physDevPropertyMap;
78
Tobin Ehlis1cb7f572015-10-06 09:09:24 -060079 // Track physical device per logical device
80 VkPhysicalDevice physicalDevice;
Tobin Ehlis9da65002015-09-24 15:25:16 -060081 // Vector indices correspond to queueFamilyIndex
82 vector<unique_ptr<VkQueueFamilyProperties>> queueFamilyProperties;
Cody Northrop55443ef2015-09-28 15:09:32 -060083
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070084 layer_data()
85 : report_data(nullptr), device_dispatch_table(nullptr),
86 instance_dispatch_table(nullptr), device_extensions(),
87 instanceState(nullptr), physicalDeviceState(nullptr),
88 actualPhysicalDeviceFeatures(), requestedPhysicalDeviceFeatures(),
89 physicalDevice(){};
Cody Northrop55443ef2015-09-28 15:09:32 -060090};
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060091
Tobin Ehlis1cb7f572015-10-06 09:09:24 -060092static unordered_map<void *, layer_data *> layer_data_map;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060093
94static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
95
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070096// TODO : This can be much smarter, using separate locks for separate global
97// data
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060098static int globalLockInitialized = 0;
99static loader_platform_thread_mutex globalLock;
100
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700101template layer_data *
102get_my_data_ptr<layer_data>(void *data_key,
103 std::unordered_map<void *, layer_data *> &data_map);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600104
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700105static void init_device_limits(layer_data *my_data,
106 const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600107 uint32_t report_flags = 0;
108 uint32_t debug_action = 0;
109 FILE *log_output = NULL;
110 const char *option_str;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700111 VkDebugReportCallbackEXT callback;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600112 // initialize DeviceLimits options
113 report_flags = getLayerOptionFlags("DeviceLimitsReportFlags", 0);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700114 getLayerOptionEnum("DeviceLimitsDebugAction", (uint32_t *)&debug_action);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600115
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700116 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600117 option_str = getLayerOption("DeviceLimitsLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600118 log_output = getLayerLogOutput(option_str, "DeviceLimits");
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700119 VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700120 memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700121 dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700122 dbgCreateInfo.flags = report_flags;
123 dbgCreateInfo.pfnCallback = log_callback;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700124 dbgCreateInfo.pUserData = (void *)log_output;
125 layer_create_msg_callback(my_data->report_data, &dbgCreateInfo,
126 pAllocator, &callback);
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600127 my_data->logging_callback.push_back(callback);
128 }
129
130 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700131 VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700132 memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700133 dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700134 dbgCreateInfo.flags = report_flags;
135 dbgCreateInfo.pfnCallback = win32_debug_output_msg;
136 dbgCreateInfo.pUserData = NULL;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700137 layer_create_msg_callback(my_data->report_data, &dbgCreateInfo,
138 pAllocator, &callback);
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600139 my_data->logging_callback.push_back(callback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600140 }
141
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700142 if (!globalLockInitialized) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600143 // TODO/TBD: Need to delete this mutex sometime. How??? One
144 // suggestion is to call this during vkCreateInstance(), and then we
145 // can clean it up during vkDestroyInstance(). However, that requires
146 // that the layer have per-instance locks. We need to come back and
147 // address this soon.
148 loader_platform_thread_create_mutex(&globalLock);
149 globalLockInitialized = 1;
150 }
151}
Courtney Goeltzenleuchter20c35012015-11-30 12:14:06 -0700152
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -0700153static const VkExtensionProperties instance_extensions[] = {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700154 {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
Courtney Goeltzenleuchter20c35012015-11-30 12:14:06 -0700155
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700156VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
157 vkEnumerateInstanceExtensionProperties(const char *pLayerName,
158 uint32_t *pCount,
159 VkExtensionProperties *pProperties) {
160 return util_GetExtensionProperties(1, instance_extensions, pCount,
161 pProperties);
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600162}
163
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700164static const VkLayerProperties dl_global_layers[] = {{
165 "VK_LAYER_LUNARG_device_limits", VK_API_VERSION, VK_MAKE_VERSION(0, 1, 0),
166 "Validation layer: Device Limits",
167}};
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600168
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700169VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
170 vkEnumerateInstanceLayerProperties(uint32_t *pCount,
171 VkLayerProperties *pProperties) {
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600172 return util_GetLayerProperties(ARRAY_SIZE(dl_global_layers),
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700173 dl_global_layers, pCount, pProperties);
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600174}
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600175
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700176VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
177 vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
178 const VkAllocationCallbacks *pAllocator,
179 VkInstance *pInstance) {
180 VkLayerInstanceCreateInfo *chain_info =
181 get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600182
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700183 assert(chain_info->u.pLayerInfo);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700184 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
185 chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
186 PFN_vkCreateInstance fpCreateInstance =
187 (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700188 if (fpCreateInstance == NULL) {
189 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600190 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700191
192 // Advance the link info for the next element on the chain
193 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
194
195 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
196 if (result != VK_SUCCESS)
197 return result;
198
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700199 layer_data *my_data =
200 get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700201 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700202 layer_init_instance_dispatch_table(
203 *pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700204
205 my_data->report_data = debug_report_create_instance(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700206 my_data->instance_dispatch_table, *pInstance,
207 pCreateInfo->enabledExtensionCount,
208 pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700209
210 init_device_limits(my_data, pAllocator);
211 my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE());
212
213 return VK_SUCCESS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600214}
215
216/* hook DestroyInstance to remove tableInstanceMap entry */
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700217VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
218 vkDestroyInstance(VkInstance instance,
219 const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600220 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600221 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
222 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800223 pTable->DestroyInstance(instance, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600224
225 // Clean up logging callback, if any
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600226 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700227 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700228 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600229 my_data->logging_callback.pop_back();
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600230 }
231
232 layer_debug_report_destroy_instance(my_data->report_data);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600233 delete my_data->instance_dispatch_table;
234 layer_data_map.erase(key);
Tobin Ehlis0b632332015-10-07 09:38:40 -0600235 if (layer_data_map.empty()) {
236 // Release mutex when destroying last instance.
237 loader_platform_thread_delete_mutex(&globalLock);
238 globalLockInitialized = 0;
239 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600240}
241
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700242VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
243 vkEnumeratePhysicalDevices(VkInstance instance,
244 uint32_t *pPhysicalDeviceCount,
245 VkPhysicalDevice *pPhysicalDevices) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600246 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700247 layer_data *my_data =
248 get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600249 if (my_data->instanceState) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700250 // For this instance, flag when vkEnumeratePhysicalDevices goes to
251 // QUERY_COUNT and then QUERY_DETAILS
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600252 if (NULL == pPhysicalDevices) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700253 my_data->instanceState->vkEnumeratePhysicalDevicesState =
254 QUERY_COUNT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600255 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700256 if (UNCALLED ==
257 my_data->instanceState->vkEnumeratePhysicalDevicesState) {
258 // Flag error here, shouldn't be calling this without having
259 // queried count
260 skipCall |= log_msg(
261 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
262 VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
263 DEVLIMITS_MUST_QUERY_COUNT, "DL",
264 "Invalid call sequence to vkEnumeratePhysicalDevices() w/ "
265 "non-NULL pPhysicalDevices. You should first call "
266 "vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to "
267 "query pPhysicalDeviceCount.");
268 } // TODO : Could also flag a warning if re-calling this function in
269 // QUERY_DETAILS state
270 else if (my_data->instanceState->physicalDevicesCount !=
271 *pPhysicalDeviceCount) {
272 // TODO: Having actual count match count from app is not a
273 // requirement, so this can be a warning
274 skipCall |=
275 log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
276 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
277 __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
278 "Call to vkEnumeratePhysicalDevices() w/ "
279 "pPhysicalDeviceCount value %u, but actual count "
280 "supported by this instance is %u.",
281 *pPhysicalDeviceCount,
282 my_data->instanceState->physicalDevicesCount);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600283 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700284 my_data->instanceState->vkEnumeratePhysicalDevicesState =
285 QUERY_DETAILS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600286 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600287 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700288 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700289 VkResult result =
290 my_data->instance_dispatch_table->EnumeratePhysicalDevices(
291 instance, pPhysicalDeviceCount, pPhysicalDevices);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600292 if (NULL == pPhysicalDevices) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700293 my_data->instanceState->physicalDevicesCount =
294 *pPhysicalDeviceCount;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600295 } else { // Save physical devices
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700296 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
297 layer_data *phy_dev_data = get_my_data_ptr(
298 get_dispatch_key(pPhysicalDevices[i]), layer_data_map);
299 phy_dev_data->physicalDeviceState =
300 unique_ptr<PHYSICAL_DEVICE_STATE>(
301 new PHYSICAL_DEVICE_STATE());
Tobin Ehlis9da65002015-09-24 15:25:16 -0600302 // Init actual features for each physical device
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700303 my_data->instance_dispatch_table->GetPhysicalDeviceFeatures(
304 pPhysicalDevices[i],
305 &(phy_dev_data->actualPhysicalDeviceFeatures));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600306 }
307 }
308 return result;
309 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700310 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
311 VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
312 DEVLIMITS_INVALID_INSTANCE, "DL",
313 "Invalid instance (%#" PRIxLEAST64
314 ") passed into vkEnumeratePhysicalDevices().",
315 (uint64_t)instance);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600316 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700317 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600318}
319
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700320VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
321 vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
322 VkPhysicalDeviceFeatures *pFeatures) {
323 layer_data *phy_dev_data =
324 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
325 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState =
326 QUERY_DETAILS;
327 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFeatures(
328 physicalDevice, pFeatures);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600329}
330
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700331VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
332 vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
333 VkFormat format,
334 VkFormatProperties *pFormatProperties) {
335 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
336 ->instance_dispatch_table->GetPhysicalDeviceFormatProperties(
337 physicalDevice, format, pFormatProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600338}
339
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700340VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
341 vkGetPhysicalDeviceImageFormatProperties(
342 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
343 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
344 VkImageFormatProperties *pImageFormatProperties) {
345 return get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
346 ->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(
347 physicalDevice, format, type, tiling, usage, flags,
348 pImageFormatProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600349}
350
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700351VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
352 vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
353 VkPhysicalDeviceProperties *pProperties) {
354 layer_data *phy_dev_data =
355 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
356 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(
357 physicalDevice, pProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600358}
359
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700360VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
361 vkGetPhysicalDeviceQueueFamilyProperties(
362 VkPhysicalDevice physicalDevice, uint32_t *pCount,
363 VkQueueFamilyProperties *pQueueFamilyProperties) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600364 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700365 layer_data *phy_dev_data =
366 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600367 if (phy_dev_data->physicalDeviceState) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600368 if (NULL == pQueueFamilyProperties) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700369 phy_dev_data->physicalDeviceState
370 ->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600371 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700372 // Verify that for each physical device, this function is called
373 // first with NULL pQueueFamilyProperties ptr in order to get count
374 if (UNCALLED ==
375 phy_dev_data->physicalDeviceState
376 ->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
377 skipCall |= log_msg(
378 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
379 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
380 __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
381 "Invalid call sequence to "
382 "vkGetPhysicalDeviceQueueFamilyProperties() w/ non-NULL "
383 "pQueueFamilyProperties. You should first call "
384 "vkGetPhysicalDeviceQueueFamilyProperties() w/ NULL "
385 "pQueueFamilyProperties to query pCount.");
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600386 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700387 // Then verify that pCount that is passed in on second call matches
388 // what was returned
389 if (phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount !=
390 *pCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700391
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700392 // TODO: this is not a requirement of the Valid Usage section
393 // for vkGetPhysicalDeviceQueueFamilyProperties, so provide as
394 // warning
395 skipCall |= log_msg(
396 phy_dev_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
397 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
398 __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
399 "Call to vkGetPhysicalDeviceQueueFamilyProperties() w/ "
400 "pCount value %u, but actual count supported by this "
401 "physicalDevice is %u.",
402 *pCount, phy_dev_data->physicalDeviceState
403 ->queueFamilyPropertiesCount);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600404 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700405 phy_dev_data->physicalDeviceState
406 ->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600407 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600408 if (skipCall)
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600409 return;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700410 phy_dev_data->instance_dispatch_table
411 ->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount,
412 pQueueFamilyProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600413 if (NULL == pQueueFamilyProperties) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700414 phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount =
415 *pCount;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600416 } else { // Save queue family properties
Tobin Ehlis9da65002015-09-24 15:25:16 -0600417 phy_dev_data->queueFamilyProperties.reserve(*pCount);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700418 for (uint32_t i = 0; i < *pCount; i++) {
419 phy_dev_data->queueFamilyProperties.emplace_back(
420 new VkQueueFamilyProperties(pQueueFamilyProperties[i]));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600421 }
422 }
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600423 return;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600424 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700425 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
426 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
427 DEVLIMITS_INVALID_PHYSICAL_DEVICE, "DL",
428 "Invalid physicalDevice (%#" PRIxLEAST64
429 ") passed into vkGetPhysicalDeviceQueueFamilyProperties().",
430 (uint64_t)physicalDevice);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600431 }
432}
433
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700434VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
435 VkPhysicalDevice physicalDevice,
436 VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
437 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
438 ->instance_dispatch_table->GetPhysicalDeviceMemoryProperties(
439 physicalDevice, pMemoryProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600440}
441
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700442VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
443 vkGetPhysicalDeviceSparseImageFormatProperties(
444 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
445 VkSampleCountFlagBits samples, VkImageUsageFlags usage,
446 VkImageTiling tiling, uint32_t *pNumProperties,
447 VkSparseImageFormatProperties *pProperties) {
448 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
449 ->instance_dispatch_table->GetPhysicalDeviceSparseImageFormatProperties(
450 physicalDevice, format, type, samples, usage, tiling,
451 pNumProperties, pProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600452}
453
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700454VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
455 vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
456 uint32_t viewportCount, const VkViewport *pViewports) {
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600457 VkBool32 skipCall = VK_FALSE;
458 /* TODO: Verify viewportCount < maxViewports from VkPhysicalDeviceLimits */
459 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700460 layer_data *my_data =
461 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
462 my_data->device_dispatch_table->CmdSetViewport(
463 commandBuffer, firstViewport, viewportCount, pViewports);
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600464 }
465}
466
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700467VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
468 vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor,
469 uint32_t scissorCount, const VkRect2D *pScissors) {
Courtney Goeltzenleuchter49c73082015-09-17 15:06:17 -0600470 VkBool32 skipCall = VK_FALSE;
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600471 /* TODO: Verify scissorCount < maxViewports from VkPhysicalDeviceLimits */
472 /* TODO: viewportCount and scissorCount must match at draw time */
Courtney Goeltzenleuchter49c73082015-09-17 15:06:17 -0600473 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700474 layer_data *my_data =
475 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
476 my_data->device_dispatch_table->CmdSetScissor(
477 commandBuffer, firstScissor, scissorCount, pScissors);
Courtney Goeltzenleuchter49c73082015-09-17 15:06:17 -0600478 }
479}
480
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700481static void
482createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo,
483 VkDevice device) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600484 uint32_t i;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700485 layer_data *my_data =
486 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600487 my_data->device_extensions.debug_marker_enabled = false;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600488
Jon Ashburnf19916e2016-01-11 13:12:43 -0700489 for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700490 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
491 DEBUG_MARKER_EXTENSION_NAME) == 0) {
492 /* Found a matching extension name, mark it enabled and init
493 * dispatch table*/
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600494 initDebugMarkerTable(device);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600495 my_data->device_extensions.debug_marker_enabled = true;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600496 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600497 }
498}
499
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700500// Verify that features have been queried and verify that requested features are
501// available
502static VkBool32 validate_features_request(layer_data *phy_dev_data) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600503 VkBool32 skipCall = VK_FALSE;
504 // Verify that all of the requested features are available
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700505 // Get ptrs into actual and requested structs and if requested is 1 but
506 // actual is 0, request is invalid
507 VkBool32 *actual =
508 (VkBool32 *)&(phy_dev_data->actualPhysicalDeviceFeatures);
509 VkBool32 *requested =
510 (VkBool32 *)&(phy_dev_data->requestedPhysicalDeviceFeatures);
511 // TODO : This is a nice, compact way to loop through struct, but a bad way
512 // to report issues
513 // Need to provide the struct member name with the issue. To do that seems
514 // like we'll
515 // have to loop through each struct member which should be done w/ codegen
516 // to keep in synch.
Tobin Ehlis9da65002015-09-24 15:25:16 -0600517 uint32_t errors = 0;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700518 uint32_t totalBools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600519 for (uint32_t i = 0; i < totalBools; i++) {
520 if (requested[i] > actual[i]) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700521 skipCall |= log_msg(
522 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
523 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
524 DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
525 "While calling vkCreateDevice(), requesting feature #%u in "
526 "VkPhysicalDeviceFeatures struct, which is not available on "
527 "this device.",
528 i);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600529 errors++;
530 }
531 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700532 if (errors &&
533 (UNCALLED ==
534 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState)) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600535 // If user didn't request features, notify them that they should
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700536 // TODO: Verify this against the spec. I believe this is an invalid use
537 // of the API and should return an error
538 skipCall |=
539 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
540 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
541 __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
542 "You requested features that are unavailable on this "
543 "device. You should first query feature availability by "
544 "calling vkGetPhysicalDeviceFeatures().");
Tobin Ehlis9da65002015-09-24 15:25:16 -0600545 }
Tobin Ehlis72b27cc2015-09-29 11:22:37 -0600546 return skipCall;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600547}
548
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700549VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
550 vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
551 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600552 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700553 layer_data *phy_dev_data =
554 get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600555 // First check is app has actually requested queueFamilyProperties
Tobin Ehlis9da65002015-09-24 15:25:16 -0600556 if (!phy_dev_data->physicalDeviceState) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700557 skipCall |=
558 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
559 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
560 __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
561 "Invalid call to vkCreateDevice() w/o first calling "
562 "vkEnumeratePhysicalDevices().");
563 } else if (QUERY_DETAILS !=
564 phy_dev_data->physicalDeviceState
565 ->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
566 // TODO: This is not called out as an invalid use in the spec so make
567 // more informative recommendation.
568 skipCall |=
569 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
570 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
571 __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
572 "Call to vkCreateDevice() w/o first calling "
573 "vkGetPhysicalDeviceQueueFamilyProperties().");
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600574 } else {
575 // Check that the requested queue properties are valid
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700576 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
577 uint32_t requestedIndex =
578 pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
579 if (phy_dev_data->queueFamilyProperties.size() <=
580 requestedIndex) { // requested index is out of bounds for this
581 // physical device
582 skipCall |= log_msg(
583 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
584 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
585 __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
586 "Invalid queue create request in vkCreateDevice(). Invalid "
587 "queueFamilyIndex %u requested.",
588 requestedIndex);
589 } else if (pCreateInfo->pQueueCreateInfos[i].queueCount >
590 phy_dev_data->queueFamilyProperties[requestedIndex]
591 ->queueCount) {
592 skipCall |= log_msg(
593 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
594 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
595 __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
596 "Invalid queue create request in vkCreateDevice(). "
597 "QueueFamilyIndex %u only has %u queues, but requested "
598 "queueCount is %u.",
599 requestedIndex,
600 phy_dev_data->queueFamilyProperties[requestedIndex]
601 ->queueCount,
602 pCreateInfo->pQueueCreateInfos[i].queueCount);
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600603 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600604 }
605 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600606 // Check that any requested features are available
607 if (pCreateInfo->pEnabledFeatures) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700608 phy_dev_data->requestedPhysicalDeviceFeatures =
609 *(pCreateInfo->pEnabledFeatures);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600610 skipCall |= validate_features_request(phy_dev_data);
611 }
612 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700613 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600614
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700615 VkLayerDeviceCreateInfo *chain_info =
616 get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700617
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700618 assert(chain_info->u.pLayerInfo);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700619 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
620 chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
621 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr =
622 chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
623 PFN_vkCreateDevice fpCreateDevice =
624 (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700625 if (fpCreateDevice == NULL) {
626 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600627 }
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700628
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700629 // Advance the link info for the next element on the chain
630 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
631
632 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
633 if (result != VK_SUCCESS) {
634 return result;
635 }
636
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700637 layer_data *my_instance_data =
638 get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
639 layer_data *my_device_data =
640 get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700641 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700642 layer_init_device_dispatch_table(
643 *pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
644 my_device_data->report_data = layer_debug_report_create_device(
645 my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700646 my_device_data->physicalDevice = gpu;
647 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
648
649 // Get physical device properties for this device
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700650 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(
651 gpu, &(phy_dev_data->physDevPropertyMap[*pDevice]));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600652 return result;
653}
654
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700655VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
656 vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600657 // Free device lifetime allocations
658 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600659 layer_data *my_device_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800660 my_device_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600661 tableDebugMarkerMap.erase(key);
662 delete my_device_data->device_dispatch_table;
663 layer_data_map.erase(key);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600664}
665
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700666VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
667 vkCreateCommandPool(VkDevice device,
668 const VkCommandPoolCreateInfo *pCreateInfo,
669 const VkAllocationCallbacks *pAllocator,
670 VkCommandPool *pCommandPool) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600671 // TODO : Verify that requested QueueFamilyIndex for this pool exists
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700672 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
673 ->device_dispatch_table->CreateCommandPool(
674 device, pCreateInfo, pAllocator, pCommandPool);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600675 return result;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600676}
677
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700678VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
679 vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
680 const VkAllocationCallbacks *pAllocator) {
681 get_my_data_ptr(get_dispatch_key(device), layer_data_map)
682 ->device_dispatch_table->DestroyCommandPool(device, commandPool,
683 pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600684}
685
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700686VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
687 vkResetCommandPool(VkDevice device, VkCommandPool commandPool,
688 VkCommandPoolResetFlags flags) {
689 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
690 ->device_dispatch_table->ResetCommandPool(
691 device, commandPool, flags);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600692 return result;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600693}
694
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700695VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
696 vkAllocateCommandBuffers(VkDevice device,
697 const VkCommandBufferAllocateInfo *pCreateInfo,
698 VkCommandBuffer *pCommandBuffer) {
699 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
700 ->device_dispatch_table->AllocateCommandBuffers(
701 device, pCreateInfo, pCommandBuffer);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600702 return result;
703}
Mark Lobodzinskifbb130e2015-10-06 11:59:54 -0600704
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700705VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
706 vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
707 uint32_t count,
708 const VkCommandBuffer *pCommandBuffers) {
709 get_my_data_ptr(get_dispatch_key(device), layer_data_map)
710 ->device_dispatch_table->FreeCommandBuffers(device, commandPool, count,
711 pCommandBuffers);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600712}
713
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700714VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
715 vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex,
716 uint32_t queueIndex, VkQueue *pQueue) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600717 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700718 layer_data *dev_data =
719 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600720 VkPhysicalDevice gpu = dev_data->physicalDevice;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700721 layer_data *phy_dev_data =
722 get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
723 if (queueFamilyIndex >=
724 phy_dev_data->queueFamilyProperties.size()) { // requested index is out
725 // of bounds for this
726 // physical device
727 skipCall |= log_msg(
728 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
729 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
730 DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
731 "Invalid queueFamilyIndex %u requested in vkGetDeviceQueue().",
732 queueFamilyIndex);
733 } else if (queueIndex >=
734 phy_dev_data->queueFamilyProperties[queueFamilyIndex]
735 ->queueCount) {
736 skipCall |= log_msg(
737 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
738 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
739 DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
740 "Invalid queue request in vkGetDeviceQueue(). QueueFamilyIndex %u "
741 "only has %u queues, but requested queueIndex is %u.",
742 queueFamilyIndex,
743 phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount,
744 queueIndex);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600745 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600746 if (skipCall)
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600747 return;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700748 dev_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex,
749 queueIndex, pQueue);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600750}
751
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700752VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
753 vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
754 VkDeviceSize memoryOffset) {
755 layer_data *dev_data =
756 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
757 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
758 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700759
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700760 VkDeviceSize uniformAlignment = dev_data->physDevPropertyMap[device]
761 .limits.minUniformBufferOffsetAlignment;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700762 if (vk_safe_modulo(memoryOffset, uniformAlignment) != 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700763 skipCall |=
764 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
765 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
766 __LINE__, DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, "DL",
767 "vkBindBufferMemory(): memoryOffset %#" PRIxLEAST64
768 " must be a multiple of device limit "
769 "minUniformBufferOffsetAlignment %#" PRIxLEAST64,
770 memoryOffset, uniformAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700771 }
772
773 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700774 result = dev_data->device_dispatch_table->BindBufferMemory(
775 device, buffer, mem, memoryOffset);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700776 }
777 return result;
778}
779
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700780VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
781 vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
782 const VkWriteDescriptorSet *pDescriptorWrites,
783 uint32_t descriptorCopyCount,
784 const VkCopyDescriptorSet *pDescriptorCopies) {
785 layer_data *dev_data =
786 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
787 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
788 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700789
Mark Youngee3f3a22016-01-25 12:18:32 -0700790 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700791 if ((pDescriptorWrites[i].descriptorType ==
792 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
793 (pDescriptorWrites[i].descriptorType ==
794 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
795 VkDeviceSize uniformAlignment =
796 dev_data->physDevPropertyMap[device]
797 .limits.minUniformBufferOffsetAlignment;
798 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount;
799 j++) {
800 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset,
801 uniformAlignment) != 0) {
802 skipCall |= log_msg(
803 dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
804 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
805 __LINE__, DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, "DL",
806 "vkUpdateDescriptorSets(): "
807 "pDescriptorWrites[%d].pBufferInfo[%d].offset "
808 "(%#" PRIxLEAST64
809 ") must be a multiple of device limit "
810 "minUniformBufferOffsetAlignment %#" PRIxLEAST64,
811 i, j, pDescriptorWrites[i].pBufferInfo[j].offset,
812 uniformAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700813 }
814 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700815 } else if ((pDescriptorWrites[i].descriptorType ==
816 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
817 (pDescriptorWrites[i].descriptorType ==
818 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
819 VkDeviceSize storageAlignment =
820 dev_data->physDevPropertyMap[device]
821 .limits.minStorageBufferOffsetAlignment;
822 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount;
823 j++) {
824 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset,
825 storageAlignment) != 0) {
826 skipCall |= log_msg(
827 dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
828 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
829 __LINE__, DEVLIMITS_INVALID_STORAGE_BUFFER_OFFSET, "DL",
830 "vkUpdateDescriptorSets(): "
831 "pDescriptorWrites[%d].pBufferInfo[%d].offset "
832 "(%#" PRIxLEAST64
833 ") must be a multiple of device limit "
834 "minStorageBufferOffsetAlignment %#" PRIxLEAST64,
835 i, j, pDescriptorWrites[i].pBufferInfo[j].offset,
836 storageAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700837 }
838 }
839 }
840 }
841 if (skipCall == VK_FALSE) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700842 dev_data->device_dispatch_table->UpdateDescriptorSets(
843 device, descriptorWriteCount, pDescriptorWrites,
844 descriptorCopyCount, pDescriptorCopies);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700845 }
846}
847
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700848VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
849 vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
850 VkDeviceSize dstOffset, VkDeviceSize dataSize,
851 const uint32_t *pData) {
852 layer_data *dev_data =
853 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyana3082432015-09-25 13:39:21 -0600854
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700855 // dstOffset is the byte offset into the buffer to start updating and must
856 // be a multiple of 4.
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800857 if (dstOffset & 3) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700858 layer_data *my_data =
859 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
860 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
861 (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, "DL",
862 "vkCmdUpdateBuffer parameter, VkDeviceSize dstOffset, is "
863 "not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600864 return;
865 }
866 }
867
868 // dataSize is the number of bytes to update, which must be a multiple of 4.
869 if (dataSize & 3) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700870 layer_data *my_data =
871 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
872 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
873 (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, "DL",
874 "vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is "
875 "not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600876 return;
877 }
878 }
879
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700880 dev_data->device_dispatch_table->CmdUpdateBuffer(
881 commandBuffer, dstBuffer, dstOffset, dataSize, pData);
Mike Stroyana3082432015-09-25 13:39:21 -0600882}
883
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700884VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
885 vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
886 VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
887 layer_data *dev_data =
888 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyana3082432015-09-25 13:39:21 -0600889
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700890 // dstOffset is the byte offset into the buffer to start filling and must be
891 // a multiple of 4.
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800892 if (dstOffset & 3) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700893 layer_data *my_data =
894 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
895 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
896 (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, "DL",
897 "vkCmdFillBuffer parameter, VkDeviceSize dstOffset, is not "
898 "a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600899 return;
900 }
901 }
902
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800903 // size is the number of bytes to fill, which must be a multiple of 4.
904 if (size & 3) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700905 layer_data *my_data =
906 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
907 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
908 (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, "DL",
909 "vkCmdFillBuffer parameter, VkDeviceSize size, is not a "
910 "multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600911 return;
912 }
913 }
914
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700915 dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer,
916 dstOffset, size, data);
Mike Stroyana3082432015-09-25 13:39:21 -0600917}
918
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700919VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700920 VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
921 const VkAllocationCallbacks *pAllocator,
922 VkDebugReportCallbackEXT *pMsgCallback) {
923 layer_data *my_data =
924 get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
925 VkResult res =
926 my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(
927 instance, pCreateInfo, pAllocator, pMsgCallback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600928 if (VK_SUCCESS == res) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700929 res = layer_create_msg_callback(my_data->report_data, pCreateInfo,
930 pAllocator, pMsgCallback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600931 }
932 return res;
933}
934
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700935VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
936 vkDestroyDebugReportCallbackEXT(VkInstance instance,
937 VkDebugReportCallbackEXT msgCallback,
938 const VkAllocationCallbacks *pAllocator) {
939 layer_data *my_data =
940 get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
941 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(
942 instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700943 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600944}
945
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700946VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
947 vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
948 VkDebugReportObjectTypeEXT objType, uint64_t object,
949 size_t location, int32_t msgCode,
950 const char *pLayerPrefix, const char *pMsg) {
951 layer_data *my_data =
952 get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
953 my_data->instance_dispatch_table->DebugReportMessageEXT(
954 instance, flags, objType, object, location, msgCode, pLayerPrefix,
955 pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700956}
957
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700958VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
959 vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700960 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700961 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600962 if (!strcmp(funcName, "vkDestroyDevice"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700963 return (PFN_vkVoidFunction)vkDestroyDevice;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600964 if (!strcmp(funcName, "vkGetDeviceQueue"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700965 return (PFN_vkVoidFunction)vkGetDeviceQueue;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600966 if (!strcmp(funcName, "CreateCommandPool"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700967 return (PFN_vkVoidFunction)vkCreateCommandPool;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600968 if (!strcmp(funcName, "DestroyCommandPool"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700969 return (PFN_vkVoidFunction)vkDestroyCommandPool;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600970 if (!strcmp(funcName, "ResetCommandPool"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700971 return (PFN_vkVoidFunction)vkResetCommandPool;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800972 if (!strcmp(funcName, "vkAllocateCommandBuffers"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700973 return (PFN_vkVoidFunction)vkAllocateCommandBuffers;
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600974 if (!strcmp(funcName, "vkFreeCommandBuffers"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700975 return (PFN_vkVoidFunction)vkFreeCommandBuffers;
Mike Stroyana3082432015-09-25 13:39:21 -0600976 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700977 return (PFN_vkVoidFunction)vkCmdUpdateBuffer;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700978 if (!strcmp(funcName, "vkBindBufferMemory"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700979 return (PFN_vkVoidFunction)vkBindBufferMemory;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700980 if (!strcmp(funcName, "vkUpdateDescriptorSets"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700981 return (PFN_vkVoidFunction)vkUpdateDescriptorSets;
Mike Stroyana3082432015-09-25 13:39:21 -0600982 if (!strcmp(funcName, "vkCmdFillBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700983 return (PFN_vkVoidFunction)vkCmdFillBuffer;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600984
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700985 if (dev == NULL)
986 return NULL;
987
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700988 layer_data *my_data =
989 get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
990 VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600991 {
992 if (pTable->GetDeviceProcAddr == NULL)
993 return NULL;
994 return pTable->GetDeviceProcAddr(dev, funcName);
995 }
996}
997
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700998VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
999 vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001000 PFN_vkVoidFunction fptr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001001
Tobin Ehlis1cb7f572015-10-06 09:09:24 -06001002 layer_data *my_data;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001003 if (!strcmp(funcName, "vkGetInstanceProcAddr"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001004 return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001005 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001006 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001007 if (!strcmp(funcName, "vkCreateInstance"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001008 return (PFN_vkVoidFunction)vkCreateInstance;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001009 if (!strcmp(funcName, "vkDestroyInstance"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001010 return (PFN_vkVoidFunction)vkDestroyInstance;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001011 if (!strcmp(funcName, "vkCreateDevice"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001012 return (PFN_vkVoidFunction)vkCreateDevice;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001013 if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001014 return (PFN_vkVoidFunction)vkEnumeratePhysicalDevices;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001015 if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001016 return (PFN_vkVoidFunction)vkGetPhysicalDeviceFeatures;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001017 if (!strcmp(funcName, "vkGetPhysicalDeviceFormatProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001018 return (PFN_vkVoidFunction)vkGetPhysicalDeviceFormatProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001019 if (!strcmp(funcName, "vkGetPhysicalDeviceImageFormatProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001020 return (PFN_vkVoidFunction)vkGetPhysicalDeviceImageFormatProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001021 if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001022 return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001023 if (!strcmp(funcName, "vkGetPhysicalDeviceQueueFamilyProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001024 return (PFN_vkVoidFunction)vkGetPhysicalDeviceQueueFamilyProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001025 if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001026 return (PFN_vkVoidFunction)vkGetPhysicalDeviceMemoryProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001027 if (!strcmp(funcName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001028 return (
1029 PFN_vkVoidFunction)vkGetPhysicalDeviceSparseImageFormatProperties;
Tobin Ehlisfd3843f2015-09-29 12:26:00 -06001030 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001031 return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
Tobin Ehlisfd3843f2015-09-29 12:26:00 -06001032 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001033 return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001034
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001035 if (!instance)
1036 return NULL;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001037
1038 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
1039
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001040 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
1041 if (fptr)
1042 return fptr;
1043
1044 {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001045 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06001046 if (pTable->GetInstanceProcAddr == NULL)
1047 return NULL;
1048 return pTable->GetInstanceProcAddr(instance, funcName);
1049 }
1050}