diff options
Diffstat (limited to 'layers/core_validation.cpp')
| -rw-r--r-- | layers/core_validation.cpp | 341 |
1 files changed, 122 insertions, 219 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index c3768da6..ad922947 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -37,19 +37,19 @@ // Turn on mem_tracker merged code #define MTMERGESOURCE 1 +#include <SPIRV/spirv.hpp> +#include <algorithm> +#include <assert.h> +#include <iostream> +#include <list> +#include <map> +#include <set> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <assert.h> +#include <string> #include <unordered_map> #include <unordered_set> -#include <map> -#include <string> -#include <iostream> -#include <algorithm> -#include <list> -#include <SPIRV/spirv.hpp> -#include <set> #include "vk_loader_platform.h" #include "vk_dispatch_table_helper.h" @@ -105,16 +105,9 @@ struct layer_data { std::vector<VkDebugReportCallbackEXT> logging_callback; VkLayerDispatchTable *device_dispatch_table; VkLayerInstanceDispatchTable *instance_dispatch_table; -#if MTMERGESOURCE -// MTMERGESOURCE - stuff pulled directly from MT - uint64_t currentFenceId; - // Maps for tracking key structs related to mem_tracker state - // Images and Buffers are 2 objects that can have memory bound to them so they get special treatment - unordered_map<uint64_t, MT_OBJ_BINDING_INFO> imageBindingMap; - unordered_map<uint64_t, MT_OBJ_BINDING_INFO> bufferBindingMap; -// MTMERGESOURCE - End of MT stuff -#endif + devExts device_extensions; + uint64_t currentFenceId; unordered_set<VkQueue> queues; // all queues under given device // Global set of all cmdBuffers that are inFlight on this device unordered_set<VkCommandBuffer> globalInFlightCmdBuffers; @@ -152,11 +145,8 @@ struct layer_data { PHYS_DEV_PROPERTIES_NODE physDevProperties; // MTMERGESOURCE - added a couple of fields to constructor initializer layer_data() - : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), -#if MTMERGESOURCE - currentFenceId(1), -#endif - device_extensions(){}; + : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), device_extensions(), + currentFenceId(1){}; }; static const VkLayerProperties cv_global_layers[] = {{ @@ -260,25 +250,24 @@ static void clear_cmd_buf_and_mem_references(layer_data *my_data, const VkComman #define MAX_BINDING 0xFFFFFFFF -static MT_OBJ_BINDING_INFO *get_object_binding_info(layer_data *my_data, uint64_t handle, VkDebugReportObjectTypeEXT type) { - MT_OBJ_BINDING_INFO *retValue = NULL; +static VkDeviceMemory *get_object_mem_binding(layer_data *my_data, uint64_t handle, VkDebugReportObjectTypeEXT type) { switch (type) { case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: { - auto it = my_data->imageBindingMap.find(handle); - if (it != my_data->imageBindingMap.end()) - return &(*it).second; + auto it = my_data->imageMap.find(VkImage(handle)); + if (it != my_data->imageMap.end()) + return &(*it).second.mem; break; } case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: { - auto it = my_data->bufferBindingMap.find(handle); - if (it != my_data->bufferBindingMap.end()) - return &(*it).second; + auto it = my_data->bufferMap.find(VkBuffer(handle)); + if (it != my_data->bufferMap.end()) + return &(*it).second.mem; break; } default: break; } - return retValue; + return nullptr; } // MTMERGESOURCE - end section #endif @@ -301,59 +290,6 @@ static void delete_cmd_buf_info(layer_data *my_data, VkCommandPool commandPool, my_data->commandBufferMap.erase(cb); } -static void add_object_binding_info(layer_data *my_data, const uint64_t handle, const VkDebugReportObjectTypeEXT type, - const VkDeviceMemory mem) { - switch (type) { - // Buffers and images are unique as their CreateInfo is in container struct - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: { - auto pCI = &my_data->bufferBindingMap[handle]; - pCI->mem = mem; - break; - } - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: { - auto pCI = &my_data->imageBindingMap[handle]; - pCI->mem = mem; - break; - } - default: - break; - } -} - -static void add_object_create_info(layer_data *my_data, const uint64_t handle, const VkDebugReportObjectTypeEXT type, - const void *pCreateInfo) { - // TODO : For any CreateInfo struct that has ptrs, need to deep copy them and appropriately clean up on Destroy - switch (type) { - // Buffers and images are unique as their CreateInfo is in container struct - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: { - auto pCI = &my_data->bufferBindingMap[handle]; - memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO)); - memcpy(&pCI->create_info.buffer, pCreateInfo, sizeof(VkBufferCreateInfo)); - break; - } - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: { - auto pCI = &my_data->imageBindingMap[handle]; - memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO)); - memcpy(&pCI->create_info.image, pCreateInfo, sizeof(VkImageCreateInfo)); - break; - } - // Swap Chain is very unique, use my_data->imageBindingMap, but copy in - // SwapChainCreatInfo's usage flags and set the mem value to a unique key. These is used by - // vkCreateImageView and internal mem_tracker routines to distinguish swap chain images - case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: { - auto pCI = &my_data->imageBindingMap[handle]; - memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO)); - pCI->mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY; - pCI->valid = false; - pCI->create_info.image.usage = - const_cast<VkSwapchainCreateInfoKHR *>(static_cast<const VkSwapchainCreateInfoKHR *>(pCreateInfo))->imageUsage; - break; - } - default: - break; - } -} - // Add a fence, creating one if necessary to our list of fences/fenceIds static bool add_fence_info(layer_data *my_data, VkFence fence, VkQueue queue, uint64_t *fenceId) { bool skipCall = false; @@ -445,12 +381,12 @@ static bool validate_usage_flags(layer_data *my_data, void *disp_obj, VkFlags ac // Helper function to validate usage flags for images // Pulls image info and then sends actual vs. desired usage off to helper above where // an error will be flagged if usage is not correct -static bool validate_image_usage_flags(layer_data *my_data, void *disp_obj, VkImage image, VkFlags desired, bool strict, - char const *func_name, char const *usage_string) { +static bool validate_image_usage_flags(layer_data *dev_data, void *disp_obj, VkImage image, VkFlags desired, VkBool32 strict, + char const *func_name, char const *usage_string) { bool skipCall = false; - MT_OBJ_BINDING_INFO *pBindInfo = get_object_binding_info(my_data, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT); - if (pBindInfo) { - skipCall = validate_usage_flags(my_data, disp_obj, pBindInfo->create_info.image.usage, desired, strict, (uint64_t)image, + auto const image_node = dev_data->imageMap.find(image); + if (image_node != dev_data->imageMap.end()) { + skipCall = validate_usage_flags(dev_data, disp_obj, image_node->second.createInfo.usage, desired, strict, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "image", func_name, usage_string); } return skipCall; @@ -459,12 +395,12 @@ static bool validate_image_usage_flags(layer_data *my_data, void *disp_obj, VkIm // Helper function to validate usage flags for buffers // Pulls buffer info and then sends actual vs. desired usage off to helper above where // an error will be flagged if usage is not correct -static bool validate_buffer_usage_flags(layer_data *my_data, void *disp_obj, VkBuffer buffer, VkFlags desired, bool strict, - char const *func_name, char const *usage_string) { +static bool validate_buffer_usage_flags(layer_data *dev_data, void *disp_obj, VkBuffer buffer, VkFlags desired, VkBool32 strict, + char const *func_name, char const *usage_string) { bool skipCall = false; - MT_OBJ_BINDING_INFO *pBindInfo = get_object_binding_info(my_data, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT); - if (pBindInfo) { - skipCall = validate_usage_flags(my_data, disp_obj, pBindInfo->create_info.buffer.usage, desired, strict, (uint64_t)buffer, + auto const buffer_node = dev_data->bufferMap.find(buffer); + if (buffer_node != dev_data->bufferMap.end()) { + skipCall = validate_usage_flags(dev_data, disp_obj, buffer_node->second.createInfo.usage, desired, strict, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "buffer", func_name, usage_string); } return skipCall; @@ -501,9 +437,8 @@ static void add_mem_obj_info(layer_data *my_data, void *object, const VkDeviceMe static bool validate_memory_is_valid(layer_data *dev_data, VkDeviceMemory mem, const char *functionName, VkImage image = VK_NULL_HANDLE) { if (mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { - MT_OBJ_BINDING_INFO *pBindInfo = - get_object_binding_info(dev_data, reinterpret_cast<const uint64_t &>(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT); - if (pBindInfo && !pBindInfo->valid) { + auto const image_node = dev_data->imageMap.find(image); + if (image_node != dev_data->imageMap.end() && !image_node->second.valid) { return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)(mem), __LINE__, MEMTRACK_INVALID_USAGE_FLAG, "MEM", "%s: Cannot read invalid swapchain image %" PRIx64 ", please fill the memory before using.", @@ -523,10 +458,9 @@ static bool validate_memory_is_valid(layer_data *dev_data, VkDeviceMemory mem, c static void set_memory_valid(layer_data *dev_data, VkDeviceMemory mem, bool valid, VkImage image = VK_NULL_HANDLE) { if (mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { - MT_OBJ_BINDING_INFO *pBindInfo = - get_object_binding_info(dev_data, reinterpret_cast<const uint64_t &>(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT); - if (pBindInfo) { - pBindInfo->valid = valid; + auto image_node = dev_data->imageMap.find(image); + if (image_node != dev_data->imageMap.end()) { + image_node->second.valid = valid; } } else { DEVICE_MEM_INFO *pMemObj = get_mem_obj_info(dev_data, mem); @@ -717,11 +651,11 @@ static const char *object_type_to_string(VkDebugReportObjectTypeEXT type) { static bool clear_object_binding(layer_data *dev_data, void *dispObj, uint64_t handle, VkDebugReportObjectTypeEXT type) { // TODO : Need to customize images/buffers/swapchains to track mem binding and clear it here appropriately bool skipCall = false; - MT_OBJ_BINDING_INFO *pObjBindInfo = get_object_binding_info(dev_data, handle, type); - if (pObjBindInfo) { - DEVICE_MEM_INFO *pMemObjInfo = get_mem_obj_info(dev_data, pObjBindInfo->mem); + VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type); + if (pMemBinding) { + DEVICE_MEM_INFO *pMemObjInfo = get_mem_obj_info(dev_data, *pMemBinding); // TODO : Make sure this is a reasonable way to reset mem binding - pObjBindInfo->mem = VK_NULL_HANDLE; + *pMemBinding = VK_NULL_HANDLE; if (pMemObjInfo) { // This obj is bound to a memory object. Remove the reference to this object in that memory object's list, // and set the objects memory binding pointer to NULL. @@ -742,10 +676,8 @@ static bool clear_object_binding(layer_data *dev_data, void *dispObj, uint64_t h // IF a previous binding existed, output validation error // Otherwise, add reference from objectInfo to memoryInfo // Add reference off of objInfo -// device is required for error logging, need a dispatchable -// object for that. -static bool set_mem_binding(layer_data *dev_data, void *dispatch_object, VkDeviceMemory mem, uint64_t handle, - VkDebugReportObjectTypeEXT type, const char *apiName) { +static bool set_mem_binding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, + VkDebugReportObjectTypeEXT type, const char *apiName) { bool skipCall = false; // Handle NULL case separately, just clear previous binding & decrement reference if (mem == VK_NULL_HANDLE) { @@ -753,8 +685,8 @@ static bool set_mem_binding(layer_data *dev_data, void *dispatch_object, VkDevic skipCall = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_MEM_OBJ, "MEM", "In %s, attempting to Bind Obj(%#" PRIxLEAST64 ") to NULL", apiName, handle); } else { - MT_OBJ_BINDING_INFO *pObjBindInfo = get_object_binding_info(dev_data, handle, type); - if (!pObjBindInfo) { + VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type); + if (!pMemBinding) { skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", "In %s, attempting to update Binding of %s Obj(%#" PRIxLEAST64 ") that's not in global list", @@ -763,8 +695,7 @@ static bool set_mem_binding(layer_data *dev_data, void *dispatch_object, VkDevic // non-null case so should have real mem obj DEVICE_MEM_INFO *pMemInfo = get_mem_obj_info(dev_data, mem); if (pMemInfo) { - // TODO : Need to track mem binding for obj and report conflict here - DEVICE_MEM_INFO *pPrevBinding = get_mem_obj_info(dev_data, pObjBindInfo->mem); + DEVICE_MEM_INFO *pPrevBinding = get_mem_obj_info(dev_data, *pMemBinding); if (pPrevBinding != NULL) { skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, @@ -777,12 +708,15 @@ static bool set_mem_binding(layer_data *dev_data, void *dispatch_object, VkDevic // For image objects, make sure default memory state is correctly set // TODO : What's the best/correct way to handle this? if (VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT == type) { - VkImageCreateInfo ici = pObjBindInfo->create_info.image; - if (ici.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { - // TODO:: More memory state transition stuff. + auto const image_node = dev_data->imageMap.find(VkImage(handle)); + if (image_node != dev_data->imageMap.end()) { + VkImageCreateInfo ici = image_node->second.createInfo; + if (ici.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { + // TODO:: More memory state transition stuff. + } } } - pObjBindInfo->mem = mem; + *pMemBinding = mem; } } } @@ -803,18 +737,19 @@ static bool set_sparse_mem_binding(layer_data *dev_data, void *dispObject, VkDev if (mem == VK_NULL_HANDLE) { skipCall = clear_object_binding(dev_data, dispObject, handle, type); } else { - MT_OBJ_BINDING_INFO *pObjBindInfo = get_object_binding_info(dev_data, handle, type); - if (!pObjBindInfo) { + VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type); + if (!pMemBinding) { skipCall |= log_msg( dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", "In %s, attempting to update Binding of Obj(%#" PRIxLEAST64 ") that's not in global list()", apiName, handle); - } - // non-null case so should have real mem obj - DEVICE_MEM_INFO *pInfo = get_mem_obj_info(dev_data, mem); - if (pInfo) { - pInfo->objBindings.insert({handle, type}); - // Need to set mem binding for this object - pObjBindInfo->mem = mem; + } else { + // non-null case so should have real mem obj + DEVICE_MEM_INFO *pInfo = get_mem_obj_info(dev_data, mem); + if (pInfo) { + pInfo->objBindings.insert({handle, type}); + // Need to set mem binding for this object + *pMemBinding = mem; + } } } return skipCall; @@ -830,21 +765,15 @@ void print_object_map_members(layer_data *my_data, void *dispObj, T const &objec } // For given Object, get 'mem' obj that it's bound to or NULL if no binding -static bool get_mem_binding_from_object(layer_data *my_data, void *dispObj, const uint64_t handle, - const VkDebugReportObjectTypeEXT type, VkDeviceMemory *mem) { +static bool get_mem_binding_from_object(layer_data *dev_data, void *dispObj, const uint64_t handle, + const VkDebugReportObjectTypeEXT type, VkDeviceMemory *mem) { bool skipCall = false; *mem = VK_NULL_HANDLE; - MT_OBJ_BINDING_INFO *pObjBindInfo = get_object_binding_info(my_data, handle, type); - if (pObjBindInfo) { - if (pObjBindInfo->mem) { - *mem = pObjBindInfo->mem; - } else { - skipCall = - log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_MISSING_MEM_BINDINGS, - "MEM", "Trying to get mem binding for object %#" PRIxLEAST64 " but object has no mem binding", handle); - } + VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type); + if (pMemBinding) { + *mem = *pMemBinding; } else { - skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_OBJECT, + skipCall = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_OBJECT, "MEM", "Trying to get mem binding for object %#" PRIxLEAST64 " but no such object in %s list", handle, object_type_to_string(type)); } @@ -2837,7 +2766,7 @@ static bool validate_and_update_drawtime_descriptor_state( if ((pWDS->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || (pWDS->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { for (uint32_t j = 0; j < pWDS->descriptorCount; ++j) { - bufferSize = dev_data->bufferMap[pWDS->pBufferInfo[j].buffer].create_info->size; + bufferSize = dev_data->bufferMap[pWDS->pBufferInfo[j].buffer].createInfo.size; uint32_t dynOffset = pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].dynamicOffsets[dynOffsetIndex]; if (pWDS->pBufferInfo[j].range == VK_WHOLE_SIZE) { if ((dynOffset + pWDS->pBufferInfo[j].offset) > bufferSize) { @@ -5828,13 +5757,6 @@ vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *p layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); bool skipCall = false; loader_platform_thread_lock_mutex(&globalLock); -#if MTMERGESOURCE - auto item = dev_data->bufferBindingMap.find((uint64_t)buffer); - if (item != dev_data->bufferBindingMap.end()) { - skipCall = clear_object_binding(dev_data, device, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT); - dev_data->bufferBindingMap.erase(item); - } -#endif if (!validateIdleBuffer(dev_data, buffer) && !skipCall) { loader_platform_thread_unlock_mutex(&globalLock); dev_data->device_dispatch_table->DestroyBuffer(device, buffer, pAllocator); @@ -5859,15 +5781,6 @@ vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocation VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) { layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); bool skipCall = false; -#if MTMERGESOURCE - loader_platform_thread_lock_mutex(&globalLock); - auto item = dev_data->imageBindingMap.find((uint64_t)image); - if (item != dev_data->imageBindingMap.end()) { - skipCall = clear_object_binding(dev_data, device, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT); - dev_data->imageBindingMap.erase(item); - } - loader_platform_thread_unlock_mutex(&globalLock); -#endif if (!skipCall) dev_data->device_dispatch_table->DestroyImage(device, image, pAllocator); @@ -5875,7 +5788,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkIma const auto& entry = dev_data->imageMap.find(image); if (entry != dev_data->imageMap.end()) { // Clear any memory mapping for this image - const auto &mem_entry = dev_data->memObjMap.find(entry->second.mem); + auto mem_entry = dev_data->memObjMap.find(entry->second.mem); if (mem_entry != dev_data->memObjMap.end()) mem_entry->second.image = VK_NULL_HANDLE; @@ -5941,12 +5854,12 @@ vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDevic // Track objects tied to memory uint64_t buffer_handle = (uint64_t)(buffer); bool skipCall = - set_mem_binding(dev_data, device, mem, buffer_handle, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "vkBindBufferMemory"); - add_object_binding_info(dev_data, buffer_handle, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, mem); - { + set_mem_binding(dev_data, mem, buffer_handle, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "vkBindBufferMemory"); + auto buffer_node = dev_data->bufferMap.find(buffer); + if (buffer_node != dev_data->bufferMap.end()) { + buffer_node->second.mem = mem; VkMemoryRequirements memRequirements; - // MTMTODO : Shouldn't this call down the chain? - vkGetBufferMemoryRequirements(device, buffer, &memRequirements); + dev_data->device_dispatch_table->GetBufferMemoryRequirements(device, buffer, &memRequirements); skipCall |= validate_buffer_image_aliasing(dev_data, buffer_handle, mem, memoryOffset, memRequirements, dev_data->memObjMap[mem].bufferRanges, dev_data->memObjMap[mem].imageRanges, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT); @@ -5961,7 +5874,7 @@ vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDevic memoryOffset, memRequirements.alignment); } // Validate device limits alignments - VkBufferUsageFlags usage = dev_data->bufferMap[buffer].create_info->usage; + VkBufferUsageFlags usage = dev_data->bufferMap[buffer].createInfo.usage; if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) { if (vk_safe_modulo(memoryOffset, dev_data->physDevProperties.properties.limits.minTexelBufferOffsetAlignment) != 0) { skipCall |= @@ -6330,11 +6243,8 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, c if (VK_SUCCESS == result) { loader_platform_thread_lock_mutex(&globalLock); -#if MTMERGESOURCE - add_object_create_info(dev_data, (uint64_t)*pBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, pCreateInfo); -#endif // TODO : This doesn't create deep copy of pQueueFamilyIndices so need to fix that if/when we want that data to be valid - dev_data->bufferMap[*pBuffer].create_info = unique_ptr<VkBufferCreateInfo>(new VkBufferCreateInfo(*pCreateInfo)); + dev_data->bufferMap[*pBuffer].createInfo = *pCreateInfo; dev_data->bufferMap[*pBuffer].in_use.store(0); loader_platform_thread_unlock_mutex(&globalLock); } @@ -6368,9 +6278,6 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, co if (VK_SUCCESS == result) { loader_platform_thread_lock_mutex(&globalLock); -#if MTMERGESOURCE - add_object_create_info(dev_data, (uint64_t)*pImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, pCreateInfo); -#endif IMAGE_LAYOUT_NODE image_node; image_node.layout = pCreateInfo->initialLayout; image_node.format = pCreateInfo->format; @@ -8670,24 +8577,25 @@ static bool ValidateBarriers(const char *funcName, VkCommandBuffer cmdBuffer, ui } auto buffer_data = dev_data->bufferMap.find(mem_barrier->buffer); - uint64_t buffer_size = - buffer_data->second.create_info ? reinterpret_cast<uint64_t &>(buffer_data->second.create_info->size) : 0; + VkDeviceSize buffer_size = (buffer_data->second.createInfo.sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO) + ? buffer_data->second.createInfo.size + : 0; if (buffer_data != dev_data->bufferMap.end()) { if (mem_barrier->offset >= buffer_size) { - skip_call |= - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, - DRAWSTATE_INVALID_BARRIER, "DS", "%s: Buffer Barrier 0x%" PRIx64 " has offset %" PRIu64 - " whose sum is not less than total size %" PRIu64 ".", - funcName, reinterpret_cast<const uint64_t &>(mem_barrier->buffer), - reinterpret_cast<const uint64_t &>(mem_barrier->offset), buffer_size); + skip_call |= log_msg( + dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, + DRAWSTATE_INVALID_BARRIER, "DS", + "%s: Buffer Barrier 0x%" PRIx64 " has offset %" PRIu64 " which is not less than total size %" PRIu64 ".", + funcName, reinterpret_cast<const uint64_t &>(mem_barrier->buffer), + reinterpret_cast<const uint64_t &>(mem_barrier->offset), reinterpret_cast<const uint64_t &>(buffer_size)); } else if (mem_barrier->size != VK_WHOLE_SIZE && (mem_barrier->offset + mem_barrier->size > buffer_size)) { - skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, - __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", - "%s: Buffer Barrier 0x%" PRIx64 " has offset %" PRIu64 " and size %" PRIu64 - " whose sum is greater than total size %" PRIu64 ".", - funcName, reinterpret_cast<const uint64_t &>(mem_barrier->buffer), - reinterpret_cast<const uint64_t &>(mem_barrier->offset), - reinterpret_cast<const uint64_t &>(mem_barrier->size), buffer_size); + skip_call |= log_msg( + dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, + DRAWSTATE_INVALID_BARRIER, "DS", "%s: Buffer Barrier 0x%" PRIx64 " has offset %" PRIu64 " and size %" PRIu64 + " whose sum is greater than total size %" PRIu64 ".", + funcName, reinterpret_cast<const uint64_t &>(mem_barrier->buffer), + reinterpret_cast<const uint64_t &>(mem_barrier->offset), reinterpret_cast<const uint64_t &>(mem_barrier->size), + reinterpret_cast<const uint64_t &>(buffer_size)); } } } @@ -10289,33 +10197,35 @@ VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; bool skipCall = false; -#if MTMERGESOURCE loader_platform_thread_lock_mutex(&globalLock); - // Track objects tied to memory - uint64_t image_handle = (uint64_t)(image); - skipCall = - set_mem_binding(dev_data, device, mem, image_handle, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkBindImageMemory"); - add_object_binding_info(dev_data, image_handle, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, mem); - { + auto image_node = dev_data->imageMap.find(image); + if (image_node != dev_data->imageMap.end()) { + // Track objects tied to memory + uint64_t image_handle = reinterpret_cast<uint64_t>(image); + skipCall = set_mem_binding(dev_data, mem, image_handle, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkBindImageMemory"); VkMemoryRequirements memRequirements; - vkGetImageMemoryRequirements(device, image, &memRequirements); + loader_platform_thread_unlock_mutex(&globalLock); + dev_data->device_dispatch_table->GetImageMemoryRequirements(device, image, &memRequirements); + loader_platform_thread_lock_mutex(&globalLock); skipCall |= validate_buffer_image_aliasing(dev_data, image_handle, mem, memoryOffset, memRequirements, dev_data->memObjMap[mem].imageRanges, dev_data->memObjMap[mem].bufferRanges, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT); - } - print_mem_list(dev_data, device); - loader_platform_thread_unlock_mutex(&globalLock); -#endif - if (!skipCall) { - result = dev_data->device_dispatch_table->BindImageMemory(device, image, mem, memoryOffset); - VkMemoryRequirements memRequirements; - dev_data->device_dispatch_table->GetImageMemoryRequirements(device, image, &memRequirements); - loader_platform_thread_lock_mutex(&globalLock); - dev_data->memObjMap[mem].image = image; - dev_data->imageMap[image].mem = mem; - dev_data->imageMap[image].memOffset = memoryOffset; - dev_data->imageMap[image].memSize = memRequirements.size; + print_mem_list(dev_data, device); loader_platform_thread_unlock_mutex(&globalLock); + if (!skipCall) { + result = dev_data->device_dispatch_table->BindImageMemory(device, image, mem, memoryOffset); + loader_platform_thread_lock_mutex(&globalLock); + dev_data->memObjMap[mem].image = image; + image_node->second.mem = mem; + image_node->second.memOffset = memoryOffset; + image_node->second.memSize = memRequirements.size; + loader_platform_thread_unlock_mutex(&globalLock); + } + } else { + log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, + reinterpret_cast<const uint64_t &>(image), __LINE__, MEMTRACK_INVALID_OBJECT, "MT", + "vkBindImageMemory: Cannot find invalid image %" PRIx64 ", has it already been deleted?", + reinterpret_cast<const uint64_t &>(image)); } return result; } @@ -10505,11 +10415,9 @@ vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocat } dev_data->imageSubresourceMap.erase(image_sub); } -#if MTMERGESOURCE skipCall = clear_object_binding(dev_data, device, (uint64_t)swapchain_image, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT); - dev_data->imageBindingMap.erase((uint64_t)swapchain_image); -#endif + dev_data->imageMap.erase(swapchain_image); } } delete swapchain_data->second; @@ -10549,23 +10457,18 @@ vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pCo IMAGE_LAYOUT_NODE image_layout_node; image_layout_node.layout = VK_IMAGE_LAYOUT_UNDEFINED; image_layout_node.format = swapchain_node->createInfo.imageFormat; - dev_data->imageMap[pSwapchainImages[i]].createInfo.mipLevels = 1; - dev_data->imageMap[pSwapchainImages[i]].createInfo.arrayLayers = swapchain_node->createInfo.imageArrayLayers; + auto &image_node = dev_data->imageMap[pSwapchainImages[i]]; + image_node.createInfo.mipLevels = 1; + image_node.createInfo.arrayLayers = swapchain_node->createInfo.imageArrayLayers; + image_node.createInfo.usage = swapchain_node->createInfo.imageUsage; + image_node.valid = false; + image_node.mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY; swapchain_node->images.push_back(pSwapchainImages[i]); ImageSubresourcePair subpair = {pSwapchainImages[i], false, VkImageSubresource()}; dev_data->imageSubresourceMap[pSwapchainImages[i]].push_back(subpair); dev_data->imageLayoutMap[subpair] = image_layout_node; dev_data->device_extensions.imageToSwapchainMap[pSwapchainImages[i]] = swapchain; } - if (!swapchain_node->images.empty()) { - for (auto image : swapchain_node->images) { - // Add image object binding, then insert the new Mem Object and then bind it to created image -#if MTMERGESOURCE - add_object_create_info(dev_data, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, - &swapchain_node->createInfo); -#endif - } - } loader_platform_thread_unlock_mutex(&globalLock); } return result; |
