diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index db282d83a..4046b4d9f 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -141,7 +141,40 @@ class VulkanResourceManager : public ResourceManagerDelete(this); + VkResourceRecord *record = GetRecord(obj); + if(record) + { + // we need to lock here because the app could be creating + // and deleting from this pool at the same time. We do know + // though that the pool isn't going to be destroyed while + // either allocation or freeing happens, so we only need to + // lock against concurrent allocs or deletes of children. + + if(record->pool) + { + // here we lock against concurrent alloc/delete + record->pool->LockChunks(); + for(auto it = record->pool->pooledChildren.begin(); it != record->pool->pooledChildren.end(); ++it) + { + if(*it == record) + { + // remove it from our pool so we don't try and destroy it + record->pool->pooledChildren.erase(it); + break; + } + } + record->pool->UnlockChunks(); + } + else if(record->pooledChildren.size()) + { + // delete all of our children + for(auto it = record->pooledChildren.begin(); it != record->pooledChildren.end(); ++it) + (*it)->Delete(this); + record->pooledChildren.clear(); + } + + record->Delete(this); + } if(clearID) { // note the nulling of the wrapped object's ID here is rather unpleasant, diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index a0c7c7ad3..4bf224432 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -557,6 +557,7 @@ struct VkResourceRecord : public ResourceRecord VkResourceRecord(ResourceId id) : ResourceRecord(id, true), bakedCommands(NULL), + pool(NULL), memory(NULL) { } @@ -641,6 +642,11 @@ struct VkResourceRecord : public ResourceRecord // queues associated with this instance, so they can be shut down on destruction vector queues; + // pointer to either the pool this item is allocated from, or the children allocated + // from this pool. Protected by the chunk lock + VkResourceRecord *pool; + vector pooledChildren; + // descriptor set bindings for this descriptor set. Filled out on // create from the layout. ResourceId layout; diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index 975a128fe..95c3a3cb8 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -269,7 +269,17 @@ VkResult WrappedVulkan::vkAllocDescriptorSets( ResourceId layoutID = GetResID(pSetLayouts[i]); - record->AddParent(GetRecord(descriptorPool)); + VkResourceRecord *poolrecord = GetRecord(descriptorPool); + + { + poolrecord->LockChunks(); + poolrecord->pooledChildren.push_back(record); + poolrecord->UnlockChunks(); + } + + record->pool = poolrecord; + + record->AddParent(poolrecord); record->AddParent(GetResourceManager()->GetResourceRecord(layoutID)); // just always treat descriptor sets as dirty