Files
UnrealEngineUWP/Engine/Source/Runtime/RenderCore/Private/RenderCaptureInterface.cpp
luke thatcher 7ec6ef81f5 New GPU profiler improvements. The TStatId on FRHIBreadcrumb has been replaced with a FRHIBreadcrumbData struct that holds additional profiling related data, which includes:
- The TStatId for "stat gpu" stats.
 - The FName required by the CSV profiler for GPU stats.
 - The source file and line number to allow breadcrumbs shown in Insights to link back to their original source location.

Additional changes:
 - Added temporary support for the Insights GPU track. This is guarded by RHI_TEMP_USE_GPU_TRACE until we have a newer, more capable API.
 - Simplified FMeshDrawEvent into a standard RHI breadcrumb in FMeshDrawCommand::SubmitDraw().
 - Moved "r.GPUCsvStatsEnabled" cvar into GPUProfiler.cpp, so it is accessible to both old and new profilers.

#jira UE-177299
#rb mihnea.balta

[CL 35973862 by luke thatcher in ue5-main branch]
2024-09-03 14:10:13 -04:00

154 lines
4.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "RenderCaptureInterface.h"
#include "IRenderCaptureProvider.h"
#include "RenderGraphBuilder.h"
#include "RenderingThread.h"
namespace RenderCaptureInterface
{
FScopedCapture::FScopedCapture(bool bEnable, TCHAR const* InEventName, TCHAR const* InFileName)
: bCapture(bEnable && IRenderCaptureProvider::IsAvailable())
, bEvent(InEventName != nullptr)
, RHICommandList(nullptr)
, GraphBuilder(nullptr)
{
check(!GIsThreadedRendering || !IsInRenderingThread());
if (bCapture)
{
#if WITH_RHI_BREADCRUMBS
RHIBreadcrumb = MakeUnique<TOptional<FRHIBreadcrumbEventManual>>();
#endif
ENQUEUE_RENDER_COMMAND(BeginCaptureCommand)([
FileName = FString(InFileName)
#if WITH_RHI_BREADCRUMBS
, EventName = FString(InEventName)
, Breadcrumb = RHIBreadcrumb.Get()
, bPushEvent = bEvent
#endif
](FRHICommandListImmediate& RHICommandListLocal)
{
IRenderCaptureProvider::Get().BeginCapture(&RHICommandListLocal, IRenderCaptureProvider::ECaptureFlags_Launch, FileName);
#if WITH_RHI_BREADCRUMBS
if (bPushEvent)
{
Breadcrumb->Emplace(RHICommandListLocal, FRHIBreadcrumbData(__FILE__, __LINE__, TStatId(), NAME_None), TEXT("%s"), EventName);
}
#endif
});
}
}
FScopedCapture::FScopedCapture(bool bEnable, FRHICommandList* InRHICommandList, TCHAR const* InEventName, TCHAR const* InFileName)
: bCapture(bEnable && IRenderCaptureProvider::IsAvailable() && InRHICommandList->IsImmediate())
, bEvent(InEventName != nullptr)
, RHICommandList(InRHICommandList)
, GraphBuilder(nullptr)
{
if (bCapture)
{
check(!GIsThreadedRendering || IsInRenderingThread());
IRenderCaptureProvider::Get().BeginCapture(&FRHICommandListImmediate::Get(*RHICommandList), IRenderCaptureProvider::ECaptureFlags_Launch, FString(InFileName));
#if WITH_RHI_BREADCRUMBS
if (bEvent)
{
RHIBreadcrumb = MakeUnique<TOptional<FRHIBreadcrumbEventManual>>();
RHIBreadcrumb->Emplace(*RHICommandList, FRHIBreadcrumbData(__FILE__, __LINE__, TStatId(), NAME_None), TEXT("%s"), FString(InEventName));
}
#endif
}
}
FScopedCapture::FScopedCapture(bool bEnable, FRDGBuilder& InGraphBuilder, TCHAR const* InEventName, TCHAR const* InFileName)
: bCapture(bEnable&& IRenderCaptureProvider::IsAvailable())
, bEvent(InEventName != nullptr)
, RHICommandList(nullptr)
, GraphBuilder(&InGraphBuilder)
{
check(!GIsThreadedRendering || IsInRenderingThread());
if (bCapture)
{
GraphBuilder->AddPass(
RDG_EVENT_NAME("BeginCapture"),
ERDGPassFlags::None,
[FileName = FString(InFileName)](FRHICommandListImmediate& RHICommandListLocal)
{
IRenderCaptureProvider::Get().BeginCapture(&RHICommandListLocal, IRenderCaptureProvider::ECaptureFlags_Launch, FString(FileName));
});
#if RDG_EVENTS
if (bEvent)
{
RDGEvent.Emplace(*GraphBuilder, ERDGScopeFlags::None, FRHIBreadcrumbData(__FILE__, __LINE__, TStatId(), NAME_None), RDG_EVENT_NAME("%s", InEventName));
}
#endif
}
}
FScopedCapture::~FScopedCapture()
{
if (bCapture)
{
if (GraphBuilder != nullptr)
{
check(!GIsThreadedRendering || IsInRenderingThread());
#if RDG_EVENTS
if (bEvent)
{
RDGEvent.Reset();
}
#endif
GraphBuilder->AddPass(
RDG_EVENT_NAME("EndCapture"),
ERDGPassFlags::None,
[](FRHICommandListImmediate& RHICommandListLocal)
{
IRenderCaptureProvider::Get().EndCapture(&RHICommandListLocal);
});
}
else if (RHICommandList != nullptr)
{
check(!GIsThreadedRendering || IsInRenderingThread());
#if WITH_RHI_BREADCRUMBS
if (bEvent)
{
(*RHIBreadcrumb)->End(*RHICommandList);
}
#endif
IRenderCaptureProvider::Get().EndCapture(&FRHICommandListImmediate::Get(*RHICommandList));
}
else
{
check(!GIsThreadedRendering || !IsInRenderingThread());
ENQUEUE_RENDER_COMMAND(EndCaptureCommand)([
#if WITH_RHI_BREADCRUMBS
bPopEvent = bEvent
, Breadcrumb = MoveTemp(RHIBreadcrumb)
#endif
](FRHICommandListImmediate& RHICommandListLocal)
{
#if WITH_RHI_BREADCRUMBS
if (bPopEvent)
{
(*Breadcrumb)->End(RHICommandListLocal);
}
#endif
IRenderCaptureProvider::Get().EndCapture(&RHICommandListLocal);
});
}
}
}
}