Files
UnrealEngineUWP/Engine/Source/Runtime/SlateRHIRenderer/Private/SlateUpdatableBuffer.cpp
Andrew Davidson 45edf67938 Merging //UE5/Dev-LargeWorldCoordinates @ 17581892 to //UE5/Main
[CL 17595295 by Andrew Davidson in ue5-main branch]
2021-09-22 10:00:43 -04:00

69 lines
2.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SlateUpdatableBuffer.h"
#include "RenderingThread.h"
DECLARE_CYCLE_STAT(TEXT("UpdateInstanceBuffer Time (RT)"), STAT_SlateUpdateInstanceBuffer_RT, STATGROUP_Slate);
DECLARE_CYCLE_STAT(TEXT("UpdateInstanceBuffer Time (RHIT)"), STAT_SlateUpdateInstanceBuffer_RHIT, STATGROUP_Slate);
FSlateUpdatableInstanceBuffer::FSlateUpdatableInstanceBuffer(int32 InitialInstanceCount)
{
Proxy = new FRenderProxy;
Proxy->InstanceBufferResource.Init(InitialInstanceCount);
}
FSlateUpdatableInstanceBuffer::~FSlateUpdatableInstanceBuffer()
{
ENQUEUE_RENDER_COMMAND(SlateUpdatableInstanceBuffer_DeleteProxy)(
[Ptr = Proxy](FRHICommandListImmediate&)
{
delete Ptr;
});
Proxy = nullptr;
}
void FSlateUpdatableInstanceBuffer::Update(FSlateInstanceBufferData& Data)
{
check(IsThreadSafeForSlateRendering());
NumInstances = Data.Num();
if (NumInstances > 0)
{
// Enqueue a render thread command to update the proxy with the new data.
ENQUEUE_RENDER_COMMAND(SlateUpdatableInstanceBuffer_Update)(
[Ptr = Proxy, LocalDataRT = MoveTemp(Data)](FRHICommandListImmediate& RHICmdList) mutable
{
Ptr->Update(RHICmdList, LocalDataRT);
});
}
}
void FSlateUpdatableInstanceBuffer::FRenderProxy::Update(FRHICommandListImmediate& RHICmdList, FSlateInstanceBufferData& Data)
{
SCOPE_CYCLE_COUNTER(STAT_SlateUpdateInstanceBuffer_RT);
InstanceBufferResource.PreFillBuffer(Data.Num(), false);
// Enqueue the lock/unlock to the RHI thread
FRHIBuffer* VertexBuffer = InstanceBufferResource.VertexBufferRHI;
RHICmdList.EnqueueLambda([VertexBuffer, LocalData = MoveTemp(Data)](FRHICommandListImmediate& InRHICmdList)
{
SCOPE_CYCLE_COUNTER(STAT_SlateUpdateInstanceBuffer_RHIT);
int32 RequiredVertexBufferSize = LocalData.Num() * LocalData.GetTypeSize();
uint8* InstanceBufferData = (uint8*)InRHICmdList.LockBuffer(VertexBuffer, 0, RequiredVertexBufferSize, RLM_WriteOnly);
FMemory::Memcpy(InstanceBufferData, LocalData.GetData(), RequiredVertexBufferSize);
InRHICmdList.UnlockBuffer(VertexBuffer);
});
RHICmdList.RHIThreadFence(true);
}
void FSlateUpdatableInstanceBuffer::FRenderProxy::BindStreamSource(FRHICommandList& RHICmdList, int32 StreamIndex, uint32 InstanceOffset)
{
RHICmdList.SetStreamSource(StreamIndex, InstanceBufferResource.VertexBufferRHI, InstanceOffset * sizeof(FVector4f));
}