diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index 1043cc905..ddefbc887 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -198,6 +198,8 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) } else { + RDCASSERT(res != NULL); + if(type == eResDescriptorSet) { uint32_t numElems; @@ -205,8 +207,6 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) m_pSerialiser->SerialiseComplexArray("Bindings", bindings, numElems); - RDCASSERT(res != NULL); - const VulkanCreationInfo::DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[ m_DescriptorSetInfo[id].layout ]; uint32_t numBinds = (uint32_t)layout.bindings.size(); @@ -353,7 +353,7 @@ void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool } else if(type == eResDeviceMemory) { - RDCERR("Unexpected attempt to create initial state for memory"); + // ignore, it was probably dirty but not referenced in the frame } else if(type == eResFramebuffer) { diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index 436fe85a1..e076a5aef 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -438,20 +438,56 @@ void VulkanResourceManager::ApplyTransitions(vector< pair processed; + + // VKTODOMED this is hack, should be done earlier, but for now it works. + // iterate through every referenced resource and make sure its memory is referenced + // too. + for(auto it = m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it) + { + ResourceId id = it->first; + + if(processed.find(id) != processed.end()) continue; + processed.insert(id); + + VkResourceRecord *record = GetResourceRecord(id); + + if(record && record->GetMemoryRecord()) + { + RDCLOG("Propagating reference from %llu to %llu", record->GetResourceID(), record->GetMemoryRecord()->GetResourceID()); + // mark it as read-before-write so that we ensure there are initial states serialised for it. + MarkResourceFrameReferenced(record->GetMemoryRecord()->GetResourceID(), eFrameRef_ReadBeforeWrite); + } + else if(record && HasCurrentResource(id)) + { + // also extra hack - framebuffers and views and things need to mark their + // parents referenced so that we can eventually come to the image or buffer + // with a memory record. + WrappedVkRes *res = GetCurrentResource(id); + + if(WrappedVkBufferView::IsAlloc(res) || + WrappedVkImageView::IsAlloc(res) || + WrappedVkAttachmentView::IsAlloc(res) || + WrappedVkFramebuffer::IsAlloc(res)) + { + record->MarkParentsReferenced(this, eFrameRef_Read); + + RDCLOG("Propagating references to parents from %llu", record->GetResourceID()); + + // reset to start so we can do this recursively - nasty I know. + it = m_FrameReferencedResources.begin(); + } + } + } +} + bool VulkanResourceManager::Force_InitialState(WrappedVkRes *res) { - // VKTODOMED don't want to be forcing device memory initial state, need to - // know which objects have dirtied their bound memory. - if(!WrappedVkDeviceMemory::IsAlloc(res)) - return false; - - WrappedVkDeviceMemory *devmem = (WrappedVkDeviceMemory *)res; - - // debug-only resources we don't want initial states for - if(devmem->record == NULL) - return false; - - return true; + return false; } bool VulkanResourceManager::Need_InitialStateChunk(WrappedVkRes *res) diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index ce6f164b7..7ef486bb6 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -83,6 +83,8 @@ class VulkanResourceManager : public ResourceManager::ParentType *)ResourceManager::GetCurrentResource(id)) ); } + + void Hack_PropagateReferencesToMemory(); // handling memory & image transitions void RecordTransitions(vector< pair > &trans, map &states, diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 9165ef031..8804750bf 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -88,6 +88,10 @@ VkResult WrappedVulkan::vkAllocMemory( RDCASSERT(record); record->AddChunk(chunk); + + // VKTODOMED always treat memory as dirty for now, so its initial state + // is guaranteed to be prepared + GetResourceManager()->MarkDirtyResource(id); } else { diff --git a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp index a09e302c1..a3ad69d58 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp @@ -882,6 +882,8 @@ VkResult WrappedVulkan::vkQueuePresentWSI( m_pFileSerialiser->Insert(scope.Get(true)); } + GetResourceManager()->Hack_PropagateReferencesToMemory(); + RDCDEBUG("Inserting Resource Serialisers"); GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser);