From f9bc98a9e2054b25cf995266580c386cc72206e8 Mon Sep 17 00:00:00 2001 From: Tobin Ehlis Date: Thu, 23 Jun 2016 17:03:56 -0600 Subject: layers: BUFFER_NODE clean-up Initial work to prepare for larger overhaul of BUFFER_NODE as well as unifying INVALID_CB treatment. This adds cb_bindings set to BASE_NODE which will be used to track command buffers that objects are bound to in order to flag them as INVALID if objects are deleted while CB are still valid. Initially making use of this with BUFFER_NODE, but it will move to all objects that can be bound to command buffers. Also, use getBufferNode() utility in DestroyBuffer() and add buffer to BUFFER_NODE so it can be used for erasing node from map. --- layers/core_validation.cpp | 12 ++++++------ layers/core_validation_types.h | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 0a047c9f..5e3090a4 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -5099,14 +5099,14 @@ VKAPI_ATTR void VKAPI_CALL DestroyBuffer(VkDevice device, VkBuffer buffer, lock.lock(); } // Clean up memory binding and range information for buffer - auto buff_it = dev_data->bufferMap.find(buffer); - if (buff_it != dev_data->bufferMap.end()) { - auto mem_info = getMemObjInfo(dev_data, buff_it->second.get()->mem); + auto buff_node = getBufferNode(dev_data, buffer); + if (buff_node) { + auto mem_info = getMemObjInfo(dev_data, buff_node->mem); if (mem_info) { - remove_memory_ranges(reinterpret_cast(buffer), buff_it->second.get()->mem, mem_info->bufferRanges); + remove_memory_ranges(reinterpret_cast(buffer), buff_node->mem, mem_info->bufferRanges); } clear_object_binding(dev_data, reinterpret_cast(buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT); - dev_data->bufferMap.erase(buff_it); + dev_data->bufferMap.erase(buff_node->buffer); } } @@ -5544,7 +5544,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateBuffer(VkDevice device, const VkBufferCreat if (VK_SUCCESS == result) { std::lock_guard lock(global_lock); // 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.insert(std::make_pair(*pBuffer, unique_ptr(new BUFFER_NODE(pCreateInfo)))); + dev_data->bufferMap.insert(std::make_pair(*pBuffer, unique_ptr(new BUFFER_NODE(*pBuffer, pCreateInfo)))); } return result; } diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index 0cb9b685..8111cc74 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -60,7 +60,13 @@ class DescriptorSet; class BASE_NODE { public: + // Track when object is being used by an in-flight command buffer std::atomic_int in_use; + // Track command buffers that this object is bound to + // binding initialized when cmd referencing object is bound to command buffer + // binding removed when command buffer is reset or destroyed + // When an object is destroyed, any bound cbs are set to INVALID + std::unordered_set cb_bindings; }; struct DESCRIPTOR_POOL_NODE { @@ -102,11 +108,17 @@ struct DESCRIPTOR_POOL_NODE { class BUFFER_NODE : public BASE_NODE { public: using BASE_NODE::in_use; + VkBuffer buffer; VkDeviceMemory mem; VkBufferCreateInfo createInfo; - BUFFER_NODE() : mem(VK_NULL_HANDLE), createInfo{} { in_use.store(0); }; - BUFFER_NODE(const VkBufferCreateInfo *pCreateInfo) : mem(VK_NULL_HANDLE), createInfo(*pCreateInfo) { in_use.store(0); }; - BUFFER_NODE(const BUFFER_NODE &rh_obj) : mem(rh_obj.mem), createInfo(rh_obj.createInfo) { in_use.store(rh_obj.in_use.load()); }; + BUFFER_NODE() : buffer(VK_NULL_HANDLE), mem(VK_NULL_HANDLE), createInfo{} { in_use.store(0); }; + BUFFER_NODE(VkBuffer buff, const VkBufferCreateInfo *pCreateInfo) + : buffer(buff), mem(VK_NULL_HANDLE), createInfo(*pCreateInfo) { + in_use.store(0); + }; + BUFFER_NODE(const BUFFER_NODE &rh_obj) : buffer(rh_obj.buffer), mem(rh_obj.mem), createInfo(rh_obj.createInfo) { + in_use.store(0); + }; }; struct SAMPLER_NODE { -- cgit v1.2.3