You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#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]
113 lines
3.7 KiB
C++
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;
|
|
}
|