bool WrappedVulkan::Serialise_vkCreateFence(
			Serialiser*                                 localSerialiser,
			VkDevice                                    device,
			const VkFenceCreateInfo*                    pCreateInfo,
			const VkAllocationCallbacks*                pAllocator,
			VkFence*                                    pFence)
{
	SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
	SERIALISE_ELEMENT(VkFenceCreateInfo, info, *pCreateInfo);
	SERIALISE_ELEMENT(ResourceId, id, GetResID(*pFence));

	if(m_State == READING)
	{
		device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);
		VkFence fence = VK_NULL_HANDLE;

		VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), &info, NULL, &fence);

		if(ret != VK_SUCCESS)
		{
			RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret);
		}
		else
		{
			ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), fence);
			GetResourceManager()->AddLiveResource(id, fence);
		}
	}

	return true;
}
Beispiel #2
0
bool WrappedVulkan::Serialise_vkGetDeviceQueue(Serialiser *localSerialiser, VkDevice device,
                                               uint32_t queueFamilyIndex, uint32_t queueIndex,
                                               VkQueue *pQueue)
{
  SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
  SERIALISE_ELEMENT(uint32_t, familyIdx, m_SupportedQueueFamily);
  SERIALISE_ELEMENT(uint32_t, idx, queueIndex);
  SERIALISE_ELEMENT(ResourceId, queueId, GetResID(*pQueue));

  if(m_State == READING)
  {
    device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);

    VkQueue queue;
    ObjDisp(device)->GetDeviceQueue(Unwrap(device), familyIdx, idx, &queue);

    GetResourceManager()->WrapResource(Unwrap(device), queue);
    GetResourceManager()->AddLiveResource(queueId, queue);

    if(familyIdx == m_QueueFamilyIdx)
    {
      m_Queue = queue;

      // we can now submit any cmds that were queued (e.g. from creating debug
      // manager on vkCreateDevice)
      SubmitCmds();
    }
  }

  return true;
}
Beispiel #3
0
bool WrappedVulkan::Serialise_vkGetSwapchainImagesKHR(
		Serialiser*                              localSerialiser,
		VkDevice                                 device,
		VkSwapchainKHR                           swapchain,
		uint32_t*                                pCount,
		VkImage*                                 pSwapchainImages)
{
	SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
	SERIALISE_ELEMENT(ResourceId, swapId, GetResID(swapchain));
	SERIALISE_ELEMENT(uint32_t, idx, *pCount);
	SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSwapchainImages));

	if(m_State == READING)
	{
		// use original ID because we don't create a live version of the swapchain
		auto &swapInfo = m_CreationInfo.m_SwapChain[swapId];

		RDCASSERT(idx < swapInfo.images.size(), idx, swapInfo.images.size());
		GetResourceManager()->AddLiveResource(id, swapInfo.images[idx].im);

		m_CreationInfo.m_Image[GetResID(swapInfo.images[idx].im)] = m_CreationInfo.m_Image[swapId];
	}

	return true;
}
bool WrappedVulkan::Serialise_vkAllocateMemory(
			Serialiser*                                 localSerialiser,
			VkDevice                                    device,
			const VkMemoryAllocateInfo*                 pAllocateInfo,
			const VkAllocationCallbacks*                pAllocator,
			VkDeviceMemory*                             pMemory)
{
	SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
	SERIALISE_ELEMENT(VkMemoryAllocateInfo, info, *pAllocateInfo);
	SERIALISE_ELEMENT(ResourceId, id, GetResID(*pMemory));

	if(m_State == READING)
	{
		VkDeviceMemory mem = VK_NULL_HANDLE;

		device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);

		// serialised memory type index is non-remapped, so we remap now.
		// PORTABILITY may need to re-write info to change memory type index to the
		// appropriate index on replay
		info.memoryTypeIndex = m_PhysicalDeviceData.memIdxMap[info.memoryTypeIndex];

		VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, NULL, &mem);
		
		if(ret != VK_SUCCESS)
		{
			RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret);
		}
		else
		{
			ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), mem);
			GetResourceManager()->AddLiveResource(id, mem);

			m_CreationInfo.m_Memory[live].Init(GetResourceManager(), m_CreationInfo, &info);

			// create a buffer with the whole memory range bound, for copying to and from
			// conveniently (for initial state data)
			VkBuffer buf = VK_NULL_HANDLE;

			VkBufferCreateInfo bufInfo = {
				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0,
				info.allocationSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT,
			};

			ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf);
			RDCASSERTEQUAL(ret, VK_SUCCESS);

			ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf);

			ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(mem), 0);
			
			// register as a live-only resource, so it is cleaned up properly
			GetResourceManager()->AddLiveResource(bufid, buf);

			m_CreationInfo.m_Memory[live].wholeMemBuf = buf;
		}
	}

	return true;
}
Beispiel #5
0
vector<ResourceId> D3D12RenderState::GetRTVIDs() const
{
  vector<ResourceId> ret;

  if(rtSingle)
  {
    if(!rts.empty())
    {
      const D3D12Descriptor *descs = DescriptorFromPortableHandle(GetResourceManager(), rts[0]);

      for(UINT i = 0; i < rts.size(); i++)
      {
        RDCASSERT(descs[i].GetType() == D3D12Descriptor::TypeRTV);
        ret.push_back(GetResID(descs[i].nonsamp.resource));
      }
    }
  }
  else
  {
    for(UINT i = 0; i < rts.size(); i++)
    {
      WrappedID3D12DescriptorHeap *heap =
          GetResourceManager()->GetLiveAs<WrappedID3D12DescriptorHeap>(rts[0].heap);

      const D3D12Descriptor &desc = heap->GetDescriptors()[rts[i].index];

      RDCASSERT(desc.GetType() == D3D12Descriptor::TypeRTV);
      ret.push_back(GetResID(desc.nonsamp.resource));
    }
  }

  return ret;
}
bool WrappedVulkan::Serialise_vkCreateEvent(
			Serialiser*                             localSerialiser,
			VkDevice                                device,
			const VkEventCreateInfo*                pCreateInfo,
			const VkAllocationCallbacks*            pAllocator,
			VkEvent*                                pEvent)
{
	SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
	SERIALISE_ELEMENT(VkEventCreateInfo, info, *pCreateInfo);
	SERIALISE_ELEMENT(ResourceId, id, GetResID(*pEvent));

	if(m_State == READING)
	{
		device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);
		VkEvent ev = VK_NULL_HANDLE;

		VkResult ret = ObjDisp(device)->CreateEvent(Unwrap(device), &info, NULL, &ev);

		// see top of this file for current event/fence handling
		ObjDisp(device)->SetEvent(Unwrap(device), ev);

		if(ret != VK_SUCCESS)
		{
			RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret);
		}
		else
		{
			ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), ev);
			GetResourceManager()->AddLiveResource(id, ev);
		}
	}

	return true;
}
Beispiel #7
0
void D3D12Descriptor::GetRefIDs(ResourceId &id, ResourceId &id2, FrameRefType &ref)
{
  id = ResourceId();
  id2 = ResourceId();
  ref = eFrameRef_Read;

  switch(GetType())
  {
    case D3D12Descriptor::TypeUndefined:
    case D3D12Descriptor::TypeSampler:
      // nothing to do - no resource here
      break;
    case D3D12Descriptor::TypeCBV:
      id = WrappedID3D12Resource::GetResIDFromAddr(nonsamp.cbv.BufferLocation);
      break;
    case D3D12Descriptor::TypeSRV: id = GetResID(nonsamp.resource); break;
    case D3D12Descriptor::TypeUAV:
      id2 = GetResID(nonsamp.uav.counterResource);
    // deliberate fall-through
    case D3D12Descriptor::TypeRTV:
    case D3D12Descriptor::TypeDSV:
      ref = eFrameRef_Write;
      id = GetResID(nonsamp.resource);
      break;
  }
}
VkResult WrappedVulkan::vkFlushMappedMemoryRanges(
			VkDevice                                    device,
			uint32_t                                    memRangeCount,
			const VkMappedMemoryRange*                  pMemRanges)
{
	if(m_State >= WRITING)
	{
		bool capframe = false;
		{
			SCOPED_LOCK(m_CapTransitionLock);
			capframe = (m_State == WRITING_CAPFRAME);
		}

		for(uint32_t i = 0; i < memRangeCount; i++)
		{
			ResourceId memid = GetResID(pMemRanges[i].memory);
			
			MemMapState *state = GetRecord(pMemRanges[i].memory)->memMapState;
			state->mapFlushed = true;

			if(state->mappedPtr == NULL)
			{
				RDCERR("Flushing memory that isn't currently mapped");
				continue;
			}

			if(capframe)
			{
				CACHE_THREAD_SERIALISER();

				SCOPED_SERIALISE_CONTEXT(FLUSH_MEM);
				Serialise_vkFlushMappedMemoryRanges(localSerialiser, device, 1, pMemRanges + i);

				m_FrameCaptureRecord->AddChunk(scope.Get());
				GetResourceManager()->MarkResourceFrameReferenced(GetResID(pMemRanges[i].memory), eFrameRef_Write);
			}
			else
			{
				GetResourceManager()->MarkDirtyResource(memid);
			}
		}
	}
	
	VkMappedMemoryRange *unwrapped = GetTempArray<VkMappedMemoryRange>(memRangeCount);
	for(uint32_t i=0; i < memRangeCount; i++)
	{
		unwrapped[i] = pMemRanges[i];
		unwrapped[i].memory = Unwrap(unwrapped[i].memory);
	}

	VkResult ret = ObjDisp(device)->FlushMappedMemoryRanges(Unwrap(device), memRangeCount, unwrapped);

	return ret;
}
Beispiel #9
0
bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
    Serialiser *localSerialiser, VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
    const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
    VkPipeline *pPipelines)
{
  SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
  SERIALISE_ELEMENT(ResourceId, cacheId, GetResID(pipelineCache));
  SERIALISE_ELEMENT(VkGraphicsPipelineCreateInfo, info, *pCreateInfos);
  SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelines));

  if(m_State == READING)
  {
    VkPipeline pipe = VK_NULL_HANDLE;

    device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);
    // don't use pipeline caches on replay
    pipelineCache =
        VK_NULL_HANDLE;    // GetResourceManager()->GetLiveHandle<VkPipelineCache>(cacheId);

    VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache),
                                                            1, &info, NULL, &pipe);

    if(ret != VK_SUCCESS)
    {
      RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret);
    }
    else
    {
      ResourceId live;

      if(GetResourceManager()->HasWrapper(ToTypedHandle(pipe)))
      {
        live = GetResourceManager()->GetNonDispWrapper(pipe)->id;

        // destroy this instance of the duplicate, as we must have matching create/destroy
        // calls and there won't be a wrapped resource hanging around to destroy this one.
        ObjDisp(device)->DestroyPipeline(Unwrap(device), pipe, NULL);

        // whenever the new ID is requested, return the old ID, via replacements.
        GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live));
      }
      else
      {
        live = GetResourceManager()->WrapResource(Unwrap(device), pipe);
        GetResourceManager()->AddLiveResource(id, pipe);

        m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &info);
      }
    }
  }

  return true;
}
bool WrappedVulkan::Serialise_vkCreateDescriptorSetLayout(
    Serialiser*                                 localSerialiser,
    VkDevice                                    device,
    const VkDescriptorSetLayoutCreateInfo*      pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkDescriptorSetLayout*                      pSetLayout)
{
    SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
    SERIALISE_ELEMENT(VkDescriptorSetLayoutCreateInfo, info, *pCreateInfo);
    SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSetLayout));

    if(m_State == READING)
    {
        VkDescriptorSetLayout layout = VK_NULL_HANDLE;

        device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);

        VkResult ret = ObjDisp(device)->CreateDescriptorSetLayout(Unwrap(device), &info, NULL, &layout);

        if(ret != VK_SUCCESS)
        {
            RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret);
        }
        else
        {
            ResourceId live;

            if(GetResourceManager()->HasWrapper(ToTypedHandle(layout)))
            {
                live = GetResourceManager()->GetNonDispWrapper(layout)->id;

                // destroy this instance of the duplicate, as we must have matching create/destroy
                // calls and there won't be a wrapped resource hanging around to destroy this one.
                ObjDisp(device)->DestroyDescriptorSetLayout(Unwrap(device), layout, NULL);

                // whenever the new ID is requested, return the old ID, via replacements.
                GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live));
            }
            else
            {
                live = GetResourceManager()->WrapResource(Unwrap(device), layout);
                GetResourceManager()->AddLiveResource(id, layout);

                m_CreationInfo.m_DescSetLayout[live].Init(GetResourceManager(), m_CreationInfo, &info);
            }
        }
    }

    return true;
}
Beispiel #11
0
void D3D12ResourceManager::ApplyBarriers(vector<D3D12_RESOURCE_BARRIER> &barriers,
                                         map<ResourceId, SubresourceStateVector> &states)
{
  for(size_t b = 0; b < barriers.size(); b++)
  {
    D3D12_RESOURCE_TRANSITION_BARRIER &trans = barriers[b].Transition;
    ResourceId id = GetResID(trans.pResource);
    SubresourceStateVector &st = states[id];

    // skip non-transitions, or begin-halves of transitions
    if(barriers[b].Type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION ||
       (barriers[b].Flags & D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY))
      continue;

    if(trans.Subresource == D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES)
    {
      for(size_t i = 0; i < st.size(); i++)
      {
        BARRIER_ASSERT("Mismatching before state", st[i] == trans.StateBefore, st[i],
                       trans.StateBefore, i);
        st[i] = trans.StateAfter;
      }
    }
    else
    {
      BARRIER_ASSERT("Mismatching before state", st[trans.Subresource] == trans.StateBefore,
                     st[trans.Subresource], trans.StateBefore, trans.Subresource);
      st[trans.Subresource] = trans.StateAfter;
    }
  }
}
Beispiel #12
0
PortableHandle ToPortableHandle(D3D12Descriptor *desc)
{
  if(desc == NULL)
    return PortableHandle(0);

  return PortableHandle(GetResID(desc->samp.heap), desc->samp.idx);
}
VkResult WrappedVulkan::vkBindBufferMemory(
    VkDevice                                    device,
    VkBuffer                                    buffer,
    VkDeviceMemory                              mem,
    VkDeviceSize                                memOffset)
{
	VkResourceRecord *record = GetRecord(buffer);

	if(m_State >= WRITING)
	{
		Chunk *chunk = NULL;

		{
			CACHE_THREAD_SERIALISER();
		
			SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_MEM);
			Serialise_vkBindBufferMemory(localSerialiser, device, buffer, mem, memOffset);

			chunk = scope.Get();
		}
	
		// memory object bindings are immutable and must happen before creation or use,
		// so this can always go into the record, even if a resource is created and bound
		// to memory mid-frame
		record->AddChunk(chunk);

		record->AddParent(GetRecord(mem));
		record->baseResource = GetResID(mem);
	}

	return ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buffer), Unwrap(mem), memOffset);
}
Beispiel #14
0
bool WrappedVulkan::Serialise_vkCmdSetDepthBounds(Serialiser *localSerialiser,
                                                  VkCommandBuffer cmdBuffer, float minDepthBounds,
                                                  float maxDepthBounds)
{
  SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
  SERIALISE_ELEMENT(float, mind, minDepthBounds);
  SERIALISE_ELEMENT(float, maxd, maxDepthBounds);

  Serialise_DebugMessages(localSerialiser, false);

  if(m_State < WRITING)
    m_LastCmdBufferID = cmdid;

  if(m_State == EXECUTING)
  {
    if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
    {
      cmdBuffer = RerecordCmdBuf(cmdid);
      ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd);
      m_RenderState.mindepth = mind;
      m_RenderState.maxdepth = maxd;
    }
  }
  else if(m_State == READING)
  {
    cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);

    ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd);
  }

  return true;
}
Beispiel #15
0
bool WrappedVulkan::Serialise_vkCmdSetDepthBias(Serialiser *localSerialiser,
                                                VkCommandBuffer cmdBuffer, float depthBias,
                                                float depthBiasClamp, float slopeScaledDepthBias)
{
  SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
  SERIALISE_ELEMENT(float, bias, depthBias);
  SERIALISE_ELEMENT(float, biasclamp, depthBiasClamp);
  SERIALISE_ELEMENT(float, slope, slopeScaledDepthBias);

  Serialise_DebugMessages(localSerialiser, false);

  if(m_State < WRITING)
    m_LastCmdBufferID = cmdid;

  if(m_State == EXECUTING)
  {
    if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
    {
      cmdBuffer = RerecordCmdBuf(cmdid);
      ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope);
      m_RenderState.bias.depth = bias;
      m_RenderState.bias.biasclamp = biasclamp;
      m_RenderState.bias.slope = slope;
    }
  }
  else if(m_State == READING)
  {
    cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);

    ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope);
  }

  return true;
}
Beispiel #16
0
bool WrappedID3D12Device::Serialise_CreateCommandSignature(const D3D12_COMMAND_SIGNATURE_DESC *pDesc,
                                                           ID3D12RootSignature *pRootSignature,
                                                           REFIID riid, void **ppvCommandSignature)
{
  SERIALISE_ELEMENT(D3D12_COMMAND_SIGNATURE_DESC, desc, *pDesc);
  SERIALISE_ELEMENT(ResourceId, RootSig, GetResID(pRootSignature));
  SERIALISE_ELEMENT(IID, guid, riid);
  SERIALISE_ELEMENT(ResourceId, CommandSig,
                    ((WrappedID3D12CommandSignature *)*ppvCommandSignature)->GetResourceID());

  if(m_State == READING)
  {
    pRootSignature = NULL;
    if(RootSig != ResourceId())
      pRootSignature = GetResourceManager()->GetLiveAs<ID3D12RootSignature>(RootSig);

    ID3D12CommandSignature *ret = NULL;
    HRESULT hr = m_pDevice->CreateCommandSignature(&desc, pRootSignature, guid, (void **)&ret);

    if(FAILED(hr))
    {
      RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr);
    }
    else
    {
      ret = new WrappedID3D12CommandSignature(ret, this);

      GetResourceManager()->AddLiveResource(CommandSig, ret);
    }
  }

  return true;
}
bool WrappedVulkan::Serialise_vkResetEvent(
	Serialiser*                                 localSerialiser,
	VkDevice                                    device,
	VkEvent                                     event)
{
	SERIALISE_ELEMENT(ResourceId, id, GetResID(device));
	SERIALISE_ELEMENT(ResourceId, eid, GetResID(event));
		
	Serialise_DebugMessages(localSerialiser, false);
	
	if(m_State < WRITING)
	{
		// see top of this file for current event/fence handling
	}

	return true;
}
Beispiel #18
0
void VulkanCreationInfo::BufferView::Init(VulkanResourceManager *resourceMan,
                                          VulkanCreationInfo &info,
                                          const VkBufferViewCreateInfo *pCreateInfo)
{
  buffer = GetResID(pCreateInfo->buffer);
  offset = pCreateInfo->offset;
  size = pCreateInfo->range;
}
Beispiel #19
0
void VulkanResourceManager::MarkSparseMapReferenced(SparseMapping *sparse)
{
  if(sparse == NULL)
  {
    RDCERR("Unexpected NULL sparse mapping");
    return;
  }

  for(size_t i = 0; i < sparse->opaquemappings.size(); i++)
    MarkResourceFrameReferenced(GetResID(sparse->opaquemappings[i].memory), eFrameRef_Read);

  for(int a = 0; a < NUM_VK_IMAGE_ASPECTS; a++)
    for(VkDeviceSize i = 0;
        sparse->pages[a] &&
        i < VkDeviceSize(sparse->imgdim.width * sparse->imgdim.height * sparse->imgdim.depth);
        i++)
      MarkResourceFrameReferenced(GetResID(sparse->pages[a][i].first), eFrameRef_Read);
}
bool WrappedVulkan::Serialise_vkGetEventStatus(
			Serialiser*                             localSerialiser,
			VkDevice                                device,
			VkEvent                                 event)
{
	SERIALISE_ELEMENT(ResourceId, id, GetResID(device));
	SERIALISE_ELEMENT(ResourceId, eid, GetResID(event));
		
	Serialise_DebugMessages(localSerialiser, false);
	
	if(m_State < WRITING)
	{
		device = GetResourceManager()->GetLiveHandle<VkDevice>(id);

		ObjDisp(device)->DeviceWaitIdle(Unwrap(device));
	}

	return true;
}
Beispiel #21
0
// needs to be separate so we don't erase from m_ImageLayouts in other destroy functions
void WrappedVulkan::vkDestroyImage(VkDevice device, VkImage obj, const VkAllocationCallbacks* pAllocator)
{
	{
		SCOPED_LOCK(m_ImageLayoutsLock);
		m_ImageLayouts.erase(GetResID(obj));
	}
	VkImage unwrappedObj = Unwrap(obj);
	GetResourceManager()->ReleaseWrappedResource(obj, true);
	return ObjDisp(device)->DestroyImage(Unwrap(device), unwrappedObj, pAllocator);
}
Beispiel #22
0
bool WrappedID3D12Device::Serialise_CreatePlacedResource(ID3D12Heap *pHeap, UINT64 HeapOffset,
                                                         const D3D12_RESOURCE_DESC *pDesc,
                                                         D3D12_RESOURCE_STATES InitialState,
                                                         const D3D12_CLEAR_VALUE *pOptimizedClearValue,
                                                         REFIID riid, void **ppvResource)
{
  SERIALISE_ELEMENT(ResourceId, Heap, GetResID(pHeap));
  SERIALISE_ELEMENT(UINT64, Offset, HeapOffset);
  SERIALISE_ELEMENT(D3D12_RESOURCE_DESC, desc, *pDesc);
  SERIALISE_ELEMENT(D3D12_RESOURCE_STATES, state, InitialState);

  SERIALISE_ELEMENT(bool, HasClearValue, pOptimizedClearValue != NULL);
  SERIALISE_ELEMENT_OPT(D3D12_CLEAR_VALUE, clearVal, *pOptimizedClearValue, HasClearValue);

  SERIALISE_ELEMENT(IID, guid, riid);
  SERIALISE_ELEMENT(ResourceId, Res, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID());

  if(m_State == READING)
  {
    pHeap = GetResourceManager()->GetLiveAs<ID3D12Heap>(Heap);
    pOptimizedClearValue = HasClearValue ? &clearVal : NULL;

    ID3D12Resource *ret = NULL;
    HRESULT hr = m_pDevice->CreatePlacedResource(Unwrap(pHeap), Offset, &desc, state,
                                                 pOptimizedClearValue, guid, (void **)&ret);

    if(FAILED(hr))
    {
      RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr);
    }
    else
    {
      ret = new WrappedID3D12Resource(ret, this);

      GetResourceManager()->AddLiveResource(Res, ret);

      SubresourceStateVector &states = m_ResourceStates[GetResID(ret)];
      states.resize(GetNumSubresources(&desc), state);
    }
  }

  return true;
}
VkResult WrappedVulkan::vkMapMemory(
			VkDevice                                    device,
			VkDeviceMemory                              mem,
			VkDeviceSize                                offset,
			VkDeviceSize                                size,
			VkMemoryMapFlags                            flags,
			void**                                      ppData)
{
	void *realData = NULL;
	VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), offset, size, flags, &realData);

	if(ret == VK_SUCCESS && realData)
	{
		ResourceId id = GetResID(mem);

		if(m_State >= WRITING)
		{
			VkResourceRecord *memrecord = GetRecord(mem);

			// must have map state, only non host visible memories have no map
			// state, and they can't be mapped!
			RDCASSERT(memrecord->memMapState);
			MemMapState &state = *memrecord->memMapState;

			// ensure size is valid
			RDCASSERT(size == VK_WHOLE_SIZE || (size > 0 && size <= memrecord->Length));

			state.mappedPtr = (byte *)realData;
			state.refData = NULL;

			state.mapOffset = offset;
			state.mapSize = size == VK_WHOLE_SIZE ? memrecord->Length : size;
			state.mapFlushed = false;

			*ppData = realData;

			if(state.mapCoherent)
			{
				SCOPED_LOCK(m_CoherentMapsLock);
				m_CoherentMaps.push_back(memrecord);
			}
		}
		else
		{
			*ppData = realData;
		}
	}
	else
	{
		*ppData = NULL;
	}

	return ret;
}
Beispiel #24
0
bool WrappedVulkan::Serialise_vkDeviceWaitIdle(Serialiser* localSerialiser, VkDevice device)
{
	SERIALISE_ELEMENT(ResourceId, id, GetResID(device));
	
	if(m_State < WRITING)
	{
		device = GetResourceManager()->GetLiveHandle<VkDevice>(id);
		ObjDisp(device)->DeviceWaitIdle(Unwrap(device));
	}

	return true;
}
bool WrappedVulkan::Serialise_vkCreateBuffer(
		Serialiser*                                 localSerialiser,
			VkDevice                                    device,
			const VkBufferCreateInfo*                   pCreateInfo,
			const VkAllocationCallbacks*                pAllocator,
			VkBuffer*                                   pBuffer)
{
	SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
	SERIALISE_ELEMENT(VkBufferCreateInfo, info, *pCreateInfo);
	SERIALISE_ELEMENT(ResourceId, id, GetResID(*pBuffer));

	if(m_State == READING)
	{
		device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);
		VkBuffer buf = VK_NULL_HANDLE;

		VkBufferUsageFlags origusage = info.usage;

		// ensure we can always readback from buffers
		info.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;

		VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &info, NULL, &buf);

		info.usage = origusage;

		if(ret != VK_SUCCESS)
		{
			RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret);
		}
		else
		{
			ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), buf);
			GetResourceManager()->AddLiveResource(id, buf);

			m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &info);
		}
	}

	return true;
}
bool WrappedVulkan::Serialise_vkUnmapMemory(
		Serialiser*                                 localSerialiser,
    VkDevice                                    device,
    VkDeviceMemory                              mem)
{
	SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
	SERIALISE_ELEMENT(ResourceId, id, GetResID(mem));

	MemMapState *state;
	if(m_State >= WRITING)
		state = GetRecord(mem)->memMapState;

	SERIALISE_ELEMENT(uint64_t, memOffset, state->mapOffset);
	SERIALISE_ELEMENT(uint64_t, memSize, state->mapSize);
	SERIALISE_ELEMENT_BUF(byte*, data, (byte *)state->mappedPtr + state->mapOffset, (size_t)memSize);

	if(m_State < WRITING)
	{
		device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);
		mem = GetResourceManager()->GetLiveHandle<VkDeviceMemory>(id);

		void *mapPtr = NULL;
		VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), memOffset, memSize, 0, &mapPtr);

		if(ret != VK_SUCCESS)
		{
			RDCERR("Error mapping memory on replay: 0x%08x", ret);
		}
		else
		{
			memcpy((byte *)mapPtr, data, (size_t)memSize);

			ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem));
		}

		SAFE_DELETE_ARRAY(data);
	}

	return true;
}
HRESULT STDMETHODCALLTYPE WrappedID3D12CommandQueue::Signal(ID3D12Fence *pFence, UINT64 Value)
{
  if(m_State == WRITING_CAPFRAME)
  {
    SCOPED_SERIALISE_CONTEXT(SIGNAL);
    Serialise_Signal(pFence, Value);

    m_QueueRecord->AddChunk(scope.Get());
    GetResourceManager()->MarkResourceFrameReferenced(GetResID(pFence), eFrameRef_Read);
  }

  return m_pReal->Signal(Unwrap(pFence), Value);
}
Beispiel #28
0
ResourceId D3D12RenderState::GetDSVID() const
{
  if(dsv.heap != ResourceId())
  {
    const D3D12Descriptor *desc = DescriptorFromPortableHandle(GetResourceManager(), dsv);

    RDCASSERT(desc->GetType() == D3D12Descriptor::TypeDSV);

    return GetResID(desc->nonsamp.resource);
  }

  return ResourceId();
}
bool WrappedVulkan::Serialise_vkResetFences(
			Serialiser*                             localSerialiser,
			VkDevice                                device,
			uint32_t                                fenceCount,
			const VkFence*                          pFences)
{
	SERIALISE_ELEMENT(ResourceId, id, GetResID(device));
	SERIALISE_ELEMENT(uint32_t, count, fenceCount);
	
	Serialise_DebugMessages(localSerialiser, false);
	
	vector<VkFence> fences;

	for(uint32_t i=0; i < count; i++)
	{
		ResourceId fence;
		if(m_State >= WRITING)
			fence = GetResID(pFences[i]);

		localSerialiser->Serialise("pFences[]", fence);
		
		if(m_State < WRITING && GetResourceManager()->HasLiveResource(fence))
			fences.push_back(Unwrap(GetResourceManager()->GetLiveHandle<VkFence>(fence)));
	}

	if(m_State < WRITING && !fences.empty())
	{
		// we don't care about fence states ourselves as we cannot record them perfectly and just
		// do full waitidle flushes.
		device = GetResourceManager()->GetLiveHandle<VkDevice>(id);

		// since we don't have anything signalling or waiting on fences, don't bother to reset them
		// either
		//ObjDisp(device)->ResetFences(Unwrap(device), (uint32_t)fences.size(), &fences[0]);
	}

	return true;
}
bool WrappedVulkan::Serialise_vkWaitForFences(
			Serialiser*                             localSerialiser,
			VkDevice                                device,
			uint32_t                                fenceCount,
			const VkFence*                          pFences,
			VkBool32                                waitAll,
			uint64_t                                timeout)
{
	SERIALISE_ELEMENT(ResourceId, id, GetResID(device));
	SERIALISE_ELEMENT(VkBool32, wait, waitAll);
	SERIALISE_ELEMENT(uint64_t, tmout, timeout);
	SERIALISE_ELEMENT(uint32_t, count, fenceCount);
		
	Serialise_DebugMessages(localSerialiser, false);
	
	vector<VkFence> fences;

	for(uint32_t i=0; i < count; i++)
	{
		ResourceId fence;
		if(m_State >= WRITING)
			fence = GetResID(pFences[i]);

		localSerialiser->Serialise("pFences[]", fence);

		if(m_State < WRITING && GetResourceManager()->HasLiveResource(fence))
			fences.push_back(Unwrap(GetResourceManager()->GetLiveHandle<VkFence>(fence)));
	}

	if(m_State < WRITING)
	{
		device = GetResourceManager()->GetLiveHandle<VkDevice>(id);

		ObjDisp(device)->DeviceWaitIdle(Unwrap(device));
	}

	return true;
}