Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
  }
}