Add Graphics::SpreadWorkload to disable graphics workloads amortization over several frames when debugging graphics perf

This commit is contained in:
Wojtek Figat
2024-06-19 14:03:55 +02:00
parent 0d48ac8fc2
commit 9c161121b3
6 changed files with 24 additions and 4 deletions

View File

@@ -22,6 +22,7 @@ bool Graphics::AllowCSMBlending = false;
Quality Graphics::GlobalSDFQuality = Quality::High;
Quality Graphics::GIQuality = Quality::High;
PostProcessSettings Graphics::PostProcessSettings;
bool Graphics::SpreadWorkload = true;
#if GRAPHICS_API_NULL
extern GPUDevice* CreateGPUDeviceNull();

View File

@@ -69,9 +69,22 @@ public:
/// </summary>
API_FIELD() static PostProcessSettings PostProcessSettings;
public:
/// <summary>
/// Debug utility to toggle graphics workloads amortization over several frames by systems such as shadows mapping, global illumination or surface atlas. Can be used to test performance in the worst-case scenario (eg. camera-cut).
/// </summary>
API_FIELD() static bool SpreadWorkload;
public:
/// <summary>
/// Disposes the device.
/// </summary>
static void DisposeDevice();
};
// Skip disabling workload spreading in Release builds
#if BUILD_RELEASE
#define GPU_SPREAD_WORKLOAD true
#else
#define GPU_SPREAD_WORKLOAD Graphics::SpreadWorkload
#endif

View File

@@ -402,7 +402,7 @@ bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderCont
bool cascadeSkipUpdate[4];
for (int32 cascadeIndex = 0; cascadeIndex < cascadesCount; cascadeIndex++)
{
cascadeSkipUpdate[cascadeIndex] = !clear && (ddgiData.LastFrameUsed % cascadeFrequencies[cascadeIndex]) != 0;
cascadeSkipUpdate[cascadeIndex] = !clear && (ddgiData.LastFrameUsed % cascadeFrequencies[cascadeIndex]) != 0 && GPU_SPREAD_WORKLOAD;
}
// Compute scrolling (probes are placed around camera but are scrolling to increase stability during movement)

View File

@@ -13,6 +13,7 @@
#include "Engine/Core/Config/GraphicsSettings.h"
#include "Engine/Graphics/GPUContext.h"
#include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/Graphics.h"
#include "Engine/Graphics/RenderTask.h"
#include "Engine/Graphics/RenderBuffers.h"
#include "Engine/Graphics/RenderTargetPool.h"
@@ -536,7 +537,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
context->SetRenderTarget(depthBuffer, ToSpan(targetBuffers, ARRAY_COUNT(targetBuffers)));
{
PROFILE_GPU_CPU_NAMED("Clear");
if (noCache || GLOBAL_SURFACE_ATLAS_DEBUG_FORCE_REDRAW_TILES)
if (noCache || GLOBAL_SURFACE_ATLAS_DEBUG_FORCE_REDRAW_TILES || !GPU_SPREAD_WORKLOAD)
{
// Full-atlas hardware clear
context->ClearDepth(depthBuffer);
@@ -1268,7 +1269,7 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
object->Bounds = OrientedBoundingBox(localBounds);
object->Bounds.Transform(localToWorld);
object->Radius = (float)actorObjectBounds.Radius;
if (dirty || GLOBAL_SURFACE_ATLAS_DEBUG_FORCE_REDRAW_TILES)
if (dirty || GLOBAL_SURFACE_ATLAS_DEBUG_FORCE_REDRAW_TILES || !GPU_SPREAD_WORKLOAD)
{
object->LastFrameUpdated = surfaceAtlasData.CurrentFrame;
object->LightingUpdateFrame = surfaceAtlasData.CurrentFrame;

View File

@@ -493,7 +493,7 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
// Rasterize world geometry into Global SDF
renderContext.View.Pass = DrawPass::GlobalSDF;
uint32 viewMask = renderContext.View.RenderLayersMask;
const bool useCache = !updated && !GLOBAL_SDF_DEBUG_FORCE_REDRAW;
const bool useCache = !updated && !GLOBAL_SDF_DEBUG_FORCE_REDRAW && GPU_SPREAD_WORKLOAD;
static_assert(GLOBAL_SDF_RASTERIZE_CHUNK_SIZE % GLOBAL_SDF_RASTERIZE_GROUP_SIZE == 0, "Invalid chunk size for Global SDF rasterization group size.");
const int32 rasterizeChunks = Math::CeilToInt((float)resolution / (float)GLOBAL_SDF_RASTERIZE_CHUNK_SIZE);
auto& chunks = ChunksCache;

View File

@@ -231,6 +231,11 @@ struct ShadowAtlasLight
float CalculateUpdateRateInv(const RenderLightData& light, float distanceFromView, bool& freezeUpdate) const
{
if (!GPU_SPREAD_WORKLOAD)
{
freezeUpdate = false;
return 1.0f;
}
const float shadowsUpdateRate = light.ShadowsUpdateRate;
const float shadowsUpdateRateAtDistance = shadowsUpdateRate * light.ShadowsUpdateRateAtDistance;
float updateRate = Math::Lerp(shadowsUpdateRate, shadowsUpdateRateAtDistance, Math::Saturate(distanceFromView / Distance));