Optimize various debug views performance
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Renderer/GBufferPass.h"
|
||||
|
||||
LODPreviewMaterialShader::LODPreviewMaterialShader()
|
||||
{
|
||||
@@ -47,26 +48,10 @@ void LODPreviewMaterialShader::Bind(BindParameters& params)
|
||||
// Find the LOD that produced this draw call
|
||||
int32 lodIndex = 0;
|
||||
auto& drawCall = *params.FirstDrawCall;
|
||||
for (auto& e : Content::GetAssetsRaw())
|
||||
const ModelLOD* drawCallModelLod;
|
||||
if (GBufferPass::IndexBufferToModelLOD.TryGet(drawCall.Geometry.IndexBuffer, drawCallModelLod))
|
||||
{
|
||||
auto model = ScriptingObject::Cast<Model>(e.Value);
|
||||
if (!model)
|
||||
continue;
|
||||
bool found = false;
|
||||
for (const auto& lod : model->LODs)
|
||||
{
|
||||
for (const auto& mesh : lod.Meshes)
|
||||
{
|
||||
if (mesh.GetIndexBuffer() == drawCall.Geometry.IndexBuffer)
|
||||
{
|
||||
lodIndex = mesh.GetLODIndex();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
lodIndex = drawCallModelLod->GetLODIndex();
|
||||
}
|
||||
|
||||
// Bind
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Content/Assets/Model.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Renderer/GBufferPass.h"
|
||||
#include "Engine/Graphics/GPUPipelineState.h"
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#include "Engine/Graphics/Shaders/GPUConstantBuffer.h"
|
||||
@@ -125,7 +126,9 @@ void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
|
||||
float scaleInLightmap = 1.0f;
|
||||
if (params.RenderContext.Task)
|
||||
{
|
||||
if (params.RenderContext.Task->ActorsSource & ActorsSources::CustomActors)
|
||||
// Skip this lookup as it's too slow
|
||||
|
||||
/*if (params.RenderContext.Task->ActorsSource & ActorsSources::CustomActors)
|
||||
{
|
||||
for (auto actor : params.RenderContext.Task->CustomActors)
|
||||
{
|
||||
@@ -142,33 +145,7 @@ void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
|
||||
if (drawCallActor)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the model that produced this draw call
|
||||
const Model* drawCallModel = nullptr;
|
||||
const ModelLOD* drawCallModelLod = nullptr;
|
||||
const Mesh* drawCallMesh = nullptr;
|
||||
for (auto& e : Content::GetAssetsRaw())
|
||||
{
|
||||
auto model = ScriptingObject::Cast<Model>(e.Value);
|
||||
if (!model)
|
||||
continue;
|
||||
for (const auto& lod : model->LODs)
|
||||
{
|
||||
for (const auto& mesh : lod.Meshes)
|
||||
{
|
||||
if (mesh.GetIndexBuffer() == drawCall.Geometry.IndexBuffer)
|
||||
{
|
||||
drawCallModel = model;
|
||||
drawCallModelLod = &lod;
|
||||
drawCallMesh = &mesh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (drawCallModel)
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
|
||||
// Bind constants
|
||||
@@ -188,21 +165,19 @@ void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
|
||||
data.LightmapTexelsPerWorldUnit = ShadowsOfMordor::LightmapTexelsPerWorldUnit;
|
||||
data.LightmapSize = 1024.0f;
|
||||
data.LightmapArea = drawCall.Surface.LightmapUVsArea;
|
||||
if (drawCallModel)
|
||||
const ModelLOD* drawCallModelLod;
|
||||
if (GBufferPass::IndexBufferToModelLOD.TryGet(drawCall.Geometry.IndexBuffer, drawCallModelLod))
|
||||
{
|
||||
// Calculate current lightmap slot size for the object (matches the ShadowsOfMordor calculations when baking the lighting)
|
||||
float globalObjectsScale = 1.0f;
|
||||
int32 atlasSize = 1024;
|
||||
int32 chartsPadding = 3;
|
||||
if (drawCallActor)
|
||||
const Scene* drawCallScene = drawCallActor ? drawCallActor->GetScene() : (Level::Scenes.Count() != 0 ? Level::Scenes[0] : nullptr);
|
||||
if (drawCallScene)
|
||||
{
|
||||
const Scene* drawCallScene = drawCallActor->GetScene();
|
||||
if (drawCallScene)
|
||||
{
|
||||
globalObjectsScale = drawCallScene->Info.LightmapSettings.GlobalObjectsScale;
|
||||
atlasSize = (int32)drawCallScene->Info.LightmapSettings.AtlasSize;
|
||||
chartsPadding = drawCallScene->Info.LightmapSettings.ChartsPadding;
|
||||
}
|
||||
globalObjectsScale = drawCallScene->Info.LightmapSettings.GlobalObjectsScale;
|
||||
atlasSize = (int32)drawCallScene->Info.LightmapSettings.AtlasSize;
|
||||
chartsPadding = drawCallScene->Info.LightmapSettings.ChartsPadding;
|
||||
}
|
||||
BoundingBox box = drawCallModelLod->GetBox(drawCall.World);
|
||||
Float3 size = box.GetSize();
|
||||
@@ -219,7 +194,7 @@ void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
|
||||
const int32 maximumChartSize = atlasSize - chartsPadding * 2;
|
||||
int32 width = Math::Clamp(Math::CeilToInt(scale), ShadowsOfMordor::LightmapMinChartSize, maximumChartSize);
|
||||
int32 height = Math::Clamp(Math::CeilToInt(scale), ShadowsOfMordor::LightmapMinChartSize, maximumChartSize);
|
||||
float invSize = 1.0f / atlasSize;
|
||||
float invSize = 1.0f / (float)atlasSize;
|
||||
data.LightmapArea = Rectangle(0, 0, width * invSize, height * invSize);
|
||||
data.LightmapSize = (float)atlasSize;
|
||||
}
|
||||
|
||||
@@ -17,27 +17,23 @@ class GPUPipelineState;
|
||||
class LightmapUVsDensityMaterialShader : public IMaterial
|
||||
{
|
||||
private:
|
||||
|
||||
AssetReference<Shader> _shader;
|
||||
AssetReference<Texture> _gridTexture;
|
||||
GPUPipelineState* _ps = nullptr;
|
||||
MaterialInfo _info;
|
||||
|
||||
public:
|
||||
|
||||
LightmapUVsDensityMaterialShader();
|
||||
virtual ~LightmapUVsDensityMaterialShader()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if COMPILE_WITH_DEV_ENV
|
||||
void OnShaderReloading(Asset* obj);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
// [IMaterial]
|
||||
const MaterialInfo& GetInfo() const override;
|
||||
GPUShader* GetShader() const override;
|
||||
|
||||
@@ -102,6 +102,8 @@ MaterialComplexityMaterialShader::MaterialComplexityMaterialShader()
|
||||
|
||||
void MaterialComplexityMaterialShader::DebugOverrideDrawCallsMaterial(RenderContext& renderContext)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
|
||||
// Cache 'ready' state for wrappers
|
||||
bool isReady[ARRAY_COUNT(_wrappers) + 1];
|
||||
for (int32 i = 0; i < ARRAY_COUNT(_wrappers); i++)
|
||||
|
||||
@@ -27,6 +27,11 @@ PACK_STRUCT(struct GBufferPassData{
|
||||
int32 ViewMode;
|
||||
});
|
||||
|
||||
#if USE_EDITOR
|
||||
Dictionary<GPUBuffer*, const ModelLOD*> GBufferPass::IndexBufferToModelLOD;
|
||||
CriticalSection GBufferPass::Locker;
|
||||
#endif
|
||||
|
||||
String GBufferPass::ToString() const
|
||||
{
|
||||
return TEXT("GBufferPass");
|
||||
@@ -97,6 +102,7 @@ void GBufferPass::Dispose()
|
||||
SAFE_DELETE(_vertexColors);
|
||||
SAFE_DELETE(_lodPreview);
|
||||
SAFE_DELETE(_materialComplexity);
|
||||
IndexBufferToModelLOD.SetCapacity(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -106,6 +112,7 @@ void DebugOverrideDrawCallsMaterial(const RenderContext& renderContext, IMateria
|
||||
{
|
||||
if (!material->IsReady())
|
||||
return;
|
||||
PROFILE_CPU();
|
||||
IMaterial::InstancingHandler handler;
|
||||
const bool canUseInstancing = material->CanUseInstancing(handler);
|
||||
const auto drawModes = material->GetDrawModes();
|
||||
@@ -318,6 +325,12 @@ GPUTextureView* GBufferPass::RenderSkybox(RenderContext& renderContext, GPUConte
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
void GBufferPass::PreOverrideDrawCalls(RenderContext& renderContext)
|
||||
{
|
||||
// Clear cache before scene drawing
|
||||
IndexBufferToModelLOD.Clear();
|
||||
}
|
||||
|
||||
void GBufferPass::OverrideDrawCalls(RenderContext& renderContext)
|
||||
{
|
||||
// Override draw calls material to use material debug shader
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "RendererPass.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Rendering scene to the GBuffer
|
||||
@@ -46,6 +49,17 @@ public:
|
||||
GPUTextureView* RenderSkybox(RenderContext& renderContext, GPUContext* context);
|
||||
|
||||
#if USE_EDITOR
|
||||
// Temporary cache for faster debug previews drawing (used only during frame rendering).
|
||||
static Dictionary<GPUBuffer*, const ModelLOD*> IndexBufferToModelLOD;
|
||||
static CriticalSection Locker;
|
||||
|
||||
FORCE_INLINE static void AddIndexBufferToModelLOD(GPUBuffer* indexBuffer, const ModelLOD* modelLod)
|
||||
{
|
||||
Locker.Lock();
|
||||
IndexBufferToModelLOD[indexBuffer] = modelLod;
|
||||
Locker.Unlock();
|
||||
}
|
||||
void PreOverrideDrawCalls(RenderContext& renderContext);
|
||||
void OverrideDrawCalls(RenderContext& renderContext);
|
||||
void DrawMaterialComplexity(RenderContext& renderContext, GPUContext* context, GPUTextureView* lightBuffer);
|
||||
#endif
|
||||
|
||||
@@ -347,6 +347,9 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
}
|
||||
if (drawShadows)
|
||||
ShadowsPass::Instance()->SetupShadows(renderContext, renderContextBatch);
|
||||
#if USE_EDITOR
|
||||
GBufferPass::Instance()->PreOverrideDrawCalls(renderContext);
|
||||
#endif
|
||||
|
||||
// Dispatch drawing (via JobSystem - multiple job batches for every scene)
|
||||
JobSystem::SetJobStartingOnDispatch(false);
|
||||
|
||||
Reference in New Issue
Block a user