Files
UnrealEngineUWP/Engine/Source/Runtime/UtilityShaders/Private/LongGPUTask.cpp
ben marsh 2b46ba7b94 Update copyright notices to 2019.
#rb none
#lockdown Nick.Penwarden

#ROBOMERGE-OWNER: ryan.gerleve
#ROBOMERGE-AUTHOR: ben.marsh
#ROBOMERGE-SOURCE: CL 4662404 in //UE4/Main/...
#ROBOMERGE-BOT: ENGINE (Main -> Dev-Networking)

[CL 4662413 by ben marsh in Dev-Networking branch]
2018-12-14 13:44:01 -05:00

113 lines
3.7 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "LongGPUTask.h"
#include "OneColorShader.h"
#include "PipelineStateCache.h"
#include "RHIStaticStates.h"
#include "RenderUtils.h"
#include "ClearQuad.h"
IMPLEMENT_SHADER_TYPE(, FLongGPUTaskPS, TEXT("/Engine/Private/OneColorShader.usf"), TEXT("MainLongGPUTask"), SF_Pixel);
int32 NumMeasuredIterationsToAchieve100ms = 0;
const int32 NumIterationsForMeasurement = 5;
static bool HasRun = false;
FRenderQueryRHIRef TimeQueryStart;
FRenderQueryRHIRef TimeQueryEnd;
void IssueScalableLongGPUTask(FRHICommandListImmediate& RHICmdList, int32 NumIteration /* = -1 by default */)
{
FRHIResourceCreateInfo Info;
FTexture2DRHIRef LongTaskRenderTarget = RHICreateTexture2D(1920, 1080, PF_B8G8R8A8, 1, 1, TexCreate_RenderTargetable, Info);
auto ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
FGraphicsPipelineStateInitializer GraphicsPSOInit;
// #todo-renderpasses DontLoad the correct action here?
FRHIRenderPassInfo RPInfo(LongTaskRenderTarget, ERenderTargetActions::DontLoad_Store);
TransitionRenderPassTargets(RHICmdList, RPInfo);
RHICmdList.BeginRenderPass(RPInfo, TEXT("LongGPUTask"));
{
RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
TShaderMapRef<TOneColorVS<true>> VertexShader(ShaderMap);
TShaderMapRef<FLongGPUTaskPS> PixelShader(ShaderMap);
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GetVertexDeclarationFVector4();
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader->GetVertexShader();
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader->GetPixelShader();
GraphicsPSOInit.PrimitiveType = PT_TriangleStrip;
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit);
VertexShader->SetDepthParameter(RHICmdList, 0.0f);
RHICmdList.SetStreamSource(0, GClearVertexBuffer.VertexBufferRHI, 0);
if (NumIteration == -1)
{
// Use the measured number of iterations to achieve 100ms
// If the query results are still not available, stall
if (NumMeasuredIterationsToAchieve100ms == 0)
{
if (TimeQueryStart != nullptr && TimeQueryEnd != nullptr) // Not all platforms/drivers support RQT_AbsoluteTime queries
{
uint64 StartTime = 0;
uint64 EndTime = 0;
// Results are in microseconds
RHICmdList.GetRenderQueryResult(TimeQueryStart, StartTime, true);
RHICmdList.GetRenderQueryResult(TimeQueryEnd, EndTime, true);
NumMeasuredIterationsToAchieve100ms = FMath::Clamp(FMath::FloorToInt(100.0f / ((EndTime - StartTime) / 1000.0f / NumIterationsForMeasurement)), 1, 200);
}
else
{
NumMeasuredIterationsToAchieve100ms = 5; // Use a constant time on these platforms
}
}
NumIteration = NumMeasuredIterationsToAchieve100ms;
}
for (int32 Iteration = 0; Iteration < NumIteration; Iteration++)
{
RHICmdList.DrawPrimitive(0, 2, 1);
}
}
RHICmdList.EndRenderPass();
}
void MeasureLongGPUTaskExecutionTime(FRHICommandListImmediate& RHICmdList)
{
if (HasRun) { return; }
check(TimeQueryStart == nullptr && TimeQueryEnd == nullptr);
TimeQueryStart = RHICmdList.CreateRenderQuery(RQT_AbsoluteTime);
TimeQueryEnd = RHICmdList.CreateRenderQuery(RQT_AbsoluteTime);
if (TimeQueryStart != nullptr && TimeQueryEnd != nullptr) // Not all platforms/drivers support RQT_AbsoluteTime queries
{
RHICmdList.EndRenderQuery(TimeQueryStart);
IssueScalableLongGPUTask(RHICmdList, NumIterationsForMeasurement);
RHICmdList.EndRenderQuery(TimeQueryEnd);
HasRun = true;
}
ClearLongGPUTaskQueries();
}
void ClearLongGPUTaskQueries()
{
TimeQueryStart = nullptr;
TimeQueryEnd = nullptr;
}