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;
}
bool WrappedID3D12Device::Serialise_CreateCommittedResource(
    const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags,
    const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState,
    const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riidResource, void **ppvResource)
{
  SERIALISE_ELEMENT(D3D12_HEAP_PROPERTIES, props, *pHeapProperties);
  SERIALISE_ELEMENT(D3D12_HEAP_FLAGS, flags, HeapFlags);
  SERIALISE_ELEMENT(D3D12_RESOURCE_DESC, desc, *pDesc);
  SERIALISE_ELEMENT(D3D12_RESOURCE_STATES, state, InitialResourceState);

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

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

  if(m_State == READING)
  {
    pOptimizedClearValue = HasClearValue ? &clearVal : NULL;

    ID3D12Resource *ret = NULL;
    HRESULT hr = m_pDevice->CreateCommittedResource(&props, flags, &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;
}
bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(ID3D11Resource *pDstResource, UINT DstSubresource, const D3D11_BOX *pDstBox,
																const void *pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch, UINT CopyFlags)
{
	SERIALISE_ELEMENT(ResourceId, idx, GetIDForResource(pDstResource));
	SERIALISE_ELEMENT(uint32_t, flags, CopyFlags);
	SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource);
	
	D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(idx);

	D3D11ResourceRecord *parent = record;

	if(record && record->NumSubResources > (int)DestSubresource)
		record = (D3D11ResourceRecord *)record->SubResources[DestSubresource];

	SERIALISE_ELEMENT(uint8_t, isUpdate, record->DataInSerialiser);

	ID3D11Resource *DestResource = pDstResource;
	if(m_State < WRITING)
	{
		if(m_pDevice->GetResourceManager()->HasLiveResource(idx))
			DestResource = (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(idx);
	}

	if(isUpdate)
	{
		SERIALISE_ELEMENT(uint8_t, HasDestBox, pDstBox != NULL);
		SERIALISE_ELEMENT_OPT(D3D11_BOX, box, *pDstBox, HasDestBox);
		SERIALISE_ELEMENT(uint32_t, SourceRowPitch, SrcRowPitch);
		SERIALISE_ELEMENT(uint32_t, SourceDepthPitch, SrcDepthPitch);

		size_t srcLength = 0;

		if(m_State >= WRITING)
		{
			RDCASSERT(record);
			
			if(WrappedID3D11Buffer::IsAlloc(DestResource))
			{
				srcLength = record->Length;

				if(HasDestBox)
					srcLength = RDCMIN((uint32_t)srcLength, pDstBox->right - pDstBox->left);
			}
			else
			{
				WrappedID3D11Texture1D *tex1 = WrappedID3D11Texture1D::IsAlloc(DestResource) ? (WrappedID3D11Texture1D *)DestResource : NULL;
				WrappedID3D11Texture2D *tex2 = WrappedID3D11Texture2D::IsAlloc(DestResource) ? (WrappedID3D11Texture2D *)DestResource : NULL;
				WrappedID3D11Texture3D *tex3 = WrappedID3D11Texture3D::IsAlloc(DestResource) ? (WrappedID3D11Texture3D *)DestResource : NULL;

				UINT mipLevel = GetMipForSubresource(DestResource, DestSubresource);

				if(tex1)
				{
					srcLength = record->Length;

					if(HasDestBox)
						srcLength = RDCMIN((uint32_t)srcLength, pDstBox->right - pDstBox->left);
				}
				else if(tex2)
				{
					D3D11_TEXTURE2D_DESC desc = {0};
					tex2->GetDesc(&desc);
					size_t rows = RDCMAX(1U,desc.Height>>mipLevel);
					DXGI_FORMAT fmt = desc.Format;
					
					if(HasDestBox)
						rows = (pDstBox->bottom - pDstBox->top);

					if(IsBlockFormat(fmt))
						rows = RDCMAX((size_t)1, rows/4);

					srcLength = SourceRowPitch*rows;
				}
				else if(tex3)
				{
					D3D11_TEXTURE3D_DESC desc = {0};
					tex3->GetDesc(&desc);
					size_t slices = RDCMAX(1U,desc.Depth>>mipLevel);

					srcLength = SourceDepthPitch*slices;

					if(HasDestBox)
						srcLength = SourceDepthPitch*(pDstBox->back - pDstBox->front);
				}
				else
				{
					RDCERR("UpdateSubResource on unexpected resource type");
				}
			}