blob: c6fb745223fd01db7193fffa0e441200463fe405 [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 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -06009 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060010 * http://www.apache.org/licenses/LICENSE-2.0
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060011 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060012 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060017 *
18 * Author: Mark Lobodzinski <mark@lunarg.com>
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070019 * Author: Mike Stroyan <mike@LunarG.com>
20 * Author: Tobin Ehlis <tobin@lunarg.com>
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060021 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <unordered_map>
27#include <memory>
28
29#include "vk_loader_platform.h"
30#include "vk_dispatch_table_helper.h"
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060031#if defined(__GNUC__)
32#pragma GCC diagnostic ignored "-Wwrite-strings"
33#endif
34#if defined(__GNUC__)
35#pragma GCC diagnostic warning "-Wwrite-strings"
36#endif
37#include "vk_struct_size_helper.h"
38#include "device_limits.h"
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -070039#include "vulkan/vk_layer.h"
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060040#include "vk_layer_config.h"
Michael Lentine5d8ad0a2016-01-28 15:03:46 -060041#include "vk_enum_validate_helper.h"
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060042#include "vk_layer_table.h"
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060043#include "vk_layer_data.h"
44#include "vk_layer_logging.h"
45#include "vk_layer_extension_utils.h"
Mark Lobodzinski6f2274e2015-09-22 09:33:21 -060046#include "vk_layer_utils.h"
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060047
Tobin Ehlis9da65002015-09-24 15:25:16 -060048// This struct will be stored in a map hashed by the dispatchable object
Cody Northrop55443ef2015-09-28 15:09:32 -060049struct layer_data {
Jon Ashburn5484e0c2016-03-08 17:48:44 -070050 debug_report_data *report_data;
51 std::vector<VkDebugReportCallbackEXT> logging_callback;
52 VkLayerDispatchTable *device_dispatch_table;
53 VkLayerInstanceDispatchTable *instance_dispatch_table;
Tobin Ehlis9da65002015-09-24 15:25:16 -060054 // Track state of each instance
Jon Ashburn5484e0c2016-03-08 17:48:44 -070055 unique_ptr<INSTANCE_STATE> instanceState;
56 unique_ptr<PHYSICAL_DEVICE_STATE> physicalDeviceState;
57 VkPhysicalDeviceFeatures actualPhysicalDeviceFeatures;
58 VkPhysicalDeviceFeatures requestedPhysicalDeviceFeatures;
Mark Lobodzinski941aea92016-01-13 10:23:15 -070059
Tobin Ehlis1cb7f572015-10-06 09:09:24 -060060 // Track physical device per logical device
61 VkPhysicalDevice physicalDevice;
Dustin Gravesa97c3942016-03-31 18:01:37 -060062 VkPhysicalDeviceProperties physicalDeviceProperties;
Tobin Ehlis9da65002015-09-24 15:25:16 -060063 // Vector indices correspond to queueFamilyIndex
64 vector<unique_ptr<VkQueueFamilyProperties>> queueFamilyProperties;
Cody Northrop55443ef2015-09-28 15:09:32 -060065
Jon Ashburn5484e0c2016-03-08 17:48:44 -070066 layer_data()
67 : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), instanceState(nullptr),
68 physicalDeviceState(nullptr), actualPhysicalDeviceFeatures(), requestedPhysicalDeviceFeatures(), physicalDevice(){};
Cody Northrop55443ef2015-09-28 15:09:32 -060069};
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060070
Tobin Ehlis1cb7f572015-10-06 09:09:24 -060071static unordered_map<void *, layer_data *> layer_data_map;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060072
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070073// TODO : This can be much smarter, using separate locks for separate global data
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060074static int globalLockInitialized = 0;
75static loader_platform_thread_mutex globalLock;
76
Jon Ashburn5484e0c2016-03-08 17:48:44 -070077template layer_data *get_my_data_ptr<layer_data>(void *data_key, std::unordered_map<void *, layer_data *> &data_map);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060078
Jon Ashburn5484e0c2016-03-08 17:48:44 -070079static void init_device_limits(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060080
Mark Lobodzinski1079e1b2016-03-15 14:21:59 -060081 layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_device_limits");
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060082
Jon Ashburn5484e0c2016-03-08 17:48:44 -070083 if (!globalLockInitialized) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060084 // TODO/TBD: Need to delete this mutex sometime. How??? One
85 // suggestion is to call this during vkCreateInstance(), and then we
86 // can clean it up during vkDestroyInstance(). However, that requires
87 // that the layer have per-instance locks. We need to come back and
88 // address this soon.
89 loader_platform_thread_create_mutex(&globalLock);
90 globalLockInitialized = 1;
91 }
92}
Courtney Goeltzenleuchter20c35012015-11-30 12:14:06 -070093
Jon Ashburn5484e0c2016-03-08 17:48:44 -070094static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
Courtney Goeltzenleuchter20c35012015-11-30 12:14:06 -070095
Jon Ashburn5484e0c2016-03-08 17:48:44 -070096VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
97vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070098 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
Tobin Ehlisfd3843f2015-09-29 12:26:00 -060099}
100
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700101VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
102 const char *pLayerName, uint32_t *pCount,
103 VkExtensionProperties *pProperties) {
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700104 if (pLayerName == NULL) {
105 dispatch_key key = get_dispatch_key(physicalDevice);
106 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700107 return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700108 } else {
109 return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
110 }
111}
112
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700113static const VkLayerProperties dl_global_layers[] = {{
Jon Ashburndc9111c2016-03-22 12:57:13 -0600114 "VK_LAYER_LUNARG_device_limits", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700115}};
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600116
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700117VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
118vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
119 return util_GetLayerProperties(ARRAY_SIZE(dl_global_layers), dl_global_layers, pCount, pProperties);
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600120}
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600121
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700122VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
123vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
124 return util_GetLayerProperties(ARRAY_SIZE(dl_global_layers), dl_global_layers, pCount, pProperties);
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700125}
126
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700127VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
128vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700129 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600130
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700131 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700132 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700133 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700134 if (fpCreateInstance == NULL) {
135 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600136 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700137
138 // Advance the link info for the next element on the chain
139 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
140
141 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
142 if (result != VK_SUCCESS)
143 return result;
144
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700145 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700146 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700147 layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700148
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700149 my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance,
150 pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700151
152 init_device_limits(my_data, pAllocator);
153 my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE());
154
155 return VK_SUCCESS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600156}
157
158/* hook DestroyInstance to remove tableInstanceMap entry */
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700159VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600160 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600161 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
162 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800163 pTable->DestroyInstance(instance, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600164
165 // Clean up logging callback, if any
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600166 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700167 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700168 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600169 my_data->logging_callback.pop_back();
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600170 }
171
172 layer_debug_report_destroy_instance(my_data->report_data);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600173 delete my_data->instance_dispatch_table;
174 layer_data_map.erase(key);
Tobin Ehlis0b632332015-10-07 09:38:40 -0600175 if (layer_data_map.empty()) {
176 // Release mutex when destroying last instance.
177 loader_platform_thread_delete_mutex(&globalLock);
178 globalLockInitialized = 0;
179 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600180}
181
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700182VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
183vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) {
Dustin Graves080069b2016-04-05 13:48:15 -0600184 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700185 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600186 if (my_data->instanceState) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700187 // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600188 if (NULL == pPhysicalDevices) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700189 my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_COUNT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600190 } else {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700191 if (UNCALLED == my_data->instanceState->vkEnumeratePhysicalDevicesState) {
192 // Flag error here, shouldn't be calling this without having queried count
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700193 skipCall |=
194 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0,
195 __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
196 "Invalid call sequence to vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first "
197 "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700198 } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state
199 else if (my_data->instanceState->physicalDevicesCount != *pPhysicalDeviceCount) {
200 // TODO: Having actual count match count from app is not a requirement, so this can be a warning
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700201 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
202 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
203 "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count "
204 "supported by this instance is %u.",
205 *pPhysicalDeviceCount, my_data->instanceState->physicalDevicesCount);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600206 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700207 my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_DETAILS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600208 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600209 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700210 return VK_ERROR_VALIDATION_FAILED_EXT;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700211 VkResult result =
212 my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600213 if (NULL == pPhysicalDevices) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700214 my_data->instanceState->physicalDevicesCount = *pPhysicalDeviceCount;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600215 } else { // Save physical devices
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700216 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700217 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map);
218 phy_dev_data->physicalDeviceState = unique_ptr<PHYSICAL_DEVICE_STATE>(new PHYSICAL_DEVICE_STATE());
Tobin Ehlis9da65002015-09-24 15:25:16 -0600219 // Init actual features for each physical device
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700220 my_data->instance_dispatch_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i],
221 &(phy_dev_data->actualPhysicalDeviceFeatures));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600222 }
223 }
224 return result;
225 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700226 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
227 DEVLIMITS_INVALID_INSTANCE, "DL", "Invalid instance (%#" PRIxLEAST64 ") passed into vkEnumeratePhysicalDevices().",
228 (uint64_t)instance);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600229 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700230 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600231}
232
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700233VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
234vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700235 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
236 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState = QUERY_DETAILS;
237 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600238}
239
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700240VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
241vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
242 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
243 ->instance_dispatch_table->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600244}
245
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700246VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
247vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
248 VkImageUsageFlags usage, VkImageCreateFlags flags,
249 VkImageFormatProperties *pImageFormatProperties) {
250 return get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
251 ->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
252 pImageFormatProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600253}
254
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700255VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
256vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700257 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
258 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600259}
260
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700261VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
262vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
263 VkQueueFamilyProperties *pQueueFamilyProperties) {
Dustin Graves080069b2016-04-05 13:48:15 -0600264 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700265 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600266 if (phy_dev_data->physicalDeviceState) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600267 if (NULL == pQueueFamilyProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700268 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600269 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700270 // Verify that for each physical device, this function is called first with NULL pQueueFamilyProperties ptr in order to
271 // get count
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700272 if (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700273 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
274 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
275 "Invalid call sequence to vkGetPhysicalDeviceQueueFamilyProperties() w/ non-NULL "
276 "pQueueFamilyProperties. You should first call vkGetPhysicalDeviceQueueFamilyProperties() w/ "
277 "NULL pQueueFamilyProperties to query pCount.");
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600278 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700279 // Then verify that pCount that is passed in on second call matches what was returned
280 if (phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount != *pCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700281
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700282 // TODO: this is not a requirement of the Valid Usage section for vkGetPhysicalDeviceQueueFamilyProperties, so
283 // provide as warning
284 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
285 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
286 "Call to vkGetPhysicalDeviceQueueFamilyProperties() w/ pCount value %u, but actual count "
287 "supported by this physicalDevice is %u.",
288 *pCount, phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600289 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700290 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600291 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600292 if (skipCall)
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600293 return;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700294 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount,
295 pQueueFamilyProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600296 if (NULL == pQueueFamilyProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700297 phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount = *pCount;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600298 } else { // Save queue family properties
Tobin Ehlis9da65002015-09-24 15:25:16 -0600299 phy_dev_data->queueFamilyProperties.reserve(*pCount);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700300 for (uint32_t i = 0; i < *pCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700301 phy_dev_data->queueFamilyProperties.emplace_back(new VkQueueFamilyProperties(pQueueFamilyProperties[i]));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600302 }
303 }
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600304 return;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600305 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700306 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
307 __LINE__, DEVLIMITS_INVALID_PHYSICAL_DEVICE, "DL",
308 "Invalid physicalDevice (%#" PRIxLEAST64 ") passed into vkGetPhysicalDeviceQueueFamilyProperties().",
309 (uint64_t)physicalDevice);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600310 }
311}
312
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700313VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
314vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
315 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
316 ->instance_dispatch_table->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600317}
318
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700319VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
320vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
321 VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling,
322 uint32_t *pNumProperties, VkSparseImageFormatProperties *pProperties) {
323 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
324 ->instance_dispatch_table->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage,
325 tiling, pNumProperties, pProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600326}
327
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700328VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
329vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) {
Dustin Graves080069b2016-04-05 13:48:15 -0600330 bool skipCall = false;
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600331 /* TODO: Verify viewportCount < maxViewports from VkPhysicalDeviceLimits */
Dustin Graves080069b2016-04-05 13:48:15 -0600332 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700333 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
334 my_data->device_dispatch_table->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600335 }
336}
337
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700338VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
339vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) {
Dustin Graves080069b2016-04-05 13:48:15 -0600340 bool skipCall = false;
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600341 /* TODO: Verify scissorCount < maxViewports from VkPhysicalDeviceLimits */
342 /* TODO: viewportCount and scissorCount must match at draw time */
Dustin Graves080069b2016-04-05 13:48:15 -0600343 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700344 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
345 my_data->device_dispatch_table->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
Courtney Goeltzenleuchter49c73082015-09-17 15:06:17 -0600346 }
347}
348
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700349// Verify that features have been queried and verify that requested features are available
Dustin Graves080069b2016-04-05 13:48:15 -0600350static bool validate_features_request(layer_data *phy_dev_data) {
351 bool skipCall = false;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600352 // Verify that all of the requested features are available
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700353 // Get ptrs into actual and requested structs and if requested is 1 but actual is 0, request is invalid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700354 VkBool32 *actual = (VkBool32 *)&(phy_dev_data->actualPhysicalDeviceFeatures);
355 VkBool32 *requested = (VkBool32 *)&(phy_dev_data->requestedPhysicalDeviceFeatures);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700356 // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues
357 // Need to provide the struct member name with the issue. To do that seems like we'll
358 // have to loop through each struct member which should be done w/ codegen to keep in synch.
Tobin Ehlis9da65002015-09-24 15:25:16 -0600359 uint32_t errors = 0;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700360 uint32_t totalBools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600361 for (uint32_t i = 0; i < totalBools; i++) {
362 if (requested[i] > actual[i]) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700363 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
364 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED,
365 "DL", "While calling vkCreateDevice(), requesting feature #%u in VkPhysicalDeviceFeatures struct, "
366 "which is not available on this device.",
367 i);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600368 errors++;
369 }
370 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700371 if (errors && (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState)) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600372 // If user didn't request features, notify them that they should
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700373 // TODO: Verify this against the spec. I believe this is an invalid use of the API and should return an error
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700374 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
375 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
376 "You requested features that are unavailable on this device. You should first query feature "
377 "availability by calling vkGetPhysicalDeviceFeatures().");
Tobin Ehlis9da65002015-09-24 15:25:16 -0600378 }
Tobin Ehlis72b27cc2015-09-29 11:22:37 -0600379 return skipCall;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600380}
381
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700382VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
383 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Dustin Graves080069b2016-04-05 13:48:15 -0600384 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700385 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600386 // First check is app has actually requested queueFamilyProperties
Tobin Ehlis9da65002015-09-24 15:25:16 -0600387 if (!phy_dev_data->physicalDeviceState) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700388 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
389 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
390 "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices().");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700391 } else if (QUERY_DETAILS != phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
392 // TODO: This is not called out as an invalid use in the spec so make more informative recommendation.
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700393 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
394 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
395 "DL", "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties().");
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600396 } else {
397 // Check that the requested queue properties are valid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700398 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700399 uint32_t requestedIndex = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700400 if (phy_dev_data->queueFamilyProperties.size() <=
401 requestedIndex) { // requested index is out of bounds for this physical device
402 skipCall |= log_msg(
403 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
404 __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700405 "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested.", requestedIndex);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700406 } else if (pCreateInfo->pQueueCreateInfos[i].queueCount >
407 phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount) {
408 skipCall |=
409 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
410 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
411 "DL", "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but "
412 "requested queueCount is %u.",
413 requestedIndex, phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount,
414 pCreateInfo->pQueueCreateInfos[i].queueCount);
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600415 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600416 }
417 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600418 // Check that any requested features are available
419 if (pCreateInfo->pEnabledFeatures) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700420 phy_dev_data->requestedPhysicalDeviceFeatures = *(pCreateInfo->pEnabledFeatures);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600421 skipCall |= validate_features_request(phy_dev_data);
422 }
423 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700424 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600425
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700426 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700427
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700428 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700429 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
430 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700431 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700432 if (fpCreateDevice == NULL) {
433 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600434 }
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700435
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700436 // Advance the link info for the next element on the chain
437 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
438
439 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
440 if (result != VK_SUCCESS) {
441 return result;
442 }
443
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700444 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700445 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700446 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
Dustin Gravesa97c3942016-03-31 18:01:37 -0600447 my_device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700448 my_device_data->physicalDevice = gpu;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700449
450 // Get physical device properties for this device
Dustin Gravesa97c3942016-03-31 18:01:37 -0600451 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_device_data->physicalDeviceProperties));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600452 return result;
453}
454
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700455VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600456 // Free device lifetime allocations
457 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600458 layer_data *my_device_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800459 my_device_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600460 delete my_device_data->device_dispatch_table;
461 layer_data_map.erase(key);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600462}
463
Michael Lentine20e4c192016-04-06 17:40:22 -0500464VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
465 const VkAllocationCallbacks *pAllocator,
466 VkRenderPass *pRenderPass) {
467 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
468 bool skip_call = false;
469 uint32_t max_color_attachments = dev_data->physicalDeviceProperties.limits.maxColorAttachments;
470 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
471 if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) {
472 skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
473 reinterpret_cast<uint64_t>(device), __LINE__, DEVLIMITS_INVALID_ATTACHMENT_COUNT, "DL",
474 "Cannot create a render pass with %d color attachments. Max is %d.",
475 pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments);
476 }
477 }
478 if (skip_call) {
479 return VK_ERROR_VALIDATION_FAILED_EXT;
480 }
481 return dev_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
482}
483
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700484VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
485 const VkAllocationCallbacks *pAllocator,
486 VkCommandPool *pCommandPool) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600487 // TODO : Verify that requested QueueFamilyIndex for this pool exists
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700488 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
489 ->device_dispatch_table->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600490 return result;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600491}
492
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700493VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
494vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
495 get_my_data_ptr(get_dispatch_key(device), layer_data_map)
496 ->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600497}
498
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700499VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
500vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
501 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
502 ->device_dispatch_table->ResetCommandPool(device, commandPool, flags);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600503 return result;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600504}
505
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700506VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
507vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo, VkCommandBuffer *pCommandBuffer) {
508 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
509 ->device_dispatch_table->AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600510 return result;
511}
Mark Lobodzinskifbb130e2015-10-06 11:59:54 -0600512
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700513VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
514vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t count, const VkCommandBuffer *pCommandBuffers) {
515 get_my_data_ptr(get_dispatch_key(device), layer_data_map)
516 ->device_dispatch_table->FreeCommandBuffers(device, commandPool, count, pCommandBuffers);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600517}
518
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700519VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
520vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
Michael Lentine09853ef2016-01-28 14:20:46 -0600521 bool skipCall = false;
522 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Tony Barboure24b8e32016-03-25 13:04:20 -0600523 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(dev_data->physicalDevice), layer_data_map);
Michael Lentine09853ef2016-01-28 14:20:46 -0600524 const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
Tony Barboure24b8e32016-03-25 13:04:20 -0600525 if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries == VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700526 skipCall |= log_msg(
527 dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
528 reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL",
529 "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support inheritedQueries.");
Michael Lentine09853ef2016-01-28 14:20:46 -0600530 }
Tony Barboure24b8e32016-03-25 13:04:20 -0600531 if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries != VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE &&
Michael Lentine5d8ad0a2016-01-28 15:03:46 -0600532 !validate_VkQueryControlFlagBits(VkQueryControlFlagBits(pInfo->queryFlags))) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700533 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
534 reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL",
535 "Cannot enable in occlusion queries in vkBeginCommandBuffer() and set queryFlags to %d which is not a "
536 "valid combination of VkQueryControlFlagBits.",
Michael Lentine5d8ad0a2016-01-28 15:03:46 -0600537 pInfo->queryFlags);
538 }
Michael Lentine0a369f62016-02-03 16:51:46 -0600539 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Michael Lentine09853ef2016-01-28 14:20:46 -0600540 if (!skipCall)
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700541 result = dev_data->device_dispatch_table->BeginCommandBuffer(commandBuffer, pBeginInfo);
Michael Lentine0a369f62016-02-03 16:51:46 -0600542 return result;
Michael Lentine09853ef2016-01-28 14:20:46 -0600543}
544
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700545VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
546vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
Dustin Graves080069b2016-04-05 13:48:15 -0600547 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700548 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600549 VkPhysicalDevice gpu = dev_data->physicalDevice;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700550 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700551 if (queueFamilyIndex >=
552 phy_dev_data->queueFamilyProperties.size()) { // requested index is out of bounds for this physical device
553 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
554 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
555 "DL", "Invalid queueFamilyIndex %u requested in vkGetDeviceQueue().", queueFamilyIndex);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700556 } else if (queueIndex >= phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700557 skipCall |= log_msg(
558 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
559 DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
560 "Invalid queue request in vkGetDeviceQueue(). QueueFamilyIndex %u only has %u queues, but requested queueIndex is %u.",
561 queueFamilyIndex, phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount, queueIndex);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600562 }
Dustin Graves080069b2016-04-05 13:48:15 -0600563 if (!skipCall)
564 dev_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600565}
566
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700567VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
568vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites,
569 uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) {
570 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Dustin Graves080069b2016-04-05 13:48:15 -0600571 bool skipCall = false;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700572
Mark Youngee3f3a22016-01-25 12:18:32 -0700573 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700574 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
575 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
Dustin Gravesa97c3942016-03-31 18:01:37 -0600576 VkDeviceSize uniformAlignment = dev_data->physicalDeviceProperties.limits.minUniformBufferOffsetAlignment;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700577 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
578 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700579 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
580 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
581 DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, "DL",
582 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (%#" PRIxLEAST64
583 ") must be a multiple of device limit minUniformBufferOffsetAlignment %#" PRIxLEAST64,
584 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700585 }
586 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700587 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
588 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Dustin Gravesa97c3942016-03-31 18:01:37 -0600589 VkDeviceSize storageAlignment = dev_data->physicalDeviceProperties.limits.minStorageBufferOffsetAlignment;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700590 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
591 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700592 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
593 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
594 DEVLIMITS_INVALID_STORAGE_BUFFER_OFFSET, "DL",
595 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (%#" PRIxLEAST64
596 ") must be a multiple of device limit minStorageBufferOffsetAlignment %#" PRIxLEAST64,
597 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700598 }
599 }
600 }
601 }
Dustin Graves080069b2016-04-05 13:48:15 -0600602 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700603 dev_data->device_dispatch_table->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
604 pDescriptorCopies);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700605 }
606}
607
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700608VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
609 VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700610 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyana3082432015-09-25 13:39:21 -0600611
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700612 // dstOffset is the byte offset into the buffer to start updating and must be a multiple of 4.
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800613 if (dstOffset & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700614 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200615 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
616 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700617 "vkCmdUpdateBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600618 return;
619 }
620 }
621
622 // dataSize is the number of bytes to update, which must be a multiple of 4.
623 if (dataSize & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700624 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200625 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
626 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700627 "vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600628 return;
629 }
630 }
631
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700632 dev_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
Mike Stroyana3082432015-09-25 13:39:21 -0600633}
634
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700635VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
636vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700637 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyana3082432015-09-25 13:39:21 -0600638
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700639 // dstOffset is the byte offset into the buffer to start filling and must be a multiple of 4.
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800640 if (dstOffset & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700641 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200642 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
643 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700644 "vkCmdFillBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600645 return;
646 }
647 }
648
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800649 // size is the number of bytes to fill, which must be a multiple of 4.
650 if (size & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700651 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200652 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
653 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700654 "vkCmdFillBuffer parameter, VkDeviceSize size, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600655 return;
656 }
657 }
658
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700659 dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
Mike Stroyana3082432015-09-25 13:39:21 -0600660}
661
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700662VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
663vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
664 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700665 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
666 VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600667 if (VK_SUCCESS == res) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700668 res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600669 }
670 return res;
671}
672
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700673VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,
674 VkDebugReportCallbackEXT msgCallback,
675 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700676 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
677 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700678 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600679}
680
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700681VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
682vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
683 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700684 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700685 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
686 pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700687}
688
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700689VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700690 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700691 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600692 if (!strcmp(funcName, "vkDestroyDevice"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700693 return (PFN_vkVoidFunction)vkDestroyDevice;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600694 if (!strcmp(funcName, "vkGetDeviceQueue"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700695 return (PFN_vkVoidFunction)vkGetDeviceQueue;
Michael Lentine20e4c192016-04-06 17:40:22 -0500696 if (!strcmp(funcName, "vkCreateRenderPass"))
697 return (PFN_vkVoidFunction)vkCreateRenderPass;
698 if (!strcmp(funcName, "vkCreateCommandPool"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700699 return (PFN_vkVoidFunction)vkCreateCommandPool;
Michael Lentine20e4c192016-04-06 17:40:22 -0500700 if (!strcmp(funcName, "vkDestroyCommandPool"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700701 return (PFN_vkVoidFunction)vkDestroyCommandPool;
Michael Lentine20e4c192016-04-06 17:40:22 -0500702 if (!strcmp(funcName, "vkResetCommandPool"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700703 return (PFN_vkVoidFunction)vkResetCommandPool;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800704 if (!strcmp(funcName, "vkAllocateCommandBuffers"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700705 return (PFN_vkVoidFunction)vkAllocateCommandBuffers;
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600706 if (!strcmp(funcName, "vkFreeCommandBuffers"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700707 return (PFN_vkVoidFunction)vkFreeCommandBuffers;
Michael Lentine09853ef2016-01-28 14:20:46 -0600708 if (!strcmp(funcName, "vkBeginCommandBuffer"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700709 return (PFN_vkVoidFunction)vkBeginCommandBuffer;
Mike Stroyana3082432015-09-25 13:39:21 -0600710 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700711 return (PFN_vkVoidFunction)vkCmdUpdateBuffer;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700712 if (!strcmp(funcName, "vkUpdateDescriptorSets"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700713 return (PFN_vkVoidFunction)vkUpdateDescriptorSets;
Mike Stroyana3082432015-09-25 13:39:21 -0600714 if (!strcmp(funcName, "vkCmdFillBuffer"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700715 return (PFN_vkVoidFunction)vkCmdFillBuffer;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600716
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700717 if (dev == NULL)
718 return NULL;
719
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700720 layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700721 VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600722 {
723 if (pTable->GetDeviceProcAddr == NULL)
724 return NULL;
725 return pTable->GetDeviceProcAddr(dev, funcName);
726 }
727}
728
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700729VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600730 PFN_vkVoidFunction fptr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600731
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600732 layer_data *my_data;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700733 if (!strcmp(funcName, "vkGetInstanceProcAddr"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700734 return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700735 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700736 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600737 if (!strcmp(funcName, "vkCreateInstance"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700738 return (PFN_vkVoidFunction)vkCreateInstance;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600739 if (!strcmp(funcName, "vkDestroyInstance"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700740 return (PFN_vkVoidFunction)vkDestroyInstance;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700741 if (!strcmp(funcName, "vkCreateDevice"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700742 return (PFN_vkVoidFunction)vkCreateDevice;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600743 if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700744 return (PFN_vkVoidFunction)vkEnumeratePhysicalDevices;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600745 if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700746 return (PFN_vkVoidFunction)vkGetPhysicalDeviceFeatures;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600747 if (!strcmp(funcName, "vkGetPhysicalDeviceFormatProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700748 return (PFN_vkVoidFunction)vkGetPhysicalDeviceFormatProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600749 if (!strcmp(funcName, "vkGetPhysicalDeviceImageFormatProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700750 return (PFN_vkVoidFunction)vkGetPhysicalDeviceImageFormatProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600751 if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700752 return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600753 if (!strcmp(funcName, "vkGetPhysicalDeviceQueueFamilyProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700754 return (PFN_vkVoidFunction)vkGetPhysicalDeviceQueueFamilyProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600755 if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700756 return (PFN_vkVoidFunction)vkGetPhysicalDeviceMemoryProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600757 if (!strcmp(funcName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700758 return (PFN_vkVoidFunction)vkGetPhysicalDeviceSparseImageFormatProperties;
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600759 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700760 return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700761 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
762 return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties;
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600763 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700764 return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700765 if (!strcmp(funcName, "vkEnumerateInstanceDeviceProperties"))
766 return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600767
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700768 if (!instance)
769 return NULL;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700770
771 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
772
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600773 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
774 if (fptr)
775 return fptr;
776
777 {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700778 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600779 if (pTable->GetInstanceProcAddr == NULL)
780 return NULL;
781 return pTable->GetInstanceProcAddr(instance, funcName);
782 }
783}