Exemplo n.º 1
0
void FD3D12Adapter::AllocateBuffer(FD3D12Device* Device,
	const D3D12_RESOURCE_DESC& InDesc,
	uint32 Size,
	uint32 InUsage,
	FRHIResourceCreateInfo& CreateInfo,
	uint32 Alignment,
	FD3D12ResourceLocation& ResourceLocation)
{
	// Explicitly check that the size is nonzero before allowing CreateBuffer to opaquely fail.
	check(Size > 0);

	const bool bIsDynamic = (InUsage & BUF_AnyDynamic) ? true : false;

	if (bIsDynamic)
	{
		void* pData = GetUploadHeapAllocator().AllocUploadResource(Size, Alignment, ResourceLocation);
		check(ResourceLocation.GetSize() == Size);

		if (CreateInfo.ResourceArray)
		{
			const void* InitialData = CreateInfo.ResourceArray->GetResourceData();

			check(Size == CreateInfo.ResourceArray->GetResourceDataSize());
			// Handle initial data
			FMemory::Memcpy(pData, InitialData, Size);
		}
	}
	else
	{
		VERIFYD3D12RESULT(Device->GetDefaultBufferAllocator().AllocDefaultResource(InDesc, ResourceLocation, Alignment));
		check(ResourceLocation.GetSize() == Size);
	}
}
FD3D12ResourceLocation* FD3D12DynamicRHI::CreateBuffer(FRHICommandListImmediate* RHICmdList, const D3D12_RESOURCE_DESC Desc, uint32 Size, uint32 InUsage, FRHIResourceCreateInfo& CreateInfo, uint32 Alignment)
{
	// Explicitly check that the size is nonzero before allowing CreateBuffer to opaquely fail.
	check(Size > 0);

	const bool bIsDynamic = (InUsage & BUF_AnyDynamic) ? true : false;

	FD3D12ResourceLocation* ResourceLocation = new FD3D12ResourceLocation(GetRHIDevice());

	// If a resource array was provided for the resource, create the resource pre-populated
	D3D12_SUBRESOURCE_DATA InitData = { 0 };
	D3D12_SUBRESOURCE_DATA* pInitData = nullptr;
	if (CreateInfo.ResourceArray)
	{
		check(Size == CreateInfo.ResourceArray->GetResourceDataSize());
		InitData.pData = CreateInfo.ResourceArray->GetResourceData();
		InitData.RowPitch = Size;
		InitData.SlicePitch = 0;
		pInitData = &InitData;
	}

	if (bIsDynamic)
	{
		void* pData = GetRHIDevice()->GetDefaultUploadHeapAllocator().AllocUploadResource(Size, Alignment, ResourceLocation);
		check(ResourceLocation->GetEffectiveBufferSize() == Size);

		if (pInitData)
		{
			// Handle initial data
			FMemory::Memcpy(pData, InitData.pData, Size);
		}
	}
	else
	{
		if (RHICmdList && pInitData)
		{
			// We only need to synchronize when creating default resource buffers (because we need a command list to initialize them)
			FScopedRHIThreadStaller StallRHIThread(*RHICmdList);

			VERIFYD3D11RESULT(GetRHIDevice()->GetDefaultBufferAllocator().AllocDefaultResource(Desc, pInitData, ResourceLocation, Alignment));
		}
		else
		{
			VERIFYD3D11RESULT(GetRHIDevice()->GetDefaultBufferAllocator().AllocDefaultResource(Desc, pInitData, ResourceLocation, Alignment));
		}
		check(ResourceLocation->GetEffectiveBufferSize() == Size);
	}

	if (CreateInfo.ResourceArray)
	{
		// Discard the resource array's contents.
		CreateInfo.ResourceArray->Discard();
	}

	return ResourceLocation;
}
void FD3D12DynamicRHI::UnlockBuffer(FRHICommandListImmediate* RHICmdList, BufferType* Buffer)
{
	// Find the outstanding lock for this Buffer.
	FD3D12LockedKey LockedKey(Buffer);
	FD3D12LockedData* LockedData = FindInOutstandingLocks(LockedKey);
	check(LockedData);

	// Determine whether the buffer is dynamic or not.
	const bool bIsDynamic = (Buffer->GetUsage() & BUF_AnyDynamic) ? true : false;

	if (bIsDynamic)
	{
		// If the Buffer is dynamic, its upload heap memory can always stay mapped. Don't do anything.
	}
	else
	{
		// If the static Buffer lock involved a staging resource, it was locked for reading.
		if (LockedData->StagingResource)
		{
			// Unmap the staging buffer's memory.
			ID3D12Resource* StagingBuffer = LockedData->StagingResource.GetReference()->GetResource();
			StagingBuffer->Unmap(0, nullptr);
		}
		else
		{
			// Copy the contents of the temporary memory buffer allocated for writing into the Buffer.
			FD3D12ResourceLocation* UploadHeapLocation = LockedData->UploadHeapLocation.GetReference();

			// If we are on the render thread, queue up the copy on the RHIThread so it happens at the correct time.
			if (ShouldDeferBufferLockOperation(RHICmdList))
			{
				new (RHICmdList->AllocCommand<FRHICommandUpdateBuffer>()) FRHICommandUpdateBuffer(Buffer->ResourceLocation, UploadHeapLocation, LockedData->Pitch);
			}
			else
			{
				UpdateBuffer(Buffer->ResourceLocation->GetResource(),
					Buffer->ResourceLocation->GetOffset(), UploadHeapLocation->GetResource(), UploadHeapLocation->GetOffset(), LockedData->Pitch);
			}
		}
	}

	// Remove the FD3D12LockedData from the lock map.
	// If the lock involved a staging resource, this releases it.
	RemoveFromOutstandingLocks(LockedKey);
}
Exemplo n.º 4
0
	void Execute(FRHICommandListBase& CmdList)
	{
		FD3D12DynamicRHI::GetD3DRHI()->UpdateBuffer(Destination->GetResource(), Destination->GetOffsetFromBaseOfResource() + DestinationOffset, Source.GetResource(), Source.GetOffsetFromBaseOfResource(), NumBytes);
	}