void RenderAPI_D3D12::EndModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int rowPitch, void* dataPtr)
{
	ID3D12Device* device = s_D3D12->GetDevice();

	const UINT64 kDataSize = textureWidth * textureHeight * 4;
	ID3D12Resource* upload = GetUploadResource(kDataSize);
	upload->Unmap(0, NULL);

	ID3D12Resource* resource = (ID3D12Resource*)textureHandle;
	D3D12_RESOURCE_DESC desc = resource->GetDesc();
	assert(desc.Width == textureWidth);
	assert(desc.Height == textureHeight);

	D3D12_TEXTURE_COPY_LOCATION srcLoc = {};
	srcLoc.pResource = upload;
	srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
	device->GetCopyableFootprints(&desc, 0, 1, 0, &srcLoc.PlacedFootprint, nullptr, nullptr, nullptr);

	D3D12_TEXTURE_COPY_LOCATION dstLoc = {};
	dstLoc.pResource = resource;
	dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
	dstLoc.SubresourceIndex = 0;

	// We inform Unity that we expect this resource to be in D3D12_RESOURCE_STATE_COPY_DEST state,
	// and because we do not barrier it ourselves, we tell Unity that no changes are done on our command list.
	UnityGraphicsD3D12ResourceState resourceState = {};
	resourceState.resource = resource;
	resourceState.expected = D3D12_RESOURCE_STATE_COPY_DEST;
	resourceState.current = D3D12_RESOURCE_STATE_COPY_DEST;

	// Queue data upload
	s_D3D12CmdList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr);

	// Execute the command list
	s_D3D12CmdList->Close();
	s_D3D12FenceValue = s_D3D12->ExecuteCommandList(s_D3D12CmdList, 1, &resourceState);
}