blob: 90c70349093fc6d2eebe290deb569ddcfebc0ddf [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
Chia-I Wu080cb7a2016-04-28 11:27:46 +080048namespace device_limits {
49
Tobin Ehlis9da65002015-09-24 15:25:16 -060050// This struct will be stored in a map hashed by the dispatchable object
Cody Northrop55443ef2015-09-28 15:09:32 -060051struct layer_data {
Jon Ashburn5484e0c2016-03-08 17:48:44 -070052 debug_report_data *report_data;
53 std::vector<VkDebugReportCallbackEXT> logging_callback;
54 VkLayerDispatchTable *device_dispatch_table;
55 VkLayerInstanceDispatchTable *instance_dispatch_table;
Tobin Ehlis9da65002015-09-24 15:25:16 -060056 // Track state of each instance
Jon Ashburn5484e0c2016-03-08 17:48:44 -070057 unique_ptr<INSTANCE_STATE> instanceState;
58 unique_ptr<PHYSICAL_DEVICE_STATE> physicalDeviceState;
59 VkPhysicalDeviceFeatures actualPhysicalDeviceFeatures;
60 VkPhysicalDeviceFeatures requestedPhysicalDeviceFeatures;
Mark Lobodzinski941aea92016-01-13 10:23:15 -070061
Tobin Ehlis1cb7f572015-10-06 09:09:24 -060062 // Track physical device per logical device
63 VkPhysicalDevice physicalDevice;
Dustin Gravesa97c3942016-03-31 18:01:37 -060064 VkPhysicalDeviceProperties physicalDeviceProperties;
Tobin Ehlis9da65002015-09-24 15:25:16 -060065 // Vector indices correspond to queueFamilyIndex
66 vector<unique_ptr<VkQueueFamilyProperties>> queueFamilyProperties;
Cody Northrop55443ef2015-09-28 15:09:32 -060067
Jon Ashburn5484e0c2016-03-08 17:48:44 -070068 layer_data()
69 : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), instanceState(nullptr),
70 physicalDeviceState(nullptr), actualPhysicalDeviceFeatures(), requestedPhysicalDeviceFeatures(), physicalDevice(){};
Cody Northrop55443ef2015-09-28 15:09:32 -060071};
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060072
Tobin Ehlis1cb7f572015-10-06 09:09:24 -060073static unordered_map<void *, layer_data *> layer_data_map;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060074
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070075// TODO : This can be much smarter, using separate locks for separate global data
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -060076static int globalLockInitialized = 0;
77static loader_platform_thread_mutex globalLock;
78
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
Chia-I Wucc0aa7a2016-04-28 14:12:27 +080096static const VkLayerProperties global_layer = {
Jon Ashburndc9111c2016-03-22 12:57:13 -060097 "VK_LAYER_LUNARG_device_limits", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer",
Chia-I Wucc0aa7a2016-04-28 14:12:27 +080098};
Tobin Ehlisfd3843f2015-09-29 12:26:00 -060099
Chia-I Wu99860202016-04-28 14:01:30 +0800100VKAPI_ATTR VkResult VKAPI_CALL
101CreateInstance(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 */
Chia-I Wu99860202016-04-28 14:01:30 +0800132VKAPI_ATTR void VKAPI_CALL
133DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600134 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600135 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
136 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800137 pTable->DestroyInstance(instance, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600138
139 // Clean up logging callback, if any
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600140 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700141 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700142 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchterd6fce632015-10-05 14:51:41 -0600143 my_data->logging_callback.pop_back();
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600144 }
145
146 layer_debug_report_destroy_instance(my_data->report_data);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600147 delete my_data->instance_dispatch_table;
148 layer_data_map.erase(key);
Tobin Ehlis0b632332015-10-07 09:38:40 -0600149 if (layer_data_map.empty()) {
150 // Release mutex when destroying last instance.
151 loader_platform_thread_delete_mutex(&globalLock);
152 globalLockInitialized = 0;
153 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600154}
155
Chia-I Wu99860202016-04-28 14:01:30 +0800156VKAPI_ATTR VkResult VKAPI_CALL
157EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) {
Dustin Graves080069b2016-04-05 13:48:15 -0600158 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700159 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600160 if (my_data->instanceState) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700161 // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600162 if (NULL == pPhysicalDevices) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700163 my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_COUNT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600164 } else {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700165 if (UNCALLED == my_data->instanceState->vkEnumeratePhysicalDevicesState) {
166 // Flag error here, shouldn't be calling this without having queried count
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700167 skipCall |=
168 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0,
169 __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
170 "Invalid call sequence to vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first "
171 "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700172 } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state
173 else if (my_data->instanceState->physicalDevicesCount != *pPhysicalDeviceCount) {
174 // 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 -0700175 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
176 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
177 "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count "
178 "supported by this instance is %u.",
179 *pPhysicalDeviceCount, my_data->instanceState->physicalDevicesCount);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600180 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700181 my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_DETAILS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600182 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600183 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700184 return VK_ERROR_VALIDATION_FAILED_EXT;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700185 VkResult result =
186 my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600187 if (NULL == pPhysicalDevices) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700188 my_data->instanceState->physicalDevicesCount = *pPhysicalDeviceCount;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600189 } else { // Save physical devices
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700190 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700191 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map);
192 phy_dev_data->physicalDeviceState = unique_ptr<PHYSICAL_DEVICE_STATE>(new PHYSICAL_DEVICE_STATE());
Tobin Ehlis9da65002015-09-24 15:25:16 -0600193 // Init actual features for each physical device
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700194 my_data->instance_dispatch_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i],
195 &(phy_dev_data->actualPhysicalDeviceFeatures));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600196 }
197 }
198 return result;
199 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700200 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
201 DEVLIMITS_INVALID_INSTANCE, "DL", "Invalid instance (%#" PRIxLEAST64 ") passed into vkEnumeratePhysicalDevices().",
202 (uint64_t)instance);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600203 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700204 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600205}
206
Chia-I Wu99860202016-04-28 14:01:30 +0800207VKAPI_ATTR void VKAPI_CALL
208GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700209 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
210 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState = QUERY_DETAILS;
211 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600212}
213
Chia-I Wu99860202016-04-28 14:01:30 +0800214VKAPI_ATTR void VKAPI_CALL
215GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700216 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
217 ->instance_dispatch_table->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600218}
219
Chia-I Wu99860202016-04-28 14:01:30 +0800220VKAPI_ATTR VkResult VKAPI_CALL
221GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
222 VkImageUsageFlags usage, VkImageCreateFlags flags,
223 VkImageFormatProperties *pImageFormatProperties) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700224 return get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
225 ->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
226 pImageFormatProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600227}
228
Chia-I Wu99860202016-04-28 14:01:30 +0800229VKAPI_ATTR void VKAPI_CALL
230GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700231 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
232 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600233}
234
Chia-I Wu99860202016-04-28 14:01:30 +0800235VKAPI_ATTR void VKAPI_CALL
236GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
237 VkQueueFamilyProperties *pQueueFamilyProperties) {
Dustin Graves080069b2016-04-05 13:48:15 -0600238 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700239 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600240 if (phy_dev_data->physicalDeviceState) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600241 if (NULL == pQueueFamilyProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700242 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600243 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700244 // Verify that for each physical device, this function is called first with NULL pQueueFamilyProperties ptr in order to
245 // get count
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700246 if (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700247 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
248 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
249 "Invalid call sequence to vkGetPhysicalDeviceQueueFamilyProperties() w/ non-NULL "
250 "pQueueFamilyProperties. You should first call vkGetPhysicalDeviceQueueFamilyProperties() w/ "
251 "NULL pQueueFamilyProperties to query pCount.");
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600252 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700253 // Then verify that pCount that is passed in on second call matches what was returned
254 if (phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount != *pCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700255
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700256 // TODO: this is not a requirement of the Valid Usage section for vkGetPhysicalDeviceQueueFamilyProperties, so
257 // provide as warning
258 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
259 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
260 "Call to vkGetPhysicalDeviceQueueFamilyProperties() w/ pCount value %u, but actual count "
261 "supported by this physicalDevice is %u.",
262 *pCount, phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600263 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700264 phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600265 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600266 if (skipCall)
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600267 return;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700268 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount,
269 pQueueFamilyProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600270 if (NULL == pQueueFamilyProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700271 phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount = *pCount;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600272 } else { // Save queue family properties
Tobin Ehlis9da65002015-09-24 15:25:16 -0600273 phy_dev_data->queueFamilyProperties.reserve(*pCount);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700274 for (uint32_t i = 0; i < *pCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700275 phy_dev_data->queueFamilyProperties.emplace_back(new VkQueueFamilyProperties(pQueueFamilyProperties[i]));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600276 }
277 }
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600278 return;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600279 } else {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700280 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
281 __LINE__, DEVLIMITS_INVALID_PHYSICAL_DEVICE, "DL",
282 "Invalid physicalDevice (%#" PRIxLEAST64 ") passed into vkGetPhysicalDeviceQueueFamilyProperties().",
283 (uint64_t)physicalDevice);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600284 }
285}
286
Chia-I Wu99860202016-04-28 14:01:30 +0800287VKAPI_ATTR void VKAPI_CALL
288GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700289 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
290 ->instance_dispatch_table->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600291}
292
Chia-I Wu99860202016-04-28 14:01:30 +0800293VKAPI_ATTR void VKAPI_CALL
294GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
295 VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling,
296 uint32_t *pNumProperties, VkSparseImageFormatProperties *pProperties) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700297 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
298 ->instance_dispatch_table->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage,
299 tiling, pNumProperties, pProperties);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600300}
301
Chia-I Wu99860202016-04-28 14:01:30 +0800302VKAPI_ATTR void VKAPI_CALL
303CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) {
Dustin Graves080069b2016-04-05 13:48:15 -0600304 bool skipCall = false;
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600305 /* TODO: Verify viewportCount < maxViewports from VkPhysicalDeviceLimits */
Dustin Graves080069b2016-04-05 13:48:15 -0600306 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700307 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
308 my_data->device_dispatch_table->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600309 }
310}
311
Chia-I Wu99860202016-04-28 14:01:30 +0800312VKAPI_ATTR void VKAPI_CALL
313CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) {
Dustin Graves080069b2016-04-05 13:48:15 -0600314 bool skipCall = false;
Courtney Goeltzenleuchter078f8172015-09-21 11:44:06 -0600315 /* TODO: Verify scissorCount < maxViewports from VkPhysicalDeviceLimits */
316 /* TODO: viewportCount and scissorCount must match at draw time */
Dustin Graves080069b2016-04-05 13:48:15 -0600317 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700318 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
319 my_data->device_dispatch_table->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
Courtney Goeltzenleuchter49c73082015-09-17 15:06:17 -0600320 }
321}
322
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700323// Verify that features have been queried and verify that requested features are available
Dustin Graves080069b2016-04-05 13:48:15 -0600324static bool validate_features_request(layer_data *phy_dev_data) {
325 bool skipCall = false;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600326 // Verify that all of the requested features are available
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700327 // 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 -0700328 VkBool32 *actual = (VkBool32 *)&(phy_dev_data->actualPhysicalDeviceFeatures);
329 VkBool32 *requested = (VkBool32 *)&(phy_dev_data->requestedPhysicalDeviceFeatures);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700330 // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues
331 // Need to provide the struct member name with the issue. To do that seems like we'll
332 // have to loop through each struct member which should be done w/ codegen to keep in synch.
Tobin Ehlis9da65002015-09-24 15:25:16 -0600333 uint32_t errors = 0;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700334 uint32_t totalBools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600335 for (uint32_t i = 0; i < totalBools; i++) {
336 if (requested[i] > actual[i]) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700337 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
338 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED,
339 "DL", "While calling vkCreateDevice(), requesting feature #%u in VkPhysicalDeviceFeatures struct, "
340 "which is not available on this device.",
341 i);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600342 errors++;
343 }
344 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700345 if (errors && (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState)) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600346 // If user didn't request features, notify them that they should
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700347 // 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 -0700348 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
349 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
350 "You requested features that are unavailable on this device. You should first query feature "
351 "availability by calling vkGetPhysicalDeviceFeatures().");
Tobin Ehlis9da65002015-09-24 15:25:16 -0600352 }
Tobin Ehlis72b27cc2015-09-29 11:22:37 -0600353 return skipCall;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600354}
355
Chia-I Wu99860202016-04-28 14:01:30 +0800356VKAPI_ATTR VkResult VKAPI_CALL
357CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
358 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Dustin Graves080069b2016-04-05 13:48:15 -0600359 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700360 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600361 // First check is app has actually requested queueFamilyProperties
Tobin Ehlis9da65002015-09-24 15:25:16 -0600362 if (!phy_dev_data->physicalDeviceState) {
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_MUST_QUERY_COUNT, "DL",
365 "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices().");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700366 } else if (QUERY_DETAILS != phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
367 // 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 -0700368 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
369 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
370 "DL", "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties().");
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600371 } else {
372 // Check that the requested queue properties are valid
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700373 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700374 uint32_t requestedIndex = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700375 if (phy_dev_data->queueFamilyProperties.size() <=
376 requestedIndex) { // requested index is out of bounds for this physical device
377 skipCall |= log_msg(
378 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
379 __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700380 "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested.", requestedIndex);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700381 } else if (pCreateInfo->pQueueCreateInfos[i].queueCount >
382 phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount) {
383 skipCall |=
384 log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
385 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
386 "DL", "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but "
387 "requested queueCount is %u.",
388 requestedIndex, phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount,
389 pCreateInfo->pQueueCreateInfos[i].queueCount);
Tobin Ehlis54a6c182015-09-22 14:00:58 -0600390 }
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600391 }
392 }
Tobin Ehlis9da65002015-09-24 15:25:16 -0600393 // Check that any requested features are available
394 if (pCreateInfo->pEnabledFeatures) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700395 phy_dev_data->requestedPhysicalDeviceFeatures = *(pCreateInfo->pEnabledFeatures);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600396 skipCall |= validate_features_request(phy_dev_data);
397 }
398 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700399 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis9da65002015-09-24 15:25:16 -0600400
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700401 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700402
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700403 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700404 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
405 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700406 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700407 if (fpCreateDevice == NULL) {
408 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600409 }
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700410
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700411 // Advance the link info for the next element on the chain
412 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
413
414 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
415 if (result != VK_SUCCESS) {
416 return result;
417 }
418
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700419 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700420 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700421 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
Dustin Gravesa97c3942016-03-31 18:01:37 -0600422 my_device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700423 my_device_data->physicalDevice = gpu;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700424
425 // Get physical device properties for this device
Dustin Gravesa97c3942016-03-31 18:01:37 -0600426 phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_device_data->physicalDeviceProperties));
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600427 return result;
428}
429
Chia-I Wu99860202016-04-28 14:01:30 +0800430VKAPI_ATTR void VKAPI_CALL
431DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600432 // Free device lifetime allocations
433 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600434 layer_data *my_device_data = get_my_data_ptr(key, layer_data_map);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800435 my_device_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600436 delete my_device_data->device_dispatch_table;
437 layer_data_map.erase(key);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600438}
439
Chia-I Wu99860202016-04-28 14:01:30 +0800440VKAPI_ATTR VkResult VKAPI_CALL
441CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
442 const VkAllocationCallbacks *pAllocator,
443 VkRenderPass *pRenderPass) {
Michael Lentine20e4c192016-04-06 17:40:22 -0500444 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
445 bool skip_call = false;
446 uint32_t max_color_attachments = dev_data->physicalDeviceProperties.limits.maxColorAttachments;
447 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
448 if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) {
449 skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
450 reinterpret_cast<uint64_t>(device), __LINE__, DEVLIMITS_INVALID_ATTACHMENT_COUNT, "DL",
451 "Cannot create a render pass with %d color attachments. Max is %d.",
452 pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments);
453 }
454 }
455 if (skip_call) {
456 return VK_ERROR_VALIDATION_FAILED_EXT;
457 }
458 return dev_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
459}
460
Chia-I Wu99860202016-04-28 14:01:30 +0800461VKAPI_ATTR VkResult VKAPI_CALL
462CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
463 const VkAllocationCallbacks *pAllocator,
464 VkCommandPool *pCommandPool) {
Tobin Ehlis9da65002015-09-24 15:25:16 -0600465 // TODO : Verify that requested QueueFamilyIndex for this pool exists
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700466 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
467 ->device_dispatch_table->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600468 return result;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600469}
470
Chia-I Wu99860202016-04-28 14:01:30 +0800471VKAPI_ATTR void VKAPI_CALL
472DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700473 get_my_data_ptr(get_dispatch_key(device), layer_data_map)
474 ->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600475}
476
Chia-I Wu99860202016-04-28 14:01:30 +0800477VKAPI_ATTR VkResult VKAPI_CALL
478ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700479 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
480 ->device_dispatch_table->ResetCommandPool(device, commandPool, flags);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600481 return result;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600482}
483
Chia-I Wu99860202016-04-28 14:01:30 +0800484VKAPI_ATTR VkResult VKAPI_CALL
485AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo, VkCommandBuffer *pCommandBuffer) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700486 VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
487 ->device_dispatch_table->AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer);
Tobin Ehlis9da65002015-09-24 15:25:16 -0600488 return result;
489}
Mark Lobodzinskifbb130e2015-10-06 11:59:54 -0600490
Chia-I Wu99860202016-04-28 14:01:30 +0800491VKAPI_ATTR void VKAPI_CALL
492FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t count, const VkCommandBuffer *pCommandBuffers) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700493 get_my_data_ptr(get_dispatch_key(device), layer_data_map)
494 ->device_dispatch_table->FreeCommandBuffers(device, commandPool, count, pCommandBuffers);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600495}
496
Chia-I Wu99860202016-04-28 14:01:30 +0800497VKAPI_ATTR VkResult VKAPI_CALL
498BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
Michael Lentine09853ef2016-01-28 14:20:46 -0600499 bool skipCall = false;
500 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Tony Barboure24b8e32016-03-25 13:04:20 -0600501 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 -0600502 const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
Tony Barboure24b8e32016-03-25 13:04:20 -0600503 if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries == VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700504 skipCall |= log_msg(
505 dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
506 reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL",
507 "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support inheritedQueries.");
Michael Lentine09853ef2016-01-28 14:20:46 -0600508 }
Tony Barboure24b8e32016-03-25 13:04:20 -0600509 if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries != VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE &&
Michael Lentine5d8ad0a2016-01-28 15:03:46 -0600510 !validate_VkQueryControlFlagBits(VkQueryControlFlagBits(pInfo->queryFlags))) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700511 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
512 reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL",
513 "Cannot enable in occlusion queries in vkBeginCommandBuffer() and set queryFlags to %d which is not a "
514 "valid combination of VkQueryControlFlagBits.",
Michael Lentine5d8ad0a2016-01-28 15:03:46 -0600515 pInfo->queryFlags);
516 }
Michael Lentine0a369f62016-02-03 16:51:46 -0600517 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Michael Lentine09853ef2016-01-28 14:20:46 -0600518 if (!skipCall)
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700519 result = dev_data->device_dispatch_table->BeginCommandBuffer(commandBuffer, pBeginInfo);
Michael Lentine0a369f62016-02-03 16:51:46 -0600520 return result;
Michael Lentine09853ef2016-01-28 14:20:46 -0600521}
522
Chia-I Wu99860202016-04-28 14:01:30 +0800523VKAPI_ATTR void VKAPI_CALL
524GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
Dustin Graves080069b2016-04-05 13:48:15 -0600525 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700526 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600527 VkPhysicalDevice gpu = dev_data->physicalDevice;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700528 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700529 if (queueFamilyIndex >=
530 phy_dev_data->queueFamilyProperties.size()) { // requested index is out of bounds for this physical device
531 skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
532 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
533 "DL", "Invalid queueFamilyIndex %u requested in vkGetDeviceQueue().", queueFamilyIndex);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700534 } else if (queueIndex >= phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700535 skipCall |= log_msg(
536 phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
537 DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
538 "Invalid queue request in vkGetDeviceQueue(). QueueFamilyIndex %u only has %u queues, but requested queueIndex is %u.",
539 queueFamilyIndex, phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount, queueIndex);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600540 }
Dustin Graves080069b2016-04-05 13:48:15 -0600541 if (!skipCall)
542 dev_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600543}
544
Chia-I Wu99860202016-04-28 14:01:30 +0800545VKAPI_ATTR void VKAPI_CALL
546UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites,
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700547 uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) {
548 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Dustin Graves080069b2016-04-05 13:48:15 -0600549 bool skipCall = false;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700550
Mark Youngee3f3a22016-01-25 12:18:32 -0700551 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700552 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
553 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
Dustin Gravesa97c3942016-03-31 18:01:37 -0600554 VkDeviceSize uniformAlignment = dev_data->physicalDeviceProperties.limits.minUniformBufferOffsetAlignment;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700555 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
556 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700557 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
558 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
559 DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, "DL",
560 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (%#" PRIxLEAST64
561 ") must be a multiple of device limit minUniformBufferOffsetAlignment %#" PRIxLEAST64,
562 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700563 }
564 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700565 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
566 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Dustin Gravesa97c3942016-03-31 18:01:37 -0600567 VkDeviceSize storageAlignment = dev_data->physicalDeviceProperties.limits.minStorageBufferOffsetAlignment;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700568 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
569 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700570 skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
571 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
572 DEVLIMITS_INVALID_STORAGE_BUFFER_OFFSET, "DL",
573 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (%#" PRIxLEAST64
574 ") must be a multiple of device limit minStorageBufferOffsetAlignment %#" PRIxLEAST64,
575 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700576 }
577 }
578 }
579 }
Dustin Graves080069b2016-04-05 13:48:15 -0600580 if (!skipCall) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700581 dev_data->device_dispatch_table->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
582 pDescriptorCopies);
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700583 }
584}
585
Chia-I Wu99860202016-04-28 14:01:30 +0800586VKAPI_ATTR void VKAPI_CALL
587CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
588 VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700589 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyana3082432015-09-25 13:39:21 -0600590
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700591 // 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 +0800592 if (dstOffset & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700593 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200594 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
595 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700596 "vkCmdUpdateBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600597 return;
598 }
599 }
600
601 // dataSize is the number of bytes to update, which must be a multiple of 4.
602 if (dataSize & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700603 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200604 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
605 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700606 "vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600607 return;
608 }
609 }
610
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700611 dev_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
Mike Stroyana3082432015-09-25 13:39:21 -0600612}
613
Chia-I Wu99860202016-04-28 14:01:30 +0800614VKAPI_ATTR void VKAPI_CALL
615CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700616 layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyana3082432015-09-25 13:39:21 -0600617
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700618 // 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 +0800619 if (dstOffset & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700620 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200621 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
622 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700623 "vkCmdFillBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600624 return;
625 }
626 }
627
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800628 // size is the number of bytes to fill, which must be a multiple of 4.
629 if (size & 3) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700630 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chris Forbes45501682016-04-07 12:00:33 +1200631 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
632 DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700633 "vkCmdFillBuffer parameter, VkDeviceSize size, is not a multiple of 4")) {
Mike Stroyana3082432015-09-25 13:39:21 -0600634 return;
635 }
636 }
637
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700638 dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
Mike Stroyana3082432015-09-25 13:39:21 -0600639}
640
Chia-I Wu99860202016-04-28 14:01:30 +0800641VKAPI_ATTR VkResult VKAPI_CALL
642CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
643 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700644 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
645 VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600646 if (VK_SUCCESS == res) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700647 res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600648 }
649 return res;
650}
651
Chia-I Wu99860202016-04-28 14:01:30 +0800652VKAPI_ATTR void VKAPI_CALL
653DestroyDebugReportCallbackEXT(VkInstance instance,
654 VkDebugReportCallbackEXT msgCallback,
655 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700656 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
657 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700658 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600659}
660
Chia-I Wu99860202016-04-28 14:01:30 +0800661VKAPI_ATTR void VKAPI_CALL
662DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
663 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700664 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700665 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
666 pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700667}
668
Chia-I Wu99860202016-04-28 14:01:30 +0800669VKAPI_ATTR VkResult VKAPI_CALL
670EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
671 const char *pLayerName, uint32_t *pCount,
672 VkExtensionProperties *pProperties) {
Chia-I Wu16489ac2016-04-28 11:21:49 +0800673 if (pLayerName == NULL) {
674 dispatch_key key = get_dispatch_key(physicalDevice);
675 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
676 return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
677 } else {
678 return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
679 }
680}
681
Chia-I Wu99860202016-04-28 14:01:30 +0800682VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
683GetDeviceProcAddr(VkDevice dev, const char *funcName) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700684 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Chia-I Wu99860202016-04-28 14:01:30 +0800685 return (PFN_vkVoidFunction)GetDeviceProcAddr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600686 if (!strcmp(funcName, "vkDestroyDevice"))
Chia-I Wu99860202016-04-28 14:01:30 +0800687 return (PFN_vkVoidFunction)DestroyDevice;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600688 if (!strcmp(funcName, "vkGetDeviceQueue"))
Chia-I Wu99860202016-04-28 14:01:30 +0800689 return (PFN_vkVoidFunction)GetDeviceQueue;
Michael Lentine20e4c192016-04-06 17:40:22 -0500690 if (!strcmp(funcName, "vkCreateRenderPass"))
Chia-I Wu99860202016-04-28 14:01:30 +0800691 return (PFN_vkVoidFunction)CreateRenderPass;
Michael Lentine20e4c192016-04-06 17:40:22 -0500692 if (!strcmp(funcName, "vkCreateCommandPool"))
Chia-I Wu99860202016-04-28 14:01:30 +0800693 return (PFN_vkVoidFunction)CreateCommandPool;
Michael Lentine20e4c192016-04-06 17:40:22 -0500694 if (!strcmp(funcName, "vkDestroyCommandPool"))
Chia-I Wu99860202016-04-28 14:01:30 +0800695 return (PFN_vkVoidFunction)DestroyCommandPool;
Michael Lentine20e4c192016-04-06 17:40:22 -0500696 if (!strcmp(funcName, "vkResetCommandPool"))
Chia-I Wu99860202016-04-28 14:01:30 +0800697 return (PFN_vkVoidFunction)ResetCommandPool;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800698 if (!strcmp(funcName, "vkAllocateCommandBuffers"))
Chia-I Wu99860202016-04-28 14:01:30 +0800699 return (PFN_vkVoidFunction)AllocateCommandBuffers;
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600700 if (!strcmp(funcName, "vkFreeCommandBuffers"))
Chia-I Wu99860202016-04-28 14:01:30 +0800701 return (PFN_vkVoidFunction)FreeCommandBuffers;
Michael Lentine09853ef2016-01-28 14:20:46 -0600702 if (!strcmp(funcName, "vkBeginCommandBuffer"))
Chia-I Wu99860202016-04-28 14:01:30 +0800703 return (PFN_vkVoidFunction)BeginCommandBuffer;
Mike Stroyana3082432015-09-25 13:39:21 -0600704 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Chia-I Wu99860202016-04-28 14:01:30 +0800705 return (PFN_vkVoidFunction)CmdUpdateBuffer;
Mark Lobodzinski941aea92016-01-13 10:23:15 -0700706 if (!strcmp(funcName, "vkUpdateDescriptorSets"))
Chia-I Wu99860202016-04-28 14:01:30 +0800707 return (PFN_vkVoidFunction)UpdateDescriptorSets;
Mike Stroyana3082432015-09-25 13:39:21 -0600708 if (!strcmp(funcName, "vkCmdFillBuffer"))
Chia-I Wu99860202016-04-28 14:01:30 +0800709 return (PFN_vkVoidFunction)CmdFillBuffer;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600710
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700711 if (dev == NULL)
712 return NULL;
713
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700714 layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700715 VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600716 {
717 if (pTable->GetDeviceProcAddr == NULL)
718 return NULL;
719 return pTable->GetDeviceProcAddr(dev, funcName);
720 }
721}
722
Chia-I Wu99860202016-04-28 14:01:30 +0800723VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
724GetInstanceProcAddr(VkInstance instance, const char *funcName) {
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600725 PFN_vkVoidFunction fptr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600726
Tobin Ehlis1cb7f572015-10-06 09:09:24 -0600727 layer_data *my_data;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700728 if (!strcmp(funcName, "vkGetInstanceProcAddr"))
Chia-I Wu99860202016-04-28 14:01:30 +0800729 return (PFN_vkVoidFunction)GetInstanceProcAddr;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700730 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Chia-I Wu99860202016-04-28 14:01:30 +0800731 return (PFN_vkVoidFunction)GetDeviceProcAddr;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600732 if (!strcmp(funcName, "vkCreateInstance"))
Chia-I Wu99860202016-04-28 14:01:30 +0800733 return (PFN_vkVoidFunction)CreateInstance;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600734 if (!strcmp(funcName, "vkDestroyInstance"))
Chia-I Wu99860202016-04-28 14:01:30 +0800735 return (PFN_vkVoidFunction)DestroyInstance;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700736 if (!strcmp(funcName, "vkCreateDevice"))
Chia-I Wu99860202016-04-28 14:01:30 +0800737 return (PFN_vkVoidFunction)CreateDevice;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600738 if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
Chia-I Wu99860202016-04-28 14:01:30 +0800739 return (PFN_vkVoidFunction)EnumeratePhysicalDevices;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600740 if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures"))
Chia-I Wu99860202016-04-28 14:01:30 +0800741 return (PFN_vkVoidFunction)GetPhysicalDeviceFeatures;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600742 if (!strcmp(funcName, "vkGetPhysicalDeviceFormatProperties"))
Chia-I Wu99860202016-04-28 14:01:30 +0800743 return (PFN_vkVoidFunction)GetPhysicalDeviceFormatProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600744 if (!strcmp(funcName, "vkGetPhysicalDeviceImageFormatProperties"))
Chia-I Wu99860202016-04-28 14:01:30 +0800745 return (PFN_vkVoidFunction)GetPhysicalDeviceImageFormatProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600746 if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
Chia-I Wu99860202016-04-28 14:01:30 +0800747 return (PFN_vkVoidFunction)GetPhysicalDeviceProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600748 if (!strcmp(funcName, "vkGetPhysicalDeviceQueueFamilyProperties"))
Chia-I Wu99860202016-04-28 14:01:30 +0800749 return (PFN_vkVoidFunction)GetPhysicalDeviceQueueFamilyProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600750 if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
Chia-I Wu99860202016-04-28 14:01:30 +0800751 return (PFN_vkVoidFunction)GetPhysicalDeviceMemoryProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600752 if (!strcmp(funcName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
Chia-I Wu99860202016-04-28 14:01:30 +0800753 return (PFN_vkVoidFunction)GetPhysicalDeviceSparseImageFormatProperties;
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600754 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700755 return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700756 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
757 return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties;
Tobin Ehlisfd3843f2015-09-29 12:26:00 -0600758 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700759 return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
Courtney Goeltzenleuchterbeb42f82016-02-12 13:46:04 -0700760 if (!strcmp(funcName, "vkEnumerateInstanceDeviceProperties"))
Chia-I Wu99860202016-04-28 14:01:30 +0800761 return (PFN_vkVoidFunction)EnumerateDeviceExtensionProperties;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600762
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700763 if (!instance)
764 return NULL;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700765
766 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
767
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600768 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
769 if (fptr)
770 return fptr;
771
772 {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700773 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Tobin Ehlisb5fc4fb2015-09-03 09:50:06 -0600774 if (pTable->GetInstanceProcAddr == NULL)
775 return NULL;
776 return pTable->GetInstanceProcAddr(instance, funcName);
777 }
778}
Chia-I Wu16489ac2016-04-28 11:21:49 +0800779
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800780} // namespace device_limits
781
782// vk_layer_logging.h expects these to be defined
783
Chia-I Wu99860202016-04-28 14:01:30 +0800784VKAPI_ATTR VkResult VKAPI_CALL
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800785vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
786 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Chia-I Wu99860202016-04-28 14:01:30 +0800787 return device_limits::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800788}
789
Chia-I Wu99860202016-04-28 14:01:30 +0800790VKAPI_ATTR void VKAPI_CALL
791vkDestroyDebugReportCallbackEXT(VkInstance instance,
792 VkDebugReportCallbackEXT msgCallback,
793 const VkAllocationCallbacks *pAllocator) {
794 device_limits::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800795}
796
Chia-I Wu99860202016-04-28 14:01:30 +0800797VKAPI_ATTR void VKAPI_CALL
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800798vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
799 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Chia-I Wu99860202016-04-28 14:01:30 +0800800 device_limits::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800801}
802
803// loader-layer interface v0
804
Chia-I Wu16489ac2016-04-28 11:21:49 +0800805VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
806vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
Chia-I Wucc0aa7a2016-04-28 14:12:27 +0800807 return util_GetLayerProperties(1, &device_limits::global_layer, pCount, pProperties);
Chia-I Wu16489ac2016-04-28 11:21:49 +0800808}
809
810VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
811vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
Chia-I Wucc0aa7a2016-04-28 14:12:27 +0800812 return util_GetLayerProperties(1, &device_limits::global_layer, pCount, pProperties);
Chia-I Wu16489ac2016-04-28 11:21:49 +0800813}
814
815VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
816vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800817 return util_GetExtensionProperties(1, device_limits::instance_extensions, pCount, pProperties);
818}
819
820VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
821 const char *pLayerName, uint32_t *pCount,
822 VkExtensionProperties *pProperties) {
Chia-I Wu99860202016-04-28 14:01:30 +0800823 return device_limits::EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800824}
825
826VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
Chia-I Wu99860202016-04-28 14:01:30 +0800827 return device_limits::GetDeviceProcAddr(dev, funcName);
Chia-I Wu080cb7a2016-04-28 11:27:46 +0800828}
829
830VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
Chia-I Wu99860202016-04-28 14:01:30 +0800831 return device_limits::GetInstanceProcAddr(instance, funcName);
Chia-I Wu16489ac2016-04-28 11:21:49 +0800832}