Moved Nanite material visibility system into new NaniteVisibility .h/.cpp as part of ongoing cleanup, and also fixed shader reload crashing for CS materials in editor

#rb rune.stubbe
[FYI] brian.karis, jamie.hayes
#jira UE-187341

[CL 28336441 by graham wihlidal in ue5-main branch]
This commit is contained in:
graham wihlidal
2023-09-29 00:34:59 -04:00
parent b5ae00a61b
commit 263e7929b2
5 changed files with 743 additions and 715 deletions

View File

@@ -4,6 +4,7 @@
#include "NaniteShared.h"
#include "NaniteSceneProxy.h"
#include "NaniteVisibility.h"
class FVirtualShadowMapArray;
class FViewFamilyInfo;

View File

@@ -885,186 +885,6 @@ struct FNaniteShadingCommand
/// END-TODO: Work in progress / experimental
struct FNaniteVisibilityQuery;
class FNaniteVisibilityResults
{
friend class FNaniteVisibility;
public:
FNaniteVisibilityResults() = default;
bool IsRasterBinVisible(uint16 BinIndex) const;
bool IsShadingBinVisible(uint16 BinIndex) const;
bool IsShadingDrawVisible(uint32 DrawId) const;
void Invalidate();
FORCEINLINE bool IsRasterTestValid() const
{
return bRasterTestValid;
}
FORCEINLINE bool IsShadingTestValid() const
{
return bShadingTestValid;
}
FORCEINLINE void GetRasterBinStats(uint32& OutNumVisible, uint32& OutNumTotal) const
{
OutNumTotal = TotalRasterBins;
OutNumVisible = IsRasterTestValid() ? VisibleRasterBins : OutNumTotal;
}
FORCEINLINE void GetShadingBinStats(uint32& OutNumVisible, uint32& OutNumTotal) const
{
OutNumTotal = TotalShadingBins;
OutNumVisible = IsShadingTestValid() ? VisibleShadingBins : OutNumTotal;
}
FORCEINLINE void GetShadingDrawStats(uint32& OutNumVisible, uint32& OutNumTotal) const
{
OutNumTotal = TotalShadingDraws;
OutNumVisible = IsShadingTestValid() ? VisibleShadingDraws : OutNumTotal;
}
FORCEINLINE void SetRasterBinIndexTranslator(const FNaniteRasterBinIndexTranslator InTranslator)
{
BinIndexTranslator = InTranslator;
}
FORCEINLINE bool ShouldRenderCustomDepthPrimitive(uint32 PrimitiveId) const
{
if (!bRasterTestValid && !bShadingTestValid)
{
// no valid test results, so we didn't visibility test any primitives
return true;
}
return VisibleCustomDepthPrimitives.Contains(PrimitiveId);
}
FORCEINLINE const TBitArray<>& GetRasterBinVisibility() const
{
return RasterBinVisibility;
}
FORCEINLINE const TBitArray<>& GetShadingBinVisibility() const
{
return ShadingBinVisibility;
}
private:
TBitArray<> RasterBinVisibility;
TBitArray<> ShadingBinVisibility;
TArray<uint32> ShadingDrawVisibility;
TSet<uint32> VisibleCustomDepthPrimitives;
FNaniteRasterBinIndexTranslator BinIndexTranslator;
uint32 TotalRasterBins = 0;
uint32 TotalShadingBins = 0;
uint32 TotalShadingDraws = 0;
uint32 VisibleRasterBins = 0;
uint32 VisibleShadingBins = 0;
uint32 VisibleShadingDraws = 0;
bool bRasterTestValid = false;
bool bShadingTestValid = false;
};
class FNaniteVisibility
{
friend class FNaniteVisibilityTask;
public:
struct FRasterBin
{
uint16 Primary = 0xFFFFu;
uint16 Secondary = 0xFFFFu;
};
struct FShadingBin
{
uint16 Primary = 0xFFFFu;
};
using PrimitiveRasterBinType = TArray<FRasterBin, TInlineAllocator<1>>;
using PrimitiveShadingBinType = TArray<FShadingBin, TInlineAllocator<1>>;
using PrimitiveShadingDrawType = TArray<uint32, TInlineAllocator<1>>;
struct FPrimitiveReferences
{
const FPrimitiveSceneInfo* SceneInfo = nullptr;
PrimitiveRasterBinType RasterBins;
PrimitiveShadingBinType ShadingBins;
PrimitiveShadingDrawType ShadingDraws;
bool bWritesCustomDepthStencil = false;
};
using PrimitiveMapType = Experimental::TRobinHoodHashMap<const FPrimitiveSceneInfo*, FPrimitiveReferences>;
public:
FNaniteVisibility();
void BeginVisibilityFrame();
void FinishVisibilityFrame();
FNaniteVisibilityQuery* BeginVisibilityQuery(
FScene& Scene,
const TConstArrayView<FConvexVolume>& ViewList,
const class FNaniteRasterPipelines* RasterPipelines,
const class FNaniteShadingPipelines* ShadingPipelines,
const class FNaniteMaterialCommands* MaterialCommands = nullptr
);
void FinishVisibilityQuery(FNaniteVisibilityQuery* Query, FNaniteVisibilityResults& OutResults);
PrimitiveRasterBinType* GetRasterBinReferences(const FPrimitiveSceneInfo* SceneInfo);
PrimitiveShadingBinType* GetShadingBinReferences(const FPrimitiveSceneInfo* SceneInfo);
PrimitiveShadingDrawType* GetShadingDrawReferences(const FPrimitiveSceneInfo* SceneInfo);
void RemoveReferences(const FPrimitiveSceneInfo* SceneInfo);
private:
FPrimitiveReferences* FindOrAddPrimitiveReferences(const FPrimitiveSceneInfo* SceneInfo);
void WaitForTasks();
// Translator should remain valid between Begin/FinishVisibilityFrame. That is, no adding or removing raster bins
FNaniteRasterBinIndexTranslator BinIndexTranslator;
TArray<FNaniteVisibilityQuery*, TInlineAllocator<32>> VisibilityQueries;
TArray<UE::Tasks::FTask, SceneRenderingAllocator> ActiveEvents;
PrimitiveMapType PrimitiveReferences;
uint8 bCalledBegin : 1;
};
class FNaniteScopedVisibilityFrame
{
public:
FNaniteScopedVisibilityFrame(const bool bInEnabled, FNaniteVisibility& InVisibility)
: Visibility(InVisibility)
, bEnabled(bInEnabled)
{
if (bEnabled)
{
Visibility.BeginVisibilityFrame();
}
}
~FNaniteScopedVisibilityFrame()
{
if (bEnabled)
{
Visibility.FinishVisibilityFrame();
}
}
FORCEINLINE FNaniteVisibility& Get()
{
return Visibility;
}
private:
FNaniteVisibility& Visibility;
bool bEnabled;
};
extern bool ShouldRenderNanite(const FScene* Scene, const FViewInfo& View, bool bCheckForAtomicSupport = true);
/** Checks whether Nanite would be rendered in this view. Used to give a visual warning about the project settings that can disable Nanite. */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,186 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "NaniteShared.h"
//#include "NaniteCullRaster.h"
struct FNaniteVisibilityQuery;
class FNaniteVisibilityResults
{
friend class FNaniteVisibility;
public:
FNaniteVisibilityResults() = default;
bool IsRasterBinVisible(uint16 BinIndex) const;
bool IsShadingBinVisible(uint16 BinIndex) const;
bool IsShadingDrawVisible(uint32 DrawId) const;
void Invalidate();
FORCEINLINE bool IsRasterTestValid() const
{
return bRasterTestValid;
}
FORCEINLINE bool IsShadingTestValid() const
{
return bShadingTestValid;
}
FORCEINLINE void GetRasterBinStats(uint32& OutNumVisible, uint32& OutNumTotal) const
{
OutNumTotal = TotalRasterBins;
OutNumVisible = IsRasterTestValid() ? VisibleRasterBins : OutNumTotal;
}
FORCEINLINE void GetShadingBinStats(uint32& OutNumVisible, uint32& OutNumTotal) const
{
OutNumTotal = TotalShadingBins;
OutNumVisible = IsShadingTestValid() ? VisibleShadingBins : OutNumTotal;
}
FORCEINLINE void GetShadingDrawStats(uint32& OutNumVisible, uint32& OutNumTotal) const
{
OutNumTotal = TotalShadingDraws;
OutNumVisible = IsShadingTestValid() ? VisibleShadingDraws : OutNumTotal;
}
FORCEINLINE void SetRasterBinIndexTranslator(const FNaniteRasterBinIndexTranslator InTranslator)
{
BinIndexTranslator = InTranslator;
}
FORCEINLINE bool ShouldRenderCustomDepthPrimitive(uint32 PrimitiveId) const
{
if (!bRasterTestValid && !bShadingTestValid)
{
// no valid test results, so we didn't visibility test any primitives
return true;
}
return VisibleCustomDepthPrimitives.Contains(PrimitiveId);
}
FORCEINLINE const TBitArray<>& GetRasterBinVisibility() const
{
return RasterBinVisibility;
}
FORCEINLINE const TBitArray<>& GetShadingBinVisibility() const
{
return ShadingBinVisibility;
}
private:
TBitArray<> RasterBinVisibility;
TBitArray<> ShadingBinVisibility;
TArray<uint32> ShadingDrawVisibility;
TSet<uint32> VisibleCustomDepthPrimitives;
FNaniteRasterBinIndexTranslator BinIndexTranslator;
uint32 TotalRasterBins = 0;
uint32 TotalShadingBins = 0;
uint32 TotalShadingDraws = 0;
uint32 VisibleRasterBins = 0;
uint32 VisibleShadingBins = 0;
uint32 VisibleShadingDraws = 0;
bool bRasterTestValid = false;
bool bShadingTestValid = false;
};
class FNaniteVisibility
{
friend class FNaniteVisibilityTask;
public:
struct FRasterBin
{
uint16 Primary = 0xFFFFu;
uint16 Secondary = 0xFFFFu;
};
struct FShadingBin
{
uint16 Primary = 0xFFFFu;
};
using PrimitiveRasterBinType = TArray<FRasterBin, TInlineAllocator<1>>;
using PrimitiveShadingBinType = TArray<FShadingBin, TInlineAllocator<1>>;
using PrimitiveShadingDrawType = TArray<uint32, TInlineAllocator<1>>;
struct FPrimitiveReferences
{
const FPrimitiveSceneInfo* SceneInfo = nullptr;
PrimitiveRasterBinType RasterBins;
PrimitiveShadingBinType ShadingBins;
PrimitiveShadingDrawType ShadingDraws;
bool bWritesCustomDepthStencil = false;
};
using PrimitiveMapType = Experimental::TRobinHoodHashMap<const FPrimitiveSceneInfo*, FPrimitiveReferences>;
public:
FNaniteVisibility();
void BeginVisibilityFrame();
void FinishVisibilityFrame();
FNaniteVisibilityQuery* BeginVisibilityQuery(
FScene& Scene,
const TConstArrayView<FConvexVolume>& ViewList,
const class FNaniteRasterPipelines* RasterPipelines,
const class FNaniteShadingPipelines* ShadingPipelines,
const class FNaniteMaterialCommands* MaterialCommands = nullptr
);
void FinishVisibilityQuery(FNaniteVisibilityQuery* Query, FNaniteVisibilityResults& OutResults);
PrimitiveRasterBinType* GetRasterBinReferences(const FPrimitiveSceneInfo* SceneInfo);
PrimitiveShadingBinType* GetShadingBinReferences(const FPrimitiveSceneInfo* SceneInfo);
PrimitiveShadingDrawType* GetShadingDrawReferences(const FPrimitiveSceneInfo* SceneInfo);
void RemoveReferences(const FPrimitiveSceneInfo* SceneInfo);
private:
FPrimitiveReferences* FindOrAddPrimitiveReferences(const FPrimitiveSceneInfo* SceneInfo);
void WaitForTasks();
// Translator should remain valid between Begin/FinishVisibilityFrame. That is, no adding or removing raster bins
FNaniteRasterBinIndexTranslator BinIndexTranslator;
TArray<FNaniteVisibilityQuery*, TInlineAllocator<32>> VisibilityQueries;
TArray<UE::Tasks::FTask, SceneRenderingAllocator> ActiveEvents;
PrimitiveMapType PrimitiveReferences;
uint8 bCalledBegin : 1;
};
class FNaniteScopedVisibilityFrame
{
public:
FNaniteScopedVisibilityFrame(const bool bInEnabled, FNaniteVisibility& InVisibility)
: Visibility(InVisibility)
, bEnabled(bInEnabled)
{
if (bEnabled)
{
Visibility.BeginVisibilityFrame();
}
}
~FNaniteScopedVisibilityFrame()
{
if (bEnabled)
{
Visibility.FinishVisibilityFrame();
}
}
FORCEINLINE FNaniteVisibility& Get()
{
return Visibility;
}
private:
FNaniteVisibility& Visibility;
bool bEnabled;
};