blob: 90dee4abdd291c9c6c9c6a9bab75b17781dbc622 [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 -070096static const VkLayerProperties dl_global_layers[] = {{
Jon Ashburndc9111c2016-03-22 12:57:13 -060097 "VK_LAYER_LUNARG_device_limits", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer",
Jon Ashburn5484e0c2016-03-08 17:48:44 -070098}};
Tobin Ehlisfd3843f2015-09-29 12:26:00 -060099
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700100VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700101vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700102 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600103
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700104 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700105 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700106 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700107 if (fpCreateInstance == NULL) {
108 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600109 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700110
111 // Advance the link info for the next element on the chain
112 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
113
114 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
115 if (result != VK_SUCCESS)
116 return result;
117
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700118 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700119 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700120 layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700121
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700122 my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance,
123 pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700124
125 init_device_limits(my_data, pAllocator);
126 my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE());
127
128 return VK_SUCCESS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600129}
130
131/* hook DestroyInstance to remove tableInstanceMap entry */
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700132VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600133 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600134 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
135 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800136 pTable->DestroyInstance(instance, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600137
138 // Clean up logging callback, if any
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600139 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700140 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700141 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600142 my_data->logging_callback.pop_back();
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600143 }
144
145 layer_debug_report_destroy_instance(my_data->report_data);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600146 delete my_data->instance_dispatch_table;
147 layer_data_map.erase(key);
Tobin Ehlis0b632332015-10-07 09:38:40 -0600148 if (layer_data_map.empty()) {
149 // Release mutex when destroying last instance.
150 loader_platform_thread_delete_mutex(&globalLock);
151 globalLockInitialized = 0;
152 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600153}
154
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700155VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
156vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) {
Dustin Graves080069b2016-04-05 13:48:15 -0600157 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700158 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600159 if (my_data->instanceState) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700160 // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600161 if (NULL == pPhysicalDevices) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700162 my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_COUNT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600163 } else {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700164 if (UNCALLED == my_data->instanceState->vkEnumeratePhysicalDevicesState) {
165 // Flag error here, shouldn't be calling this without having queried count
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700166 skipCall |=
167 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0,
168 __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
169 "Invalid call sequence to vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first "
170 "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700171 } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state
172 else if (my_data->instanceState->physicalDevicesCount != *pPhysicalDeviceCount) {
173 // 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 -0700174 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
175 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
176 "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count "
177 "supported by this instance is %u.",
178 *pPhysicalDeviceCount, my_data->instanceState->physicalDevicesCount);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600179 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700180 my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_DETAILS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600181 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600182 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700183 return VK_ERROR_VALIDATION_FAILED_EXT;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700184 VkResult result =
185 my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600186 if (NULL == pPhysicalDevices) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700187 my_data->instanceState->physicalDevicesCount = *pPhysicalDeviceCount;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600188 } else { // Save physical devices
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700189 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700190 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map);
191 phy_dev_data->physicalDeviceState = unique_ptr<PHYSICAL_DEVICE_STATE>(new PHYSICAL_DEVICE_STATE());
Tobin Ehlis9da65002015-09-24 15:25:16 -0600192 // Init actual features for each physical device
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700193 my_data->instance_dispatch_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i],
194 &(phy_dev_data->actualPhysicalDeviceFeatures));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600195 }
196 }
197 return result;
198 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700199 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
200 DEVLIMITS_INVALID_INSTANCE, "DL", "Invalid instance (%#" PRIxLEAST64 ") passed into vkEnumeratePhysicalDevices().",
201 (uint64_t)instance);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600202 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700203 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600204}
205
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700206VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
207vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700208 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
209 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState = QUERY_DETAILS;
210 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600211}
212
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700213VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
214vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
215 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
216 ->instance_dispatch_table->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600217}
218
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700219VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
220vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
221 VkImageUsageFlags usage, VkImageCreateFlags flags,
222 VkImageFormatProperties *pImageFormatProperties) {
223 return get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
224 ->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
225 pImageFormatProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600226}
227
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700228VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
229vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700230 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
231 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600232}
233
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700234VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
235vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
236 VkQueueFamilyProperties *pQueueFamilyProperties) {
Dustin Graves080069b2016-04-05 13:48:15 -0600237 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700238 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600239 if (phy_dev_data->physicalDeviceState) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600240 if (NULL == pQueueFamilyProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700241 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600242 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700243 // Verify that for each physical device, this function is called first with NULL pQueueFamilyProperties ptr in order to
244 // get count
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700245 if (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700246 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
247 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
248 "Invalid call sequence to vkGetPhysicalDeviceQueueFamilyProperties() w/ non-NULL "
249 "pQueueFamilyProperties. You should first call vkGetPhysicalDeviceQueueFamilyProperties() w/ "
250 "NULL pQueueFamilyProperties to query pCount.");
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600251 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700252 // Then verify that pCount that is passed in on second call matches what was returned
253 if (phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount != *pCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700254
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700255 // TODO: this is not a requirement of the Valid Usage section for vkGetPhysicalDeviceQueueFamilyProperties, so
256 // provide as warning
257 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
258 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
259 "Call to vkGetPhysicalDeviceQueueFamilyProperties() w/ pCount value %u, but actual count "
260 "supported by this physicalDevice is %u.",
261 *pCount, phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600262 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700263 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600264 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600265 if (skipCall)
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600266 return;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700267 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount,
268 pQueueFamilyProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600269 if (NULL == pQueueFamilyProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700270 phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount = *pCount;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600271 } else { // Save queue family properties
Tobin Ehlis9da65002015-09-24 15:25:16 -0600272 phy_dev_data->queueFamilyProperties.reserve(*pCount);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700273 for (uint32_t i = 0; i < *pCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700274 phy_dev_data->queueFamilyProperties.emplace_back(new VkQueueFamilyProperties(pQueueFamilyProperties[i]));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600275 }
276 }
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600277 return;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600278 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700279 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
280 __LINE__, DEVLIMITS_INVALID_PHYSICAL_DEVICE, "DL",
281 "Invalid physicalDevice (%#" PRIxLEAST64 ") passed into vkGetPhysicalDeviceQueueFamilyProperties().",
282 (uint64_t)physicalDevice);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600283 }
284}
285
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700286VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
287vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
288 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
289 ->instance_dispatch_table->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600290}
291
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700292VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
293vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
294 VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling,
295 uint32_t *pNumProperties, VkSparseImageFormatProperties *pProperties) {
296 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
297 ->instance_dispatch_table->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage,
298 tiling, pNumProperties, pProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600299}
300
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700301VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
302vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) {
Dustin Graves080069b2016-04-05 13:48:15 -0600303 bool skipCall = false;
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600304 /* TODO: Verify viewportCount < maxViewports from VkPhysicalDeviceLimits */
Dustin Graves080069b2016-04-05 13:48:15 -0600305 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700306 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
307 my_data->device_dispatch_table->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600308 }
309}
310
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700311VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
312vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) {
Dustin Graves080069b2016-04-05 13:48:15 -0600313 bool skipCall = false;
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600314 /* TODO: Verify scissorCount < maxViewports from VkPhysicalDeviceLimits */
315 /* TODO: viewportCount and scissorCount must match at draw time */
Dustin Graves080069b2016-04-05 13:48:15 -0600316 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700317 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
318 my_data->device_dispatch_table->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
Courtney Goeltzenleuchter49c73082015-09-17 15:06:17 -0600319 }
320}
321
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700322// Verify that features have been queried and verify that requested features are available
Dustin Graves080069b2016-04-05 13:48:15 -0600323static bool validate_features_request(layer_data *phy_dev_data) {
324 bool skipCall = false;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600325 // Verify that all of the requested features are available
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700326 // 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 -0700327 VkBool32 *actual = (VkBool32 *)&(phy_dev_data->actualPhysicalDeviceFeatures);
328 VkBool32 *requested = (VkBool32 *)&(phy_dev_data->requestedPhysicalDeviceFeatures);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700329 // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues
330 // Need to provide the struct member name with the issue. To do that seems like we'll
331 // have to loop through each struct member which should be done w/ codegen to keep in synch.
Tobin Ehlis9da65002015-09-24 15:25:16 -0600332 uint32_t errors = 0;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700333 uint32_t totalBools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600334 for (uint32_t i = 0; i < totalBools; i++) {
335 if (requested[i] > actual[i]) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700336 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
337 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED,
338 "DL", "While calling vkCreateDevice(), requesting feature #%u in VkPhysicalDeviceFeatures struct, "
339 "which is not available on this device.",
340 i);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600341 errors++;
342 }
343 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700344 if (errors && (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState)) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600345 // If user didn't request features, notify them that they should
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700346 // 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 -0700347 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
348 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
349 "You requested features that are unavailable on this device. You should first query feature "
350 "availability by calling vkGetPhysicalDeviceFeatures().");
Tobin Ehlis9da65002015-09-24 15:25:16 -0600351 }
Tobin Ehlis72b27cc2015-09-29 11:22:37 -0600352 return skipCall;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600353}
354
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700355VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
356 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Dustin Graves080069b2016-04-05 13:48:15 -0600357 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700358 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600359 // First check is app has actually requested queueFamilyProperties
Tobin Ehlis9da65002015-09-24 15:25:16 -0600360 if (!phy_dev_data->physicalDeviceState) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700361 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
362 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
363 "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices().");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700364 } else if (QUERY_DETAILS != phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
365 // 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 -0700366 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
367 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
368 "DL", "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties().");
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600369 } else {
370 // Check that the requested queue properties are valid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700371 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700372 uint32_t requestedIndex = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700373 if (phy_dev_data->queueFamilyProperties.size() <=
374 requestedIndex) { // requested index is out of bounds for this physical device
375 skipCall |= log_msg(
376 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
377 __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700378 "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested.", requestedIndex);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700379 } else if (pCreateInfo->pQueueCreateInfos[i].queueCount >
380 phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount) {
381 skipCall |=
382 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
383 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
384 "DL", "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but "
385 "requested queueCount is %u.",
386 requestedIndex, phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount,
387 pCreateInfo->pQueueCreateInfos[i].queueCount);
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600388 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600389 }
390 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600391 // Check that any requested features are available
392 if (pCreateInfo->pEnabledFeatures) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700393 phy_dev_data->requestedPhysicalDeviceFeatures = *(pCreateInfo->pEnabledFeatures);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600394 skipCall |= validate_features_request(phy_dev_data);
395 }
396 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700397 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600398
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700399 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700400
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700401 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700402 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
403 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700404 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700405 if (fpCreateDevice == NULL) {
406 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600407 }
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700408
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700409 // Advance the link info for the next element on the chain
410 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
411
412 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
413 if (result != VK_SUCCESS) {
414 return result;
415 }
416
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700417 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700418 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700419 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
Dustin Gravesa97c3942016-03-31 18:01:37 -0600420 my_device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700421 my_device_data->physicalDevice = gpu;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700422
423 // Get physical device properties for this device
Dustin Gravesa97c3942016-03-31 18:01:37 -0600424 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_device_data->physicalDeviceProperties));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600425 return result;
426}
427
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700428VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600429 // Free device lifetime allocations
430 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600431 layer_data *my_device_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800432 my_device_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600433 delete my_device_data->device_dispatch_table;
434 layer_data_map.erase(key);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600435}
436
Michael Lentine20e4c192016-04-06 17:40:22 -0500437VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
438 const VkAllocationCallbacks *pAllocator,
439 VkRenderPass *pRenderPass) {
440 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
441 bool skip_call = false;
442 uint32_t max_color_attachments = dev_data->physicalDeviceProperties.limits.maxColorAttachments;
443 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
444 if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) {
445 skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
446 reinterpret_cast<uint64_t>(device), __LINE__, DEVLIMITS_INVALID_ATTACHMENT_COUNT, "DL",
447 "Cannot create a render pass with %d color attachments. Max is %d.",
448 pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments);
449 }
450 }
451 if (skip_call) {
452 return VK_ERROR_VALIDATION_FAILED_EXT;
453 }
454 return dev_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
455}
456
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700457VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
458 const VkAllocationCallbacks *pAllocator,
459 VkCommandPool *pCommandPool) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600460 // TODO : Verify that requested QueueFamilyIndex for this pool exists
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700461 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
462 ->device_dispatch_table->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600463 return result;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600464}
465
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700466VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
467vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
468 get_my_data_ptr(get_dispatch_key(device), layer_data_map)
469 ->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600470}
471
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700472VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
473vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
474 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
475 ->device_dispatch_table->ResetCommandPool(device, commandPool, flags);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600476 return result;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600477}
478
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700479VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
480vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo, VkCommandBuffer *pCommandBuffer) {
481 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
482 ->device_dispatch_table->AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600483 return result;
484}
Mark Lobodzinskifbb130e2015-10-06 11:59:54 -0600485
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700486VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
487vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t count, const VkCommandBuffer *pCommandBuffers) {
488 get_my_data_ptr(get_dispatch_key(device), layer_data_map)
489 ->device_dispatch_table->FreeCommandBuffers(device, commandPool, count, pCommandBuffers);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600490}
491
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700492VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
493vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
Michael Lentine09853ef2016-01-28 14:20:46 -0600494 bool skipCall = false;
495 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Tony Barboure24b8e32016-03-25 13:04:20 -0600496 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 -0600497 const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
Tony Barboure24b8e32016-03-25 13:04:20 -0600498 if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries == VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700499 skipCall |= log_msg(
500 dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
501 reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL",
502 "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support inheritedQueries.");
Michael Lentine09853ef2016-01-28 14:20:46 -0600503 }
Tony Barboure24b8e32016-03-25 13:04:20 -0600504 if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries != VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE &&
Michael Lentine5d8ad0a2016-01-28 15:03:46 -0600505 !validate_VkQueryControlFlagBits(VkQueryControlFlagBits(pInfo->queryFlags))) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700506 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
507 reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL",
508 "Cannot enable in occlusion queries in vkBeginCommandBuffer() and set queryFlags to %d which is not a "
509 "valid combination of VkQueryControlFlagBits.",
Michael Lentine5d8ad0a2016-01-28 15:03:46 -0600510 pInfo->queryFlags);
511 }
Michael Lentine0a369f62016-02-03 16:51:46 -0600512 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Michael Lentine09853ef2016-01-28 14:20:46 -0600513 if (!skipCall)
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700514 result = dev_data->device_dispatch_table->BeginCommandBuffer(commandBuffer, pBeginInfo);
Michael Lentine0a369f62016-02-03 16:51:46 -0600515 return result;
Michael Lentine09853ef2016-01-28 14:20:46 -0600516}
517
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700518VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
519vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
Dustin Graves080069b2016-04-05 13:48:15 -0600520 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700521 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600522 VkPhysicalDevice gpu = dev_data->physicalDevice;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700523 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700524 if (queueFamilyIndex >=
525 phy_dev_data->queueFamilyProperties.size()) { // requested index is out of bounds for this physical device
526 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
527 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
528 "DL", "Invalid queueFamilyIndex %u requested in vkGetDeviceQueue().", queueFamilyIndex);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700529 } else if (queueIndex >= phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700530 skipCall |= log_msg(
531 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
532 DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
533 "Invalid queue request in vkGetDeviceQueue(). QueueFamilyIndex %u only has %u queues, but requested queueIndex is %u.",
534 queueFamilyIndex, phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount, queueIndex);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600535 }
Dustin Graves080069b2016-04-05 13:48:15 -0600536 if (!skipCall)
537 dev_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600538}
539
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700540VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
541vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites,
542 uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) {
543 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Dustin Graves080069b2016-04-05 13:48:15 -0600544 bool skipCall = false;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700545
Mark Youngee3f3a22016-01-25 12:18:32 -0700546 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700547 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
548 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
Dustin Gravesa97c3942016-03-31 18:01:37 -0600549 VkDeviceSize uniformAlignment = dev_data->physicalDeviceProperties.limits.minUniformBufferOffsetAlignment;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700550 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
551 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700552 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
553 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
554 DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, "DL",
555 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (%#" PRIxLEAST64
556 ") must be a multiple of device limit minUniformBufferOffsetAlignment %#" PRIxLEAST64,
557 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700558 }
559 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700560 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
561 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Dustin Gravesa97c3942016-03-31 18:01:37 -0600562 VkDeviceSize storageAlignment = dev_data->physicalDeviceProperties.limits.minStorageBufferOffsetAlignment;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700563 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
564 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700565 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
566 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
567 DEVLIMITS_INVALID_STORAGE_BUFFER_OFFSET, "DL",
568 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (%#" PRIxLEAST64
569 ") must be a multiple of device limit minStorageBufferOffsetAlignment %#" PRIxLEAST64,
570 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700571 }
572 }
573 }
574 }
Dustin Graves080069b2016-04-05 13:48:15 -0600575 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700576 dev_data->device_dispatch_table->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
577 pDescriptorCopies);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700578 }
579}
580
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700581VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
582 VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700583 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyana3082432015-09-25 13:39:21 -0600584
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700585 // 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 +0800586 if (dstOffset & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700587 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200588 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
589 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700590 "vkCmdUpdateBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600591 return;
592 }
593 }
594
595 // dataSize is the number of bytes to update, which must be a multiple of 4.
596 if (dataSize & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700597 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200598 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
599 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700600 "vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600601 return;
602 }
603 }
604
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700605 dev_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
Mike Stroyana3082432015-09-25 13:39:21 -0600606}
607
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700608VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
609vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
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 filling 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 "vkCmdFillBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600618 return;
619 }
620 }
621
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800622 // size is the number of bytes to fill, which must be a multiple of 4.
623 if (size & 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 "vkCmdFillBuffer parameter, VkDeviceSize size, 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->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
Mike Stroyana3082432015-09-25 13:39:21 -0600633}
634
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700635VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
636vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
637 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700638 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
639 VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600640 if (VK_SUCCESS == res) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700641 res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600642 }
643 return res;
644}
645
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700646VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,
647 VkDebugReportCallbackEXT msgCallback,
648 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700649 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
650 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700651 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600652}
653
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700654VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
655vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
656 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700657 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700658 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
659 pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700660}
661
Chia-I Wu16489ac2016-04-28 11:21:49 +0800662VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
663 const char *pLayerName, uint32_t *pCount,
664 VkExtensionProperties *pProperties) {
665 if (pLayerName == NULL) {
666 dispatch_key key = get_dispatch_key(physicalDevice);
667 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
668 return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
669 } else {
670 return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
671 }
672}
673
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700674VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700675 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700676 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600677 if (!strcmp(funcName, "vkDestroyDevice"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700678 return (PFN_vkVoidFunction)vkDestroyDevice;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600679 if (!strcmp(funcName, "vkGetDeviceQueue"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700680 return (PFN_vkVoidFunction)vkGetDeviceQueue;
Michael Lentine20e4c192016-04-06 17:40:22 -0500681 if (!strcmp(funcName, "vkCreateRenderPass"))
682 return (PFN_vkVoidFunction)vkCreateRenderPass;
683 if (!strcmp(funcName, "vkCreateCommandPool"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700684 return (PFN_vkVoidFunction)vkCreateCommandPool;
Michael Lentine20e4c192016-04-06 17:40:22 -0500685 if (!strcmp(funcName, "vkDestroyCommandPool"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700686 return (PFN_vkVoidFunction)vkDestroyCommandPool;
Michael Lentine20e4c192016-04-06 17:40:22 -0500687 if (!strcmp(funcName, "vkResetCommandPool"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700688 return (PFN_vkVoidFunction)vkResetCommandPool;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800689 if (!strcmp(funcName, "vkAllocateCommandBuffers"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700690 return (PFN_vkVoidFunction)vkAllocateCommandBuffers;
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600691 if (!strcmp(funcName, "vkFreeCommandBuffers"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700692 return (PFN_vkVoidFunction)vkFreeCommandBuffers;
Michael Lentine09853ef2016-01-28 14:20:46 -0600693 if (!strcmp(funcName, "vkBeginCommandBuffer"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700694 return (PFN_vkVoidFunction)vkBeginCommandBuffer;
Mike Stroyana3082432015-09-25 13:39:21 -0600695 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700696 return (PFN_vkVoidFunction)vkCmdUpdateBuffer;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700697 if (!strcmp(funcName, "vkUpdateDescriptorSets"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700698 return (PFN_vkVoidFunction)vkUpdateDescriptorSets;
Mike Stroyana3082432015-09-25 13:39:21 -0600699 if (!strcmp(funcName, "vkCmdFillBuffer"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700700 return (PFN_vkVoidFunction)vkCmdFillBuffer;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600701
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700702 if (dev == NULL)
703 return NULL;
704
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700705 layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700706 VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600707 {
708 if (pTable->GetDeviceProcAddr == NULL)
709 return NULL;
710 return pTable->GetDeviceProcAddr(dev, funcName);
711 }
712}
713
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700714VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600715 PFN_vkVoidFunction fptr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600716
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600717 layer_data *my_data;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700718 if (!strcmp(funcName, "vkGetInstanceProcAddr"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700719 return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700720 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700721 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600722 if (!strcmp(funcName, "vkCreateInstance"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700723 return (PFN_vkVoidFunction)vkCreateInstance;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600724 if (!strcmp(funcName, "vkDestroyInstance"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700725 return (PFN_vkVoidFunction)vkDestroyInstance;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700726 if (!strcmp(funcName, "vkCreateDevice"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700727 return (PFN_vkVoidFunction)vkCreateDevice;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600728 if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700729 return (PFN_vkVoidFunction)vkEnumeratePhysicalDevices;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600730 if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700731 return (PFN_vkVoidFunction)vkGetPhysicalDeviceFeatures;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600732 if (!strcmp(funcName, "vkGetPhysicalDeviceFormatProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700733 return (PFN_vkVoidFunction)vkGetPhysicalDeviceFormatProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600734 if (!strcmp(funcName, "vkGetPhysicalDeviceImageFormatProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700735 return (PFN_vkVoidFunction)vkGetPhysicalDeviceImageFormatProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600736 if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700737 return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600738 if (!strcmp(funcName, "vkGetPhysicalDeviceQueueFamilyProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700739 return (PFN_vkVoidFunction)vkGetPhysicalDeviceQueueFamilyProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600740 if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700741 return (PFN_vkVoidFunction)vkGetPhysicalDeviceMemoryProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600742 if (!strcmp(funcName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700743 return (PFN_vkVoidFunction)vkGetPhysicalDeviceSparseImageFormatProperties;
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600744 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700745 return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700746 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
747 return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties;
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600748 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700749 return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700750 if (!strcmp(funcName, "vkEnumerateInstanceDeviceProperties"))
751 return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600752
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700753 if (!instance)
754 return NULL;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700755
756 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
757
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600758 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
759 if (fptr)
760 return fptr;
761
762 {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700763 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600764 if (pTable->GetInstanceProcAddr == NULL)
765 return NULL;
766 return pTable->GetInstanceProcAddr(instance, funcName);
767 }
768}
Chia-I Wu16489ac2016-04-28 11:21:49 +0800769
770VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
771vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
772 return util_GetLayerProperties(ARRAY_SIZE(dl_global_layers), dl_global_layers, pCount, pProperties);
773}
774
775VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
776vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
777 return util_GetLayerProperties(ARRAY_SIZE(dl_global_layers), dl_global_layers, pCount, pProperties);
778}
779
780VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
781vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
782 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
783}