111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Copyright (c) 2015-2016 The Khronos Group Inc. 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 Valve Corporation 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 LunarG, Inc. 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (C) 2015-2016 Google Inc. 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Licensed under the Apache License, Version 2.0 (the "License"); 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * you may not use this file except in compliance with the License. 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * You may obtain a copy of the License at 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * http://www.apache.org/licenses/LICENSE-2.0 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Unless required by applicable law or agreed to in writing, software 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * distributed under the License is distributed on an "AS IS" BASIS, 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * See the License for the specific language governing permissions and 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * limitations under the License. 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Mark Lobodzinski <mark@lunarg.com> 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Mike Stroyan <mike@LunarG.com> 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Tobin Ehlis <tobin@lunarg.com> 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <stdio.h> 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <stdlib.h> 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <string.h> 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <unordered_map> 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <memory> 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_loader_platform.h" 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_dispatch_table_helper.h" 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(__GNUC__) 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#pragma GCC diagnostic ignored "-Wwrite-strings" 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(__GNUC__) 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#pragma GCC diagnostic warning "-Wwrite-strings" 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_struct_size_helper.h" 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "device_limits.h" 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vulkan/vk_layer.h" 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_config.h" 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_enum_validate_helper.h" 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_table.h" 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_data.h" 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_logging.h" 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_extension_utils.h" 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_utils.h" 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace device_limits { 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This struct will be stored in a map hashed by the dispatchable object 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct layer_data { 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkInstance instance; 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert debug_report_data *report_data; 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::vector<VkDebugReportCallbackEXT> logging_callback; 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerDispatchTable *device_dispatch_table; 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerInstanceDispatchTable *instance_dispatch_table; 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Track state of each instance 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unique_ptr<INSTANCE_STATE> instanceState; 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unique_ptr<PHYSICAL_DEVICE_STATE> physicalDeviceState; 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkPhysicalDeviceFeatures actualPhysicalDeviceFeatures; 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkPhysicalDeviceFeatures requestedPhysicalDeviceFeatures; 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Track physical device per logical device 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkPhysicalDevice physicalDevice; 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkPhysicalDeviceProperties physicalDeviceProperties; 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Vector indices correspond to queueFamilyIndex 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vector<unique_ptr<VkQueueFamilyProperties>> queueFamilyProperties; 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data() 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), instanceState(nullptr), 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert physicalDeviceState(nullptr), actualPhysicalDeviceFeatures(), requestedPhysicalDeviceFeatures(), physicalDevice(){}; 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic unordered_map<void *, layer_data *> layer_data_map; 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// TODO : This can be much smarter, using separate locks for separate global data 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic int globalLockInitialized = 0; 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic loader_platform_thread_mutex globalLock; 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic void init_device_limits(layer_data *my_data, const VkAllocationCallbacks *pAllocator) { 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_device_limits"); 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!globalLockInitialized) { 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO/TBD: Need to delete this mutex sometime. How??? One 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // suggestion is to call this during vkCreateInstance(), and then we 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // can clean it up during vkDestroyInstance(). However, that requires 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // that the layer have per-instance locks. We need to come back and 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // address this soon. 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loader_platform_thread_create_mutex(&globalLock); 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert globalLockInitialized = 1; 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const VkLayerProperties global_layer = { 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_LAYER_LUNARG_device_limits", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer", 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 10311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(chain_info->u.pLayerInfo); 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (fpCreateInstance == NULL) { 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_INITIALIZATION_FAILED; 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Advance the link info for the next element on the chain 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (result != VK_SUCCESS) 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance = *pInstance; 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance, 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert init_device_limits(my_data, pAllocator); 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE()); 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_SUCCESS; 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* hook DestroyInstance to remove tableInstanceMap entry */ 13511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 13611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_key key = get_dispatch_key(instance); 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(key, layer_data_map); 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pTable->DestroyInstance(instance, pAllocator); 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Clean up logging callback, if any 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert while (my_data->logging_callback.size() > 0) { 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDebugReportCallbackEXT callback = my_data->logging_callback.back(); 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_destroy_msg_callback(my_data->report_data, callback, pAllocator); 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->logging_callback.pop_back(); 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_debug_report_destroy_instance(my_data->report_data); 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert delete my_data->instance_dispatch_table; 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data_map.erase(key); 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (layer_data_map.empty()) { 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Release mutex when destroying last instance. 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loader_platform_thread_delete_mutex(&globalLock); 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert globalLockInitialized = 0; 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 16011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) { 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (my_data->instanceState) { 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (NULL == pPhysicalDevices) { 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_COUNT; 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (UNCALLED == my_data->instanceState->vkEnumeratePhysicalDevicesState) { 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Flag error here, shouldn't be calling this without having queried count 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Invalid call sequence to vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first " 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount."); 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (my_data->instanceState->physicalDevicesCount != *pPhysicalDeviceCount) { 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO: Having actual count match count from app is not a requirement, so this can be a warning 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count " 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "supported by this instance is %u.", 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *pPhysicalDeviceCount, my_data->instanceState->physicalDevicesCount); 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_DETAILS; 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (skipCall) 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (NULL == pPhysicalDevices) { 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceState->physicalDevicesCount = *pPhysicalDeviceCount; 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { // Save physical devices 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) { 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map); 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->physicalDeviceState = unique_ptr<PHYSICAL_DEVICE_STATE>(new PHYSICAL_DEVICE_STATE()); 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Init actual features for each physical device 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i], 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert &(phy_dev_data->actualPhysicalDeviceFeatures)); 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__, 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DEVLIMITS_INVALID_INSTANCE, "DL", "Invalid instance (0x%" PRIxLEAST64 ") passed into vkEnumeratePhysicalDevices().", 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (uint64_t)instance); 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 21111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) { 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState = QUERY_DETAILS; 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFeatures(physicalDevice, pFeatures); 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 21811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) { 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map) 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->instance_dispatch_table->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties); 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 22411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkImageUsageFlags usage, VkImageCreateFlags flags, 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkImageFormatProperties *pImageFormatProperties) { 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map) 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pImageFormatProperties); 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 23311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) { 23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties); 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 23911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, 24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkQueueFamilyProperties *pQueueFamilyProperties) { 24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (phy_dev_data->physicalDeviceState) { 24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (NULL == pQueueFamilyProperties) { 24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT; 24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Verify that for each physical device, this function is called first with NULL pQueueFamilyProperties ptr in order to 24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // get count 24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) { 25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Invalid call sequence to vkGetPhysicalDeviceQueueFamilyProperties() w/ non-NULL " 25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pQueueFamilyProperties. You should first call vkGetPhysicalDeviceQueueFamilyProperties() w/ " 25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "NULL pQueueFamilyProperties to query pCount."); 25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Then verify that pCount that is passed in on second call matches what was returned 25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount != *pCount) { 25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO: this is not a requirement of the Valid Usage section for vkGetPhysicalDeviceQueueFamilyProperties, so 26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // provide as warning 26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", 26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Call to vkGetPhysicalDeviceQueueFamilyProperties() w/ pCount value %u, but actual count " 26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "supported by this physicalDevice is %u.", 26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *pCount, phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount); 26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS; 26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (skipCall) 27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return; 27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount, 27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pQueueFamilyProperties); 27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (NULL == pQueueFamilyProperties) { 27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount = *pCount; 27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { // Save queue family properties 27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->queueFamilyProperties.reserve(*pCount); 27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < *pCount; i++) { 27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->queueFamilyProperties.emplace_back(new VkQueueFamilyProperties(pQueueFamilyProperties[i])); 27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return; 28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, 28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __LINE__, DEVLIMITS_INVALID_PHYSICAL_DEVICE, "DL", 28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Invalid physicalDevice (0x%" PRIxLEAST64 ") passed into vkGetPhysicalDeviceQueueFamilyProperties().", 28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (uint64_t)physicalDevice); 28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 29111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) { 29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map) 29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->instance_dispatch_table->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties); 29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 29711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, 29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, 29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t *pNumProperties, VkSparseImageFormatProperties *pProperties) { 30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map) 30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->instance_dispatch_table->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, 30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert tiling, pNumProperties, pProperties); 30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 30611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) { 30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /* TODO: Verify viewportCount < maxViewports from VkPhysicalDeviceLimits */ 30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->device_dispatch_table->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports); 31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 31611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) { 31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /* TODO: Verify scissorCount < maxViewports from VkPhysicalDeviceLimits */ 31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /* TODO: viewportCount and scissorCount must match at draw time */ 32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->device_dispatch_table->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors); 32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Verify that features have been queried and verify that requested features are available 32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic bool validate_features_request(layer_data *phy_dev_data) { 32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Verify that all of the requested features are available 33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Get ptrs into actual and requested structs and if requested is 1 but actual is 0, request is invalid 33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkBool32 *actual = (VkBool32 *)&(phy_dev_data->actualPhysicalDeviceFeatures); 33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkBool32 *requested = (VkBool32 *)&(phy_dev_data->requestedPhysicalDeviceFeatures); 33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues 33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Need to provide the struct member name with the issue. To do that seems like we'll 33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // have to loop through each struct member which should be done w/ codegen to keep in synch. 33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t errors = 0; 33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t totalBools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); 33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < totalBools; i++) { 33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (requested[i] > actual[i]) { 34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, 34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "DL", "While calling vkCreateDevice(), requesting feature #%u in VkPhysicalDeviceFeatures struct, " 34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "which is not available on this device.", 34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert i); 34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert errors++; 34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (errors && (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState)) { 34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // If user didn't request features, notify them that they should 35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO: Verify this against the spec. I believe this is an invalid use of the API and should return an error 35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL", 35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "You requested features that are unavailable on this device. You should first query feature " 35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "availability by calling vkGetPhysicalDeviceFeatures()."); 35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return skipCall; 35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 36011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, 36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map); 36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // First check is app has actually requested queueFamilyProperties 36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!phy_dev_data->physicalDeviceState) { 36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices()."); 36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (QUERY_DETAILS != phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) { 37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO: This is not called out as an invalid use in the spec so make more informative recommendation. 37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, 37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "DL", "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties()."); 37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Check that the requested queue properties are valid 37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { 37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t requestedIndex = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex; 37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (phy_dev_data->queueFamilyProperties.size() <= 37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert requestedIndex) { // requested index is out of bounds for this physical device 38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg( 38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, 38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL", 38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested.", requestedIndex); 38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pCreateInfo->pQueueCreateInfos[i].queueCount > 38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount) { 38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, 38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "DL", "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but " 39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "requested queueCount is %u.", 39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert requestedIndex, phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount, 39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pCreateInfo->pQueueCreateInfos[i].queueCount); 39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Check that any requested features are available 39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pEnabledFeatures) { 39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->requestedPhysicalDeviceFeatures = *(pCreateInfo->pEnabledFeatures); 39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= validate_features_request(phy_dev_data); 40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (skipCall) 40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(chain_info->u.pLayerInfo); 40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(phy_dev_data->instance, "vkCreateDevice"); 41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (fpCreateDevice == NULL) { 41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_INITIALIZATION_FAILED; 41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Advance the link info for the next element on the chain 41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); 41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (result != VK_SUCCESS) { 41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); 42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->device_dispatch_table = new VkLayerDispatchTable; 42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); 42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice); 42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->physicalDevice = gpu; 42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Get physical device properties for this device 42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_device_data->physicalDeviceProperties)); 43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 43411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { 43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Free device lifetime allocations 43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_key key = get_dispatch_key(device); 43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_device_data = get_my_data_ptr(key, layer_data_map); 43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->device_dispatch_table->DestroyDevice(device, pAllocator); 43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert delete my_device_data->device_dispatch_table; 44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data_map.erase(key); 44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 44411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, 44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkRenderPass *pRenderPass) { 44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skip_call = false; 44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t max_color_attachments = dev_data->physicalDeviceProperties.limits.maxColorAttachments; 45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) { 45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reinterpret_cast<uint64_t>(device), __LINE__, DEVLIMITS_INVALID_ATTACHMENT_COUNT, "DL", 45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Cannot create a render pass with %d color attachments. Max is %d.", 45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments); 45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (skip_call) { 45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return dev_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass); 46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 46511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, 46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, 46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkCommandPool *pCommandPool) { 46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO : Verify that requested QueueFamilyIndex for this pool exists 46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map) 47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->device_dispatch_table->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool); 47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 47511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) { 47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get_my_data_ptr(get_dispatch_key(device), layer_data_map) 47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator); 47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 48011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 48111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) { 48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map) 48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->device_dispatch_table->ResetCommandPool(device, commandPool, flags); 48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 48711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 48811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo, VkCommandBuffer *pCommandBuffer) { 48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map) 49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->device_dispatch_table->AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer); 49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 49411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 49511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t count, const VkCommandBuffer *pCommandBuffers) { 49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get_my_data_ptr(get_dispatch_key(device), layer_data_map) 49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ->device_dispatch_table->FreeCommandBuffers(device, commandPool, count, pCommandBuffers); 49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 50111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) { 50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(dev_data->physicalDevice), layer_data_map); 50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo; 50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries == VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE) { 50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg( 50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL", 51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support inheritedQueries."); 51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries != VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE && 51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert !validate_VkQueryControlFlagBits(VkQueryControlFlagBits(pInfo->queryFlags))) { 51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL", 51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Cannot enable in occlusion queries in vkBeginCommandBuffer() and set queryFlags to %d which is not a " 51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "valid combination of VkQueryControlFlagBits.", 51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInfo->queryFlags); 51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) 52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = dev_data->device_dispatch_table->BeginCommandBuffer(commandBuffer, pBeginInfo); 52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 52711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) { 52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkPhysicalDevice gpu = dev_data->physicalDevice; 53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map); 53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (queueFamilyIndex >= 53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->queueFamilyProperties.size()) { // requested index is out of bounds for this physical device 53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, 53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "DL", "Invalid queueFamilyIndex %u requested in vkGetDeviceQueue().", queueFamilyIndex); 53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (queueIndex >= phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount) { 53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg( 53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, 54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL", 54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Invalid queue request in vkGetDeviceQueue(). QueueFamilyIndex %u only has %u queues, but requested queueIndex is %u.", 54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert queueFamilyIndex, phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount, queueIndex); 54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) 54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dev_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue); 54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 54811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 54911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites, 55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) { 55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < descriptorWriteCount; i++) { 55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) || 55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) { 55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDeviceSize uniformAlignment = dev_data->physicalDeviceProperties.limits.minUniformBufferOffsetAlignment; 55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) { 55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) { 56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, 56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, "DL", 56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64 56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ") must be a multiple of device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64, 56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment); 56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) || 56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { 57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDeviceSize storageAlignment = dev_data->physicalDeviceProperties.limits.minStorageBufferOffsetAlignment; 57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) { 57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) { 57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, 57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DEVLIMITS_INVALID_STORAGE_BUFFER_OFFSET, "DL", 57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64 57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ") must be a multiple of device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64, 57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment); 57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dev_data->device_dispatch_table->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDescriptorCopies); 58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 59011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, 59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) { 59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // dstOffset is the byte offset into the buffer to start updating and must be a multiple of 4. 59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (dstOffset & 3) { 59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, 59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL", 59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkCmdUpdateBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) { 60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return; 60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // dataSize is the number of bytes to update, which must be a multiple of 4. 60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (dataSize & 3) { 60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, 60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL", 60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is not a multiple of 4")) { 61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return; 61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dev_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData); 61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 61811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) { 61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // dstOffset is the byte offset into the buffer to start filling and must be a multiple of 4. 62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (dstOffset & 3) { 62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, 62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL", 62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkCmdFillBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) { 62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return; 62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // size is the number of bytes to fill, which must be a multiple of 4. 63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (size & 3) { 63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, 63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL", 63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkCmdFillBuffer parameter, VkDeviceSize size, is not a multiple of 4")) { 63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return; 63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data); 64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 64411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 64511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { 64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (VK_SUCCESS == res) { 65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback); 65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return res; 65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 65511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 65611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertDestroyDebugReportCallbackEXT(VkInstance instance, 65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDebugReportCallbackEXT msgCallback, 65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator) { 65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator); 66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 66511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, 66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, 66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pMsg); 67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 67211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 67311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *pLayerName, uint32_t *pCount, 67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkExtensionProperties *pProperties) { 67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) 67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return util_GetExtensionProperties(0, nullptr, pCount, pProperties); 67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(physicalDevice); 68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_key key = get_dispatch_key(physicalDevice); 68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(key, layer_data_map); 68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties); 68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_core_instance_command(const char *name); 68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_core_device_command(const char *name); 69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 69311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetDeviceProcAddr(VkDevice dev, const char *funcName) { 69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc = intercept_core_device_command(funcName); 69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (proc) 69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return proc; 69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(dev); 69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map); 70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerDispatchTable *pTable = my_data->device_dispatch_table; 70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pTable->GetDeviceProcAddr == NULL) 70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return NULL; 70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pTable->GetDeviceProcAddr(dev, funcName); 70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 70911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 71011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetInstanceProcAddr(VkInstance instance, const char *funcName) { 71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc = intercept_core_instance_command(funcName); 71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!proc) 71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert intercept_core_device_command(funcName); 71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (proc) 71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return proc; 71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data; 71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(instance); 72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert proc = debug_report_get_instance_proc_addr(my_data->report_data, funcName); 72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (proc) 72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return proc; 72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; 72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pTable->GetInstanceProcAddr == NULL) 72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return NULL; 73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pTable->GetInstanceProcAddr(instance, funcName); 73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 73411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_core_instance_command(const char *name) { 73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static const struct { 73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *name; 73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc; 73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } core_instance_commands[] = { 74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr) }, 74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) }, 74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) }, 74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) }, 74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) }, 74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) }, 74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceFeatures", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFeatures) }, 74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFormatProperties) }, 74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceImageFormatProperties) }, 74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties) }, 75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) }, 75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceMemoryProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMemoryProperties) }, 75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceSparseImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSparseImageFormatProperties) }, 75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) }, 75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 75511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // we should never be queried for these commands 75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(strcmp(name, "vkEnumerateInstanceLayerProperties") && 75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert strcmp(name, "vkEnumerateInstanceExtensionProperties") && 75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert strcmp(name, "vkEnumerateDeviceLayerProperties")); 76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) { 76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(core_instance_commands[i].name, name)) 76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return core_instance_commands[i].proc; 76411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 76711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 76811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 76911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 77011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_core_device_command(const char *name) { 77111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static const struct { 77211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *name; 77311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc; 77411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } core_device_commands[] = { 77511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) }, 77611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice) }, 77711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue) }, 77811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CreateRenderPass) }, 77911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateCommandPool", reinterpret_cast<PFN_vkVoidFunction>(CreateCommandPool) }, 78011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkDestroyCommandPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyCommandPool) }, 78111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkResetCommandPool", reinterpret_cast<PFN_vkVoidFunction>(ResetCommandPool) }, 78211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkAllocateCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers) }, 78311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkFreeCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(FreeCommandBuffers) }, 78411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkBeginCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(BeginCommandBuffer) }, 78511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCmdUpdateBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdUpdateBuffer) }, 78611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkUpdateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(UpdateDescriptorSets) }, 78711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCmdFillBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdFillBuffer) }, 78811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCmdSetScissor", reinterpret_cast<PFN_vkVoidFunction>(CmdSetScissor) }, 78911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCmdSetViewport", reinterpret_cast<PFN_vkVoidFunction>(CmdSetViewport) }, 79011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 79111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 79211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) { 79311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(core_device_commands[i].name, name)) 79411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return core_device_commands[i].proc; 79511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 79611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 79711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 79811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 79911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 80011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace device_limits 80111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 80211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// vk_layer_logging.h expects these to be defined 80311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 80411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 80511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 80611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { 80711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return device_limits::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 80811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 80911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 81011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 81111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkDestroyDebugReportCallbackEXT(VkInstance instance, 81211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDebugReportCallbackEXT msgCallback, 81311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator) { 81411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert device_limits::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 81511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 81611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 81711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 81811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, 81911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 82011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert device_limits::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg); 82111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 82211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 82311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// loader-layer interface v0 82411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 82511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 82611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) { 82711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return util_GetLayerProperties(1, &device_limits::global_layer, pCount, pProperties); 82811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 82911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 83011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 83111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) { 83211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return util_GetLayerProperties(1, &device_limits::global_layer, pCount, pProperties); 83311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 83411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 83511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 83611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) { 83711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return util_GetExtensionProperties(1, device_limits::instance_extensions, pCount, pProperties); 83811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 83911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 84011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 84111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *pLayerName, uint32_t *pCount, 84211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkExtensionProperties *pProperties) { 84311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // the layer command handles VK_NULL_HANDLE just fine 84411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return device_limits::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); 84511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 84611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 84711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) { 84811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return device_limits::GetDeviceProcAddr(dev, funcName); 84911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 85011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 85111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 85211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties")) 85311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties); 85411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties")) 85511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties); 85611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties")) 85711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties); 85811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(funcName, "vkGetInstanceProcAddr")) 85911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr); 86011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 86111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return device_limits::GetInstanceProcAddr(instance, funcName); 86211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 863