void D3D12ResourceManager::SerialiseResourceStates(vector<D3D12_RESOURCE_BARRIER> &barriers, map<ResourceId, SubresourceStateVector> &states) { SERIALISE_ELEMENT(uint32_t, NumMems, (uint32_t)states.size()); auto srcit = states.begin(); for(uint32_t i = 0; i < NumMems; i++) { SERIALISE_ELEMENT(ResourceId, id, srcit->first); SERIALISE_ELEMENT(uint32_t, NumStates, (uint32_t)srcit->second.size()); ResourceId liveid; if(m_State < WRITING && HasLiveResource(id)) liveid = GetLiveID(id); for(uint32_t m = 0; m < NumStates; m++) { SERIALISE_ELEMENT(D3D12_RESOURCE_STATES, state, srcit->second[m]); if(m_State < WRITING && liveid != ResourceId() && srcit != states.end()) { D3D12_RESOURCE_BARRIER b; b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; b.Transition.pResource = (ID3D12Resource *)GetCurrentResource(liveid); b.Transition.Subresource = m; b.Transition.StateBefore = states[liveid][m]; b.Transition.StateAfter = state; barriers.push_back(b); } } if(m_State >= WRITING) srcit++; } // erase any do-nothing barriers for(auto it = barriers.begin(); it != barriers.end();) { if(it->Transition.StateBefore == it->Transition.StateAfter) it = barriers.erase(it); else ++it; } ApplyBarriers(barriers, states); }
void VulkanResourceManager::SerialiseImageStates(map<ResourceId, ImageLayouts> &states, vector<VkImageMemoryBarrier> &barriers) { Serialiser *localSerialiser = m_pSerialiser; SERIALISE_ELEMENT(uint32_t, NumMems, (uint32_t)states.size()); auto srcit = states.begin(); vector<pair<ResourceId, ImageRegionState> > vec; for(uint32_t i = 0; i < NumMems; i++) { SERIALISE_ELEMENT(ResourceId, id, srcit->first); SERIALISE_ELEMENT(uint32_t, NumStates, (uint32_t)srcit->second.subresourceStates.size()); ResourceId liveid; if(m_State < WRITING && HasLiveResource(id)) liveid = GetLiveID(id); for(uint32_t m = 0; m < NumStates; m++) { SERIALISE_ELEMENT(ImageRegionState, state, srcit->second.subresourceStates[m]); if(m_State < WRITING && liveid != ResourceId() && srcit != states.end()) { VkImageMemoryBarrier t; t.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; t.pNext = NULL; // these access masks aren't used, we need to apply a global memory barrier // to memory each time we restart log replaying. These barriers are just // to get images into the right layout t.srcAccessMask = 0; t.dstAccessMask = 0; // MULTIDEVICE need to handle multiple queues t.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; t.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; t.image = Unwrap(GetCurrentHandle<VkImage>(liveid)); t.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; ReplacePresentableImageLayout(state.newLayout); t.newLayout = state.newLayout; t.subresourceRange = state.subresourceRange; barriers.push_back(t); vec.push_back(std::make_pair(liveid, state)); } } if(m_State >= WRITING) srcit++; } ApplyBarriers(vec, states); for(size_t i = 0; i < vec.size(); i++) barriers[i].oldLayout = vec[i].second.oldLayout; // erase any do-nothing barriers for(auto it = barriers.begin(); it != barriers.end();) { if(it->oldLayout == UNKNOWN_PREV_IMG_LAYOUT) it->oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; if(it->oldLayout == it->newLayout) it = barriers.erase(it); else ++it; } }