diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index ef7f9f403..566ff9885 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1489,7 +1489,7 @@ void WrappedVulkan::StartFrameCapture(void *dev, void *wnd) // will check to see if they need to markdirty or markpendingdirty // and go into the frame record. { - SCOPED_LOCK(m_CapTransitionLock); + SCOPED_WRITELOCK(m_CapTransitionLock); // wait for all work to finish and apply a memory barrier to ensure all memory is visible for(size_t i = 0; i < m_QueueFamilies.size(); i++) @@ -1627,7 +1627,7 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) // transition back to IDLE atomically { - SCOPED_LOCK(m_CapTransitionLock); + SCOPED_WRITELOCK(m_CapTransitionLock); EndCaptureFrame(backbuffer); m_State = CaptureState::BackgroundCapturing; @@ -1969,7 +1969,7 @@ bool WrappedVulkan::DiscardFrameCapture(void *dev, void *wnd) // transition back to IDLE atomically { - SCOPED_LOCK(m_CapTransitionLock); + SCOPED_WRITELOCK(m_CapTransitionLock); m_State = CaptureState::BackgroundCapturing; diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 68fb8c7d8..b3be934f6 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -325,7 +325,7 @@ private: VulkanShaderCache *m_ShaderCache = NULL; VulkanTextRenderer *m_TextRenderer = NULL; - Threading::CriticalSection m_CapTransitionLock; + Threading::RWLock m_CapTransitionLock; VulkanDrawcallCallback *m_DrawcallCallback; diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index 24b8fb3bb..40fc22d79 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -929,68 +929,69 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, Unwrap(device), writeCount, unwrappedWrites, copyCount, unwrappedCopies)); } - bool capframe = false; { - SCOPED_LOCK(m_CapTransitionLock); - capframe = IsActiveCapturing(m_State); - } - - if(capframe) - { - // don't have to mark referenced any of the resources pointed to by the descriptor set - that's - // handled on queue submission by marking ref'd all the current bindings of the sets referenced - // by the cmd buffer + SCOPED_READLOCK(m_CapTransitionLock); + if(IsActiveCapturing(m_State)) { - CACHE_THREAD_SERIALISER(); + // don't have to mark referenced any of the resources pointed to by the descriptor set - + // that's + // handled on queue submission by marking ref'd all the current bindings of the sets + // referenced + // by the cmd buffer - SCOPED_SERIALISE_CHUNK(VulkanChunk::vkUpdateDescriptorSets); - Serialise_vkUpdateDescriptorSets(ser, device, writeCount, pDescriptorWrites, copyCount, - pDescriptorCopies); - - m_FrameCaptureRecord->AddChunk(scope.Get()); - } - - // previously we would not mark descriptor set destinations as ref'd here. This is because all - // descriptor sets are implicitly dirty and they're only actually *needed* when bound - we can - // safely skip any updates of unused descriptor sets. However for consistency with template - // updates below, we pull them in here even if they won't technically be needed. - - for(uint32_t i = 0; i < writeCount; i++) - { - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorWrites[i].dstSet), - eFrameRef_PartialWrite); - } - - for(uint32_t i = 0; i < copyCount; i++) - { - // At the same time as ref'ing the source set, we must ref all of its resources (via the - // bindFrameRefs). This is because they must be valid even if the source set is not ever bound - // (and so its bindings aren't pulled in). - // - // We just ref all rather than looking at only the copied sets to keep things simple. - // This does mean a slightly conservative ref'ing if the dest set doesn't end up getting - // bound, but we only do this during frame capture so it's not too bad. - - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorCopies[i].dstSet), - eFrameRef_PartialWrite); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorCopies[i].srcSet), - eFrameRef_Read); - - VkResourceRecord *setrecord = GetRecord(pDescriptorCopies[i].srcSet); - - SCOPED_LOCK(setrecord->descInfo->refLock); - - for(auto refit = setrecord->descInfo->bindFrameRefs.begin(); - refit != setrecord->descInfo->bindFrameRefs.end(); ++refit) { - GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second); + CACHE_THREAD_SERIALISER(); - if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT) + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkUpdateDescriptorSets); + Serialise_vkUpdateDescriptorSets(ser, device, writeCount, pDescriptorWrites, copyCount, + pDescriptorCopies); + + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + + // previously we would not mark descriptor set destinations as ref'd here. This is because all + // descriptor sets are implicitly dirty and they're only actually *needed* when bound - we can + // safely skip any updates of unused descriptor sets. However for consistency with template + // updates below, we pull them in here even if they won't technically be needed. + + for(uint32_t i = 0; i < writeCount; i++) + { + GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorWrites[i].dstSet), + eFrameRef_PartialWrite); + } + + for(uint32_t i = 0; i < copyCount; i++) + { + // At the same time as ref'ing the source set, we must ref all of its resources (via the + // bindFrameRefs). This is because they must be valid even if the source set is not ever + // bound + // (and so its bindings aren't pulled in). + // + // We just ref all rather than looking at only the copied sets to keep things simple. + // This does mean a slightly conservative ref'ing if the dest set doesn't end up getting + // bound, but we only do this during frame capture so it's not too bad. + + GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorCopies[i].dstSet), + eFrameRef_PartialWrite); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorCopies[i].srcSet), + eFrameRef_Read); + + VkResourceRecord *setrecord = GetRecord(pDescriptorCopies[i].srcSet); + + SCOPED_LOCK(setrecord->descInfo->refLock); + + for(auto refit = setrecord->descInfo->bindFrameRefs.begin(); + refit != setrecord->descInfo->bindFrameRefs.end(); ++refit) { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(refit->first); + GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second); - GetResourceManager()->MarkSparseMapReferenced(record->resInfo); + if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT) + { + VkResourceRecord *record = GetResourceManager()->GetResourceRecord(refit->first); + + GetResourceManager()->MarkSparseMapReferenced(record->resInfo); + } } } } @@ -1360,27 +1361,25 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate( Unwrap(device), Unwrap(descriptorSet), Unwrap(descriptorUpdateTemplate), memory)); } - bool capframe = false; { - SCOPED_LOCK(m_CapTransitionLock); - capframe = IsActiveCapturing(m_State); - } + SCOPED_READLOCK(m_CapTransitionLock); - if(capframe) - { - CACHE_THREAD_SERIALISER(); + if(IsActiveCapturing(m_State)) + { + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CHUNK(VulkanChunk::vkUpdateDescriptorSetWithTemplate); - Serialise_vkUpdateDescriptorSetWithTemplate(ser, device, descriptorSet, - descriptorUpdateTemplate, pData); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkUpdateDescriptorSetWithTemplate); + Serialise_vkUpdateDescriptorSetWithTemplate(ser, device, descriptorSet, + descriptorUpdateTemplate, pData); - m_FrameCaptureRecord->AddChunk(scope.Get()); + m_FrameCaptureRecord->AddChunk(scope.Get()); - // mark the destination set and template as referenced - GetResourceManager()->MarkResourceFrameReferenced(GetResID(descriptorSet), - eFrameRef_PartialWrite); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(descriptorUpdateTemplate), - eFrameRef_Read); + // mark the destination set and template as referenced + GetResourceManager()->MarkResourceFrameReferenced(GetResID(descriptorSet), + eFrameRef_PartialWrite); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(descriptorUpdateTemplate), + eFrameRef_Read); + } } // need to track descriptor set contents whether capframing or idle diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index 52e8f501f..1e6943a59 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -781,247 +781,249 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount, SERIALISE_TIME_CALL(ret = ObjDisp(queue)->QueueSubmit(Unwrap(queue), submitCount, unwrappedSubmits, Unwrap(fence))); - bool capframe = false; bool present = false; { - SCOPED_LOCK(m_CapTransitionLock); - capframe = IsActiveCapturing(m_State); - } + SCOPED_READLOCK(m_CapTransitionLock); - std::set refdIDs; + bool capframe = IsActiveCapturing(m_State); - VkResourceRecord *queueRecord = GetRecord(queue); + std::set refdIDs; - for(uint32_t s = 0; s < submitCount; s++) - { - for(uint32_t i = 0; i < pSubmits[s].commandBufferCount; i++) + VkResourceRecord *queueRecord = GetRecord(queue); + + for(uint32_t s = 0; s < submitCount; s++) { - ResourceId cmd = GetResID(pSubmits[s].pCommandBuffers[i]); - - VkResourceRecord *record = GetRecord(pSubmits[s].pCommandBuffers[i]); - present |= record->bakedCommands->cmdInfo->present; - + for(uint32_t i = 0; i < pSubmits[s].commandBufferCount; i++) { - SCOPED_LOCK(m_ImageLayoutsLock); - GetResourceManager()->ApplyBarriers(queueRecord->queueFamilyIndex, - record->bakedCommands->cmdInfo->imgbarriers, - m_ImageLayouts); - } + ResourceId cmd = GetResID(pSubmits[s].pCommandBuffers[i]); - for(auto it = record->bakedCommands->cmdInfo->dirtied.begin(); - it != record->bakedCommands->cmdInfo->dirtied.end(); ++it) - { - if(GetResourceManager()->HasCurrentResource(*it)) - GetResourceManager()->MarkDirtyResource(*it); - } + VkResourceRecord *record = GetRecord(pSubmits[s].pCommandBuffers[i]); + present |= record->bakedCommands->cmdInfo->present; - // with EXT_descriptor_indexing a binding might have been updated after - // vkCmdBindDescriptorSets, so we need to track dirtied here at the last second. - for(auto it = record->bakedCommands->cmdInfo->boundDescSets.begin(); - it != record->bakedCommands->cmdInfo->boundDescSets.end(); ++it) - { - VkResourceRecord *setrecord = GetRecord(*it); - - SCOPED_LOCK(setrecord->descInfo->refLock); - - const std::map> &frameRefs = - setrecord->descInfo->bindFrameRefs; - - for(auto refit = frameRefs.begin(); refit != frameRefs.end(); ++refit) { - if(refit->second.second == eFrameRef_PartialWrite || - refit->second.second == eFrameRef_ReadBeforeWrite) - { - if(GetResourceManager()->HasCurrentResource(refit->first)) - GetResourceManager()->MarkDirtyResource(refit->first); - } + SCOPED_LOCK(m_ImageLayoutsLock); + GetResourceManager()->ApplyBarriers(queueRecord->queueFamilyIndex, + record->bakedCommands->cmdInfo->imgbarriers, + m_ImageLayouts); } - } - if(capframe) - { - // for each bound descriptor set, mark it referenced as well as all resources currently - // bound to it + for(auto it = record->bakedCommands->cmdInfo->dirtied.begin(); + it != record->bakedCommands->cmdInfo->dirtied.end(); ++it) + { + if(GetResourceManager()->HasCurrentResource(*it)) + GetResourceManager()->MarkDirtyResource(*it); + } + + // with EXT_descriptor_indexing a binding might have been updated after + // vkCmdBindDescriptorSets, so we need to track dirtied here at the last second. for(auto it = record->bakedCommands->cmdInfo->boundDescSets.begin(); it != record->bakedCommands->cmdInfo->boundDescSets.end(); ++it) { - GetResourceManager()->MarkResourceFrameReferenced(GetResID(*it), eFrameRef_Read); - VkResourceRecord *setrecord = GetRecord(*it); SCOPED_LOCK(setrecord->descInfo->refLock); - for(auto refit = setrecord->descInfo->bindFrameRefs.begin(); - refit != setrecord->descInfo->bindFrameRefs.end(); ++refit) + const std::map> &frameRefs = + setrecord->descInfo->bindFrameRefs; + + for(auto refit = frameRefs.begin(); refit != frameRefs.end(); ++refit) { - refdIDs.insert(refit->first); - GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second); - - if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT) + if(refit->second.second == eFrameRef_PartialWrite || + refit->second.second == eFrameRef_ReadBeforeWrite) { - VkResourceRecord *sparserecord = GetResourceManager()->GetResourceRecord(refit->first); - - GetResourceManager()->MarkSparseMapReferenced(sparserecord->resInfo); + if(GetResourceManager()->HasCurrentResource(refit->first)) + GetResourceManager()->MarkDirtyResource(refit->first); } } - GetResourceManager()->MergeReferencedImages(setrecord->descInfo->bindImgRefs); - GetResourceManager()->MergeReferencedMemory(setrecord->descInfo->bindMemRefs); } - for(auto it = record->bakedCommands->cmdInfo->sparse.begin(); - it != record->bakedCommands->cmdInfo->sparse.end(); ++it) - GetResourceManager()->MarkSparseMapReferenced(*it); - - // pull in frame refs from this baked command buffer - record->bakedCommands->AddResourceReferences(GetResourceManager()); - record->bakedCommands->AddReferencedIDs(refdIDs); - - GetResourceManager()->MergeReferencedImages(record->bakedCommands->cmdInfo->imgFrameRefs); - GetResourceManager()->MergeReferencedMemory(record->bakedCommands->cmdInfo->memFrameRefs); - - // ref the parent command buffer's alloc record, this will pull in the cmd buffer pool - GetResourceManager()->MarkResourceFrameReferenced( - record->cmdInfo->allocRecord->GetResourceID(), eFrameRef_Read); - - for(size_t sub = 0; sub < record->bakedCommands->cmdInfo->subcmds.size(); sub++) + if(capframe) { - record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddResourceReferences( - GetResourceManager()); - record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddReferencedIDs(refdIDs); - GetResourceManager()->MergeReferencedImages( - record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->cmdInfo->imgFrameRefs); - GetResourceManager()->MergeReferencedMemory( - record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->cmdInfo->memFrameRefs); + // for each bound descriptor set, mark it referenced as well as all resources currently + // bound to it + for(auto it = record->bakedCommands->cmdInfo->boundDescSets.begin(); + it != record->bakedCommands->cmdInfo->boundDescSets.end(); ++it) + { + GetResourceManager()->MarkResourceFrameReferenced(GetResID(*it), eFrameRef_Read); + + VkResourceRecord *setrecord = GetRecord(*it); + + SCOPED_LOCK(setrecord->descInfo->refLock); + + for(auto refit = setrecord->descInfo->bindFrameRefs.begin(); + refit != setrecord->descInfo->bindFrameRefs.end(); ++refit) + { + refdIDs.insert(refit->first); + GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second); + + if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT) + { + VkResourceRecord *sparserecord = + GetResourceManager()->GetResourceRecord(refit->first); + + GetResourceManager()->MarkSparseMapReferenced(sparserecord->resInfo); + } + } + GetResourceManager()->MergeReferencedImages(setrecord->descInfo->bindImgRefs); + GetResourceManager()->MergeReferencedMemory(setrecord->descInfo->bindMemRefs); + } + + for(auto it = record->bakedCommands->cmdInfo->sparse.begin(); + it != record->bakedCommands->cmdInfo->sparse.end(); ++it) + GetResourceManager()->MarkSparseMapReferenced(*it); + + // pull in frame refs from this baked command buffer + record->bakedCommands->AddResourceReferences(GetResourceManager()); + record->bakedCommands->AddReferencedIDs(refdIDs); + + GetResourceManager()->MergeReferencedImages(record->bakedCommands->cmdInfo->imgFrameRefs); + GetResourceManager()->MergeReferencedMemory(record->bakedCommands->cmdInfo->memFrameRefs); + + // ref the parent command buffer's alloc record, this will pull in the cmd buffer pool GetResourceManager()->MarkResourceFrameReferenced( - record->bakedCommands->cmdInfo->subcmds[sub]->cmdInfo->allocRecord->GetResourceID(), - eFrameRef_Read); + record->cmdInfo->allocRecord->GetResourceID(), eFrameRef_Read); - record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddRef(); - } - - { - SCOPED_LOCK(m_CmdBufferRecordsLock); - m_CmdBufferRecords.push_back(record->bakedCommands); for(size_t sub = 0; sub < record->bakedCommands->cmdInfo->subcmds.size(); sub++) - m_CmdBufferRecords.push_back(record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands); + { + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddResourceReferences( + GetResourceManager()); + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddReferencedIDs(refdIDs); + GetResourceManager()->MergeReferencedImages( + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->cmdInfo->imgFrameRefs); + GetResourceManager()->MergeReferencedMemory( + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->cmdInfo->memFrameRefs); + GetResourceManager()->MarkResourceFrameReferenced( + record->bakedCommands->cmdInfo->subcmds[sub]->cmdInfo->allocRecord->GetResourceID(), + eFrameRef_Read); + + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddRef(); + } + + { + SCOPED_LOCK(m_CmdBufferRecordsLock); + m_CmdBufferRecords.push_back(record->bakedCommands); + for(size_t sub = 0; sub < record->bakedCommands->cmdInfo->subcmds.size(); sub++) + m_CmdBufferRecords.push_back( + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands); + } + + record->bakedCommands->AddRef(); } - record->bakedCommands->AddRef(); + record->cmdInfo->dirtied.clear(); + } + } + + if(capframe) + { + GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); + + if(fence != VK_NULL_HANDLE) + GetResourceManager()->MarkResourceFrameReferenced(GetResID(fence), eFrameRef_Read); + + std::vector maps; + { + SCOPED_LOCK(m_CoherentMapsLock); + maps = m_CoherentMaps; } - record->cmdInfo->dirtied.clear(); - } - } - - if(capframe) - { - GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); - - if(fence != VK_NULL_HANDLE) - GetResourceManager()->MarkResourceFrameReferenced(GetResID(fence), eFrameRef_Read); - - std::vector maps; - { - SCOPED_LOCK(m_CoherentMapsLock); - maps = m_CoherentMaps; - } - - for(auto it = maps.begin(); it != maps.end(); ++it) - { - VkResourceRecord *record = *it; - MemMapState &state = *record->memMapState; - - // potential persistent map - if(state.mapCoherent && state.mappedPtr && !state.mapFlushed) + for(auto it = maps.begin(); it != maps.end(); ++it) { - // only need to flush memory that could affect this submitted batch of work - if(refdIDs.find(record->GetResourceID()) == refdIDs.end()) - { - RDCDEBUG("Map of memory %llu not referenced in this queue - not flushing", - record->GetResourceID()); - continue; - } + VkResourceRecord *record = *it; + MemMapState &state = *record->memMapState; - size_t diffStart = 0, diffEnd = 0; - bool found = true; + // potential persistent map + if(state.mapCoherent && state.mappedPtr && !state.mapFlushed) + { + // only need to flush memory that could affect this submitted batch of work + if(refdIDs.find(record->GetResourceID()) == refdIDs.end()) + { + RDCDEBUG("Map of memory %llu not referenced in this queue - not flushing", + record->GetResourceID()); + continue; + } + + size_t diffStart = 0, diffEnd = 0; + bool found = true; // enabled as this is necessary for programs with very large coherent mappings // (> 1GB) as otherwise more than a couple of vkQueueSubmit calls leads to vast // memory allocation. There might still be bugs lurking in here though #if 1 - // this causes vkFlushMappedMemoryRanges call to allocate and copy to refData - // from serialised buffer. We want to copy *precisely* the serialised data, - // otherwise there is a gap in time between serialising out a snapshot of - // the buffer and whenever we then copy into the ref data, e.g. below. - // during this time, data could be written to the buffer and it won't have - // been caught in the serialised snapshot, and if it doesn't change then - // it *also* won't be caught in any future FindDiffRange() calls. - // - // Likewise once refData is allocated, the call below will also update it - // with the data serialised out for the same reason. - // - // Note: it's still possible that data is being written to by the - // application while it's being serialised out in the snapshot below. That - // is OK, since the application is responsible for ensuring it's not writing - // data that would be needed by the GPU in this submit. As long as the - // refdata we use for future use is identical to what was serialised, we - // shouldn't miss anything - state.needRefData = true; + // this causes vkFlushMappedMemoryRanges call to allocate and copy to refData + // from serialised buffer. We want to copy *precisely* the serialised data, + // otherwise there is a gap in time between serialising out a snapshot of + // the buffer and whenever we then copy into the ref data, e.g. below. + // during this time, data could be written to the buffer and it won't have + // been caught in the serialised snapshot, and if it doesn't change then + // it *also* won't be caught in any future FindDiffRange() calls. + // + // Likewise once refData is allocated, the call below will also update it + // with the data serialised out for the same reason. + // + // Note: it's still possible that data is being written to by the + // application while it's being serialised out in the snapshot below. That + // is OK, since the application is responsible for ensuring it's not writing + // data that would be needed by the GPU in this submit. As long as the + // refdata we use for future use is identical to what was serialised, we + // shouldn't miss anything + state.needRefData = true; - // if we have a previous set of data, compare. - // otherwise just serialise it all - if(state.refData) - found = FindDiffRange((byte *)state.mappedPtr, state.refData, (size_t)state.mapSize, - diffStart, diffEnd); - else + // if we have a previous set of data, compare. + // otherwise just serialise it all + if(state.refData) + found = FindDiffRange((byte *)state.mappedPtr, state.refData, (size_t)state.mapSize, + diffStart, diffEnd); + else #endif - diffEnd = (size_t)state.mapSize; - - if(found) - { - // MULTIDEVICE should find the device for this queue. - // MULTIDEVICE only want to flush maps associated with this queue - VkDevice dev = GetDev(); + diffEnd = (size_t)state.mapSize; + if(found) { - RDCLOG("Persistent map flush forced for %llu (%llu -> %llu)", record->GetResourceID(), - (uint64_t)diffStart, (uint64_t)diffEnd); - VkMappedMemoryRange range = {VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, NULL, - (VkDeviceMemory)(uint64_t)record->Resource, - state.mapOffset + diffStart, diffEnd - diffStart}; - vkFlushMappedMemoryRanges(dev, 1, &range); - state.mapFlushed = false; - } + // MULTIDEVICE should find the device for this queue. + // MULTIDEVICE only want to flush maps associated with this queue + VkDevice dev = GetDev(); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - RDCDEBUG("Persistent map flush not needed for %llu", record->GetResourceID()); + { + RDCLOG("Persistent map flush forced for %llu (%llu -> %llu)", record->GetResourceID(), + (uint64_t)diffStart, (uint64_t)diffEnd); + VkMappedMemoryRange range = {VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, NULL, + (VkDeviceMemory)(uint64_t)record->Resource, + state.mapOffset + diffStart, diffEnd - diffStart}; + vkFlushMappedMemoryRanges(dev, 1, &range); + state.mapFlushed = false; + } + + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + RDCDEBUG("Persistent map flush not needed for %llu", record->GetResourceID()); + } } } - } - { - CACHE_THREAD_SERIALISER(); + { + CACHE_THREAD_SERIALISER(); - ser.SetDrawChunk(); - SCOPED_SERIALISE_CHUNK(VulkanChunk::vkQueueSubmit); - Serialise_vkQueueSubmit(ser, queue, submitCount, pSubmits, fence); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkQueueSubmit); + Serialise_vkQueueSubmit(ser, queue, submitCount, pSubmits, fence); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + m_FrameCaptureRecord->AddChunk(scope.Get()); + } - for(uint32_t s = 0; s < submitCount; s++) - { - for(uint32_t sem = 0; sem < pSubmits[s].waitSemaphoreCount; sem++) - GetResourceManager()->MarkResourceFrameReferenced( - GetResID(pSubmits[s].pWaitSemaphores[sem]), eFrameRef_Read); + for(uint32_t s = 0; s < submitCount; s++) + { + for(uint32_t sem = 0; sem < pSubmits[s].waitSemaphoreCount; sem++) + GetResourceManager()->MarkResourceFrameReferenced( + GetResID(pSubmits[s].pWaitSemaphores[sem]), eFrameRef_Read); - for(uint32_t sem = 0; sem < pSubmits[s].signalSemaphoreCount; sem++) - GetResourceManager()->MarkResourceFrameReferenced( - GetResID(pSubmits[s].pSignalSemaphores[sem]), eFrameRef_Read); + for(uint32_t sem = 0; sem < pSubmits[s].signalSemaphoreCount; sem++) + GetResourceManager()->MarkResourceFrameReferenced( + GetResID(pSubmits[s].pSignalSemaphores[sem]), eFrameRef_Read); + } } } diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 7a93553b3..f39517d62 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -634,7 +634,7 @@ void WrappedVulkan::vkUnmapMemory(VkDevice device, VkDeviceMemory mem) bool capframe = false; { - SCOPED_LOCK(m_CapTransitionLock); + SCOPED_READLOCK(m_CapTransitionLock); capframe = IsActiveCapturing(m_State); if(!capframe) @@ -783,7 +783,7 @@ VkResult WrappedVulkan::vkFlushMappedMemoryRanges(VkDevice device, uint32_t memR { bool capframe = false; { - SCOPED_LOCK(m_CapTransitionLock); + SCOPED_READLOCK(m_CapTransitionLock); capframe = IsActiveCapturing(m_State); }