Removed intermediate copy between atlas and sensor. Cleaned code.

This commit is contained in:
doterop 2020-07-29 16:13:05 +02:00 committed by bernat
parent a6fbd3bfe2
commit 797db914e1
10 changed files with 53 additions and 199 deletions

View File

@ -193,10 +193,7 @@ void ACarlaGameModeBase::BeginPlay()
Recorder->GetReplayer()->CheckPlayAfterMapLoaded();
}
// OnBeginFrame
// OnEndFrame
CaptureAtlasDelegate = FCoreDelegates::OnBeginFrame.AddUObject(this, &ACarlaGameModeBase::CaptureAtlas);
// SendAtlasDelegate = FCoreDelegates::OnEndFrame.AddUObject(this, &ACarlaGameModeBase::SendAtlas);
CaptureAtlasDelegate = FCoreDelegates::OnEndFrame.AddUObject(this, &ACarlaGameModeBase::CaptureAtlas);
}
@ -223,25 +220,7 @@ void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
CarlaSettingsDelegate->Reset();
}
// TODO: improve this delete processs; not multithread friendly
/*
while(!AtlasCopyRequestQueue.IsEmpty())
{
delete AtlasCopyRequestQueue.Peek();
AtlasCopyRequestQueue.Pop();
}
while(!AtlasCopyRequestsQueuePool.IsEmpty())
{
delete AtlasCopyRequestsQueuePool.Peek();
AtlasCopyRequestsQueuePool.Pop();
}
*/
// OnEndFrame
FCoreDelegates::OnEndFrame.Remove(CaptureAtlasDelegate);
//FCoreDelegates::OnEndFrame.Remove(SendAtlasDelegate);
}
void ACarlaGameModeBase::SpawnActorFactories()
@ -396,39 +375,20 @@ void ACarlaGameModeBase::DebugShowSignals(bool enable)
}
}
/*
FAtlasCopyRequest* ACarlaGameModeBase::GetAtlasCopyRequest()
{
if(AtlasCopyRequestsQueuePool.IsEmpty()) {
UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::GetAtlasCopyRequest new FAtlasCopyRequest"));
return new FAtlasCopyRequest();
}
FAtlasCopyRequest* AtlasCopyRequest = nullptr;
AtlasCopyRequestsQueuePool.Dequeue(AtlasCopyRequest);
return AtlasCopyRequest;
}
*/
void ACarlaGameModeBase::CreateAtlasTextures()
{
if(AtlasTextureWidth > 0 && AtlasTextureHeight > 0)
{
UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::CreateAtlasTextures %d %dx%d"), SceneCaptureSensors.Num(), AtlasTextureWidth, AtlasTextureHeight);
FRHIResourceCreateInfo CreateInfo;
CamerasAtlasTexture = RHICreateTexture2D(AtlasTextureWidth, AtlasTextureHeight, PF_B8G8R8A8, 1, 1, TexCreate_CPUReadback, CreateInfo);
for(int i = 0; i < kMaxNumTextures; i++)
{
AtlasImage[i].Init(FColor(), AtlasTextureWidth * AtlasTextureHeight);
// Prepare some AtlasCopyRequests
//AtlasCopyRequestQueue.Enqueue(new FAtlasCopyRequest());
}
AtlasImage.Init(FColor(), AtlasTextureWidth * AtlasTextureHeight);
IsAtlasTextureValid = true;
}
}
//extern FDynamicRHI* GDynamicRHI;
void ACarlaGameModeBase::CaptureAtlas()
{
@ -448,16 +408,6 @@ void ACarlaGameModeBase::CaptureAtlas()
Sensor->CopyTextureToAtlas();
}
//if (!AtlasCopyRequestQueue.IsEmpty())
//{
// UE_LOG(LogCarla, Error, TEXT("ACarlaGameModeBase::CaptureAtlas: request full"));
// return;
//}
//UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::CaptureAtlas: creating request"));
//FAtlasCopyRequest* AtlasCopyRequest = GetAtlasCopyRequest();
//AtlasCopyRequest->ResizeBuffer(AtlasTextureWidth, AtlasTextureHeight);
// Download Atlas texture
ENQUEUE_RENDER_COMMAND(ACarlaGameModeBase_CaptureAtlas)
(
@ -476,7 +426,6 @@ void ACarlaGameModeBase::CaptureAtlas()
#if !UE_BUILD_SHIPPING
if(This->ReadSurfaceMode == 2) Rect = FIntRect(0, 0, This->SurfaceW, This->SurfaceH);
#endif
// GDynamicRHI->RHIReadSurfaceData(AtlasTexture, Rect, CurrentAtlasPixels, FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX));
#if !UE_BUILD_SHIPPING
if (This->ReadSurfaceMode == 0) return;
@ -486,68 +435,29 @@ void ACarlaGameModeBase::CaptureAtlas()
RHICmdList.ReadSurfaceData(
AtlasTexture,
Rect,
This->AtlasImage[This->CurrentAtlas],
This->AtlasImage,
FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX));
This->PreviousAtlas = This->CurrentAtlas;
This->CurrentAtlas = (This->CurrentAtlas + 1) & ~kMaxNumTextures;
}
);
//AtlasCopyRequest->Start();
// AtlasCopyRequest->Wait();
//AtlasCopyRequestQueue.Enqueue(AtlasCopyRequest);
SendAtlas();
}
void ACarlaGameModeBase::SendAtlas()
{
//if(!AtlasCopyRequestQueue.IsEmpty())
{
//FAtlasCopyRequest* AtlasCopyRequest = nullptr;
//AtlasCopyRequestQueue.Peek(AtlasCopyRequest);
// Be sure that the request has finished
//if( AtlasCopyRequest && AtlasCopyRequest->IsComplete() )
{
//UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::SendAtlas: DONE"));
#if !UE_BUILD_SHIPPING
if(!AtlasCopyToCamera)
{
//AtlasCopyRequestQueue.Pop();
//AtlasCopyRequestsQueuePool.Enqueue(AtlasCopyRequest);
return;
}
if(!AtlasCopyToCamera)
{
return;
}
#endif
ACarlaGameModeBase* This = this;
// We need to make a copy of the atlas to avoid possible threads issues later
// since the AtlasCopyRequest could be used later
//TArray<FColor> AtlasImage(AtlasCopyRequest->AtlasImage);
//ParallelFor(SceneCaptureSensors.Num(),
// [This, &AtlasImage](int32 Index)
for(int32 Index = 0; Index < SceneCaptureSensors.Num(); Index++)
{
ASceneCaptureSensor* Sensor = SceneCaptureSensors[Index];
// TODO: merge this functions and avoid double copy
Sensor->CopyTextureFromAtlas(AtlasImage[PreviousAtlas], AtlasTextureWidth);
Sensor->SendPixels();
}
//);
// Remove from pending queue ...
//AtlasCopyRequestQueue.Pop();
// ... add to pool
//AtlasCopyRequestsQueuePool.Enqueue(AtlasCopyRequest);
}
//else
{
//UE_LOG(LogCarla, Error, TEXT("ACarlaGameModeBase::SendAtlas: request didn't finish"));
}
for(int32 Index = 0; Index < SceneCaptureSensors.Num(); Index++)
{
ASceneCaptureSensor* Sensor = SceneCaptureSensors[Index];
Sensor->SendPixels(AtlasImage, AtlasTextureWidth);
}
}

View File

@ -26,47 +26,6 @@
#include "CarlaGameModeBase.generated.h"
/*
USTRUCT()
struct FAtlasCopyRequest
{
GENERATED_BODY()
void ResizeBuffer(uint32 Width, uint32 Height)
{
if(AtlasTextureWidth != Width || AtlasTextureHeight != Height)
{
UE_LOG(LogCarla, Warning, TEXT("FAtlasCopyRequest::ResizeBuffer %dx%d"), Width, Height);
AtlasTextureWidth = Width;
AtlasTextureHeight = Height;
AtlasImage.Init(FColor(), Width * Height);
}
}
void Start()
{
RenderFence.BeginFence(true);
}
void Wait()
{
RenderFence.Wait(false);
}
bool IsComplete()
{
return RenderFence.IsFenceComplete();
}
TArray<FColor> AtlasImage;
FRenderCommandFence RenderFence;
uint32 AtlasTextureWidth = 0u;
uint32 AtlasTextureHeight = 0u;
};
*/
/// Base class for the CARLA Game Mode.
UCLASS(HideCategories=(ActorTick))
class CARLA_API ACarlaGameModeBase : public AGameModeBase
@ -221,23 +180,13 @@ private:
boost::optional<carla::road::Map> Map;
FDelegateHandle CaptureAtlasDelegate;
FDelegateHandle SendAtlasDelegate;
//TQueue<FAtlasCopyRequest*> AtlasCopyRequestQueue;
//TQueue<FAtlasCopyRequest*> AtlasCopyRequestsQueuePool;
// TODO: clean
// TODO: remove kMaxNumTextures and current/prev index
static const uint32 kMaxNumTextures = 1u; // This has to be POT
TArray<ASceneCaptureSensor*> SceneCaptureSensors;
FTexture2DRHIRef CamerasAtlasTexture;
TArray<FColor> AtlasImage[kMaxNumTextures];
TArray<FColor> AtlasImage;
uint32 AtlasTextureWidth = 0u;
uint32 AtlasTextureHeight = 0u;
uint32 CurrentAtlasTextureHeight = 0u;
uint32 CurrentAtlas = 0u;
uint32 PreviousAtlas = 0u;
bool IsAtlasTextureValid = false;
#if !UE_BUILD_SHIPPING

View File

@ -30,12 +30,12 @@ ADepthCamera::ADepthCamera(const FObjectInitializer &ObjectInitializer)
Offset = carla::sensor::SensorRegistry::get<ADepthCamera*>::type::header_offset;
}
void ADepthCamera::SendPixels()
void ADepthCamera::SendPixels(const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth)
{
#if !UE_BUILD_SHIPPING
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
if(!GameMode->IsCameraStreamEnabled()) return;
#endif
SendPixelsInStream(*this);
SendPixelsInStream(*this, AtlasImage, AtlasTextureWidth);
}

View File

@ -26,5 +26,5 @@ public:
protected:
void SendPixels() override;
void SendPixels(const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth) override;
};

View File

@ -24,12 +24,12 @@ ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer &ObjectInitial
Offset = carla::sensor::SensorRegistry::get<ASceneCaptureCamera*>::type::header_offset;
}
void ASceneCaptureCamera::SendPixels()
void ASceneCaptureCamera::SendPixels(const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth)
{
#if !UE_BUILD_SHIPPING
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
if(!GameMode->IsCameraStreamEnabled()) return;
#endif
SendPixelsInStream(*this);
SendPixelsInStream(*this, AtlasImage, AtlasTextureWidth);
}

View File

@ -26,6 +26,6 @@ public:
protected:
void SendPixels() override;
void SendPixels(const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth) override;
};

View File

@ -484,19 +484,14 @@ void ASceneCaptureSensor::BeginPlay()
Super::BeginPlay();
//CopyTextureDelegate = FCoreDelegates::OnEndFrame.AddUObject(this, &ASceneCaptureCamera::CopyTextureToAtlas);
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
GameMode->AddSceneCaptureSensor(this);
ImageToSend.Init(FColor(), ImageWidth * ImageHeight);
}
void ASceneCaptureSensor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// TODO: can I remove this?
// Add the view information every tick. Its only used for one tick and then
// removed by the streamer.
@ -505,7 +500,6 @@ void ASceneCaptureSensor::Tick(float DeltaTime)
ImageWidth,
ImageWidth / FMath::Tan(CaptureComponent2D->FOVAngle));
// UE_LOG(LogCarla, Warning, TEXT("ASceneCaptureSensor::Tick"));
}
void ASceneCaptureSensor::EndPlay(const EEndPlayReason::Type EndPlayReason)
@ -513,7 +507,6 @@ void ASceneCaptureSensor::EndPlay(const EEndPlayReason::Type EndPlayReason)
Super::EndPlay(EndPlayReason);
SCENE_CAPTURE_COUNTER = 0u;
FCoreDelegates::OnEndFrame.Remove(CopyTextureDelegate);
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
GameMode->RemoveSceneCaptureSensor(this);
}
@ -562,32 +555,38 @@ void ASceneCaptureSensor::CopyTextureToAtlas()
);
}
void ASceneCaptureSensor::CopyTextureFromAtlas(const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth)
bool ASceneCaptureSensor::CopyTextureFromAtlas(
carla::Buffer &Buffer,
const TArray<FColor>& AtlasImage,
uint32 AtlasTextureWidth)
{
// Check that the atlas alreay contains our texture
// and our image has been initialized
if(AtlasImage.Num() < (PositionInAtlas.Y * AtlasTextureWidth + ImageWidth * ImageHeight) ||
ImageToSend.Num() <= 0)
if(AtlasImage.GetData() &&
AtlasImage.Num() < (PositionInAtlas.Y * AtlasTextureWidth + ImageWidth * ImageHeight))
{
return;
return false;
}
SCOPE_CYCLE_COUNTER(STAT_CarlaSensorBufferCopy);
const FColor* SourceFColor = AtlasImage.GetData() + PositionInAtlas.Y * AtlasTextureWidth;
const uint8* Source = (uint8*)SourceFColor;
uint32 Dest = Offset;
const uint32 DstStride = ImageWidth * sizeof(FColor);
const uint32 SrcStride = AtlasTextureWidth * sizeof(FColor);
Buffer.reset(Offset + ImageHeight * DstStride);
for(uint32 i = 0; i < ImageHeight; i++)
{
SCOPE_CYCLE_COUNTER(STAT_CarlaSensorBufferCopy);
const FColor* SourceFColor = &AtlasImage[0] + PositionInAtlas.Y * AtlasTextureWidth;
const uint8* Source = (uint8*)SourceFColor;
uint8* Dest = (uint8*)ImageToSend.GetData();
for(uint32 i = 0; i < ImageHeight; i++)
{
FMemory::Memcpy(Dest, Source, ImageWidth * sizeof(FColor));
Source += AtlasTextureWidth * sizeof(FColor);
Dest += ImageWidth * sizeof(FColor);
}
Buffer.copy_from(Dest, Source, DstStride);
Source += SrcStride;
Dest += DstStride;
}
return true;
}
// =============================================================================

View File

@ -272,20 +272,20 @@ public:
void CopyTextureToAtlas();
void CopyTextureFromAtlas(const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth);
bool CopyTextureFromAtlas(carla::Buffer &Buffer, const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth);
virtual void SendPixels() {}
virtual void SendPixels(const TArray<FColor>& /* AtlasImage */, uint32 /* AtlasTextureWidth */) {}
template <typename TSensor>
void SendPixelsInStream(TSensor &Sensor)
void SendPixelsInStream(TSensor &Sensor, const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth)
{
if(ImageToSend.Num() > 0)
auto Stream = GetDataStream(Sensor);
auto Buffer = Stream.PopBufferFromPool();
if(CopyTextureFromAtlas(Buffer, AtlasImage, AtlasTextureWidth))
{
{
SCOPE_CYCLE_COUNTER(STAT_CarlaSensorStreamSend);
auto Stream = GetDataStream(Sensor);
auto Buffer = Stream.PopBufferFromPool();
Buffer.copy_from(Offset, ImageToSend);
Stream.Send(Sensor, std::move(Buffer));
}
}
@ -301,10 +301,6 @@ protected:
virtual void SetUpSceneCaptureComponent(USceneCaptureComponent2D &SceneCapture) {}
FDelegateHandle CopyTextureDelegate;
TArray<FColor> ImageToSend;
/// Render target necessary for scene capture.
UPROPERTY(EditAnywhere)
UTextureRenderTarget2D *CaptureRenderTarget = nullptr;

View File

@ -26,12 +26,12 @@ ASemanticSegmentationCamera::ASemanticSegmentationCamera(
Offset = carla::sensor::SensorRegistry::get<ASemanticSegmentationCamera*>::type::header_offset;
}
void ASemanticSegmentationCamera::SendPixels()
void ASemanticSegmentationCamera::SendPixels(const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth)
{
#if !UE_BUILD_SHIPPING
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
if(!GameMode->IsCameraStreamEnabled()) return;
#endif
SendPixelsInStream(*this);
SendPixelsInStream(*this, AtlasImage, AtlasTextureWidth);
}

View File

@ -26,5 +26,5 @@ public:
protected:
void SendPixels() override;
void SendPixels(const TArray<FColor>& AtlasImage, uint32 AtlasTextureWidth) override;
};