Files
UnrealEngine/Engine/Source/Runtime/RenderCore/Public/RendererInterface.h
2025-05-18 13:04:45 +08:00

897 lines
34 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
RendererInterface.h: Renderer interface definition.
=============================================================================*/
#pragma once
#include "CoreMinimal.h"
#include "Templates/RefCounting.h"
#include "Misc/MemStack.h"
#include "Modules/ModuleInterface.h"
#include "RHI.h"
#include "RenderResource.h"
#include "RenderUtils.h"
#include "Misc/EnumClassFlags.h"
#include "UniformBuffer.h"
#include "VirtualTexturing.h"
#include "RenderGraphDefinitions.h"
#include "PathTracingOutputInvalidateReason.h"
class FCanvas;
class FCanvasRenderContext;
class FMaterial;
class FSceneInterface;
class FSceneView;
class FSceneViewFamily;
class FSceneTextureUniformParameters;
class FMobileSceneTextureUniformParameters;
class FGlobalDistanceFieldParameterData;
struct FMeshBatch;
struct FSynthBenchmarkResults;
struct FSceneTextures;
struct FViewMatrices;
class FShader;
class FShaderMapPointerTable;
class FRDGBuilder;
class FMaterialRenderProxy;
class FGPUScenePrimitiveCollector;
class FViewInfo;
template<typename ShaderType, typename PointerTableType> class TShaderRefBase;
class FSceneUniformBuffer;
class FBatchedPrimitiveParameters;
class ISceneRenderer;
class IStateStreamManager;
class ISceneRenderBuilder;
namespace Nanite
{
struct FResources;
};
class FRHITransientTexture;
struct FSceneRenderingBlockAllocationTag
{
static constexpr uint32 BlockSize = 64 * 1024; // Blocksize used to allocate from
static constexpr bool AllowOversizedBlocks = true; // The allocator supports oversized Blocks and will store them in a seperate Block with counter 1
static constexpr bool RequiresAccurateSize = true; // GetAllocationSize returning the accurate size of the allocation otherwise it could be relaxed to return the size to the end of the Block
static constexpr bool InlineBlockAllocation = false; // Inline or Noinline the BlockAllocation which can have an impact on Performance
static constexpr const char* TagName = "SceneRenderingAllocator";
using Allocator = TBlockAllocationLockFreeCache<BlockSize, FAlignedAllocator>;
};
using FSceneRenderingBulkObjectAllocator = TConcurrentLinearBulkObjectAllocator<FSceneRenderingBlockAllocationTag>;
template <typename T>
using FSceneRenderingAllocatorObject = TConcurrentLinearObject<T, FSceneRenderingBlockAllocationTag>;
using FSceneRenderingAllocator = TConcurrentLinearAllocator<FSceneRenderingBlockAllocationTag>;
using FSceneRenderingArrayAllocator = TConcurrentLinearArrayAllocator<FSceneRenderingBlockAllocationTag>;
using SceneRenderingAllocator = TConcurrentLinearArrayAllocator<FSceneRenderingBlockAllocationTag>;
using SceneRenderingBitArrayAllocator = TConcurrentLinearBitArrayAllocator<FSceneRenderingBlockAllocationTag>;
using SceneRenderingSparseArrayAllocator = TConcurrentLinearSparseArrayAllocator<FSceneRenderingBlockAllocationTag>;
using SceneRenderingSetAllocator = TConcurrentLinearSetAllocator<FSceneRenderingBlockAllocationTag>;
/** All necessary data to create a render target from the pooled render targets. */
struct FPooledRenderTargetDesc
{
public:
/** Default constructor, use one of the factory functions below to make a valid description */
FPooledRenderTargetDesc()
: PackedBits(0)
{
check(!IsValid());
}
/**
* Factory function to create 2D texture description
* @param InFlags bit mask combined from elements of ETextureCreateFlags e.g. TexCreate_UAV
*/
static FPooledRenderTargetDesc Create2DDesc(
FIntPoint InExtent,
EPixelFormat InFormat,
const FClearValueBinding& InClearValue,
ETextureCreateFlags InFlags,
ETextureCreateFlags InTargetableFlags,
bool bInForceSeparateTargetAndShaderResource,
uint8 InNumMips = 1,
bool InAutowritable = true,
bool InCreateRTWriteMask = false,
bool InCreateFmask = false)
{
check(InExtent.X);
check(InExtent.Y);
FPooledRenderTargetDesc NewDesc;
NewDesc.ClearValue = InClearValue;
NewDesc.Extent = InExtent;
NewDesc.Depth = 0;
NewDesc.ArraySize = 1;
NewDesc.bIsArray = false;
NewDesc.bIsCubemap = false;
NewDesc.NumMips = InNumMips;
NewDesc.NumSamples = 1;
NewDesc.Format = InFormat;
NewDesc.Flags = InFlags | InTargetableFlags;
NewDesc.DebugName = TEXT("UnknownTexture2D");
check(NewDesc.Is2DTexture());
return NewDesc;
}
/**
* Factory function to create 2D array texture description
* @param InFlags bit mask combined from elements of ETextureCreateFlags e.g. TexCreate_UAV
*/
static FPooledRenderTargetDesc Create2DArrayDesc(
FIntPoint InExtent,
EPixelFormat InFormat,
const FClearValueBinding& InClearValue,
ETextureCreateFlags InFlags,
ETextureCreateFlags InTargetableFlags,
bool bInForceSeparateTargetAndShaderResource,
uint16 InArraySize,
uint8 InNumMips = 1,
bool InAutowritable = true,
bool InCreateRTWriteMask = false,
bool InCreateFmask = false)
{
check(InExtent.X);
check(InExtent.Y);
FPooledRenderTargetDesc NewDesc;
NewDesc.ClearValue = InClearValue;
NewDesc.Extent = InExtent;
NewDesc.Depth = 0;
NewDesc.ArraySize = InArraySize;
NewDesc.bIsArray = true;
NewDesc.bIsCubemap = false;
NewDesc.NumMips = InNumMips;
NewDesc.NumSamples = 1;
NewDesc.Format = InFormat;
NewDesc.Flags = InFlags | InTargetableFlags;
NewDesc.DebugName = TEXT("UnknownTexture2DArray");
check(NewDesc.Is2DTexture());
return NewDesc;
}
/**
* Factory function to create 3D texture description
* @param InFlags bit mask combined from elements of ETextureCreateFlags e.g. TexCreate_UAV
*/
static FPooledRenderTargetDesc CreateVolumeDesc(
uint32 InSizeX,
uint32 InSizeY,
uint16 InSizeZ,
EPixelFormat InFormat,
const FClearValueBinding& InClearValue,
ETextureCreateFlags InFlags,
ETextureCreateFlags InTargetableFlags,
bool bInForceSeparateTargetAndShaderResource,
uint8 InNumMips = 1,
bool InAutowritable = true)
{
check(InSizeX);
check(InSizeY);
FPooledRenderTargetDesc NewDesc;
NewDesc.ClearValue = InClearValue;
NewDesc.Extent = FIntPoint(InSizeX,InSizeY);
NewDesc.Depth = InSizeZ;
NewDesc.ArraySize = 1;
NewDesc.bIsArray = false;
NewDesc.bIsCubemap = false;
NewDesc.NumMips = InNumMips;
NewDesc.NumSamples = 1;
NewDesc.Format = InFormat;
NewDesc.Flags = InFlags | InTargetableFlags;
NewDesc.DebugName = TEXT("UnknownTextureVolume");
check(NewDesc.Is3DTexture());
return NewDesc;
}
/**
* Factory function to create cube map texture description
* @param InFlags bit mask combined from elements of ETextureCreateFlags e.g. TexCreate_UAV
*/
static FPooledRenderTargetDesc CreateCubemapDesc(
uint32 InExtent,
EPixelFormat InFormat,
const FClearValueBinding& InClearValue,
ETextureCreateFlags InFlags,
ETextureCreateFlags InTargetableFlags,
bool bInForceSeparateTargetAndShaderResource,
uint16 InArraySize = 1,
uint8 InNumMips = 1,
bool InAutowritable = true)
{
check(InExtent);
FPooledRenderTargetDesc NewDesc;
NewDesc.ClearValue = InClearValue;
NewDesc.Extent = FIntPoint(InExtent, InExtent);
NewDesc.Depth = 0;
NewDesc.ArraySize = InArraySize;
// Note: this doesn't allow an array of size 1
NewDesc.bIsArray = InArraySize > 1;
NewDesc.bIsCubemap = true;
NewDesc.NumMips = InNumMips;
NewDesc.NumSamples = 1;
NewDesc.Format = InFormat;
NewDesc.Flags = InFlags | InTargetableFlags;
NewDesc.DebugName = TEXT("UnknownTextureCube");
check(NewDesc.IsCubemap());
return NewDesc;
}
/**
* Factory function to create cube map array texture description
* @param InFlags bit mask combined from elements of ETextureCreateFlags e.g. TexCreate_UAV
*/
static FPooledRenderTargetDesc CreateCubemapArrayDesc(
uint32 InExtent,
EPixelFormat InFormat,
const FClearValueBinding& InClearValue,
ETextureCreateFlags InFlags,
ETextureCreateFlags InTargetableFlags,
bool bInForceSeparateTargetAndShaderResource,
uint16 InArraySize,
uint8 InNumMips = 1,
bool InAutowritable = true)
{
check(InExtent);
FPooledRenderTargetDesc NewDesc;
NewDesc.ClearValue = InClearValue;
NewDesc.Extent = FIntPoint(InExtent, InExtent);
NewDesc.Depth = 0;
NewDesc.ArraySize = InArraySize;
NewDesc.bIsArray = true;
NewDesc.bIsCubemap = true;
NewDesc.NumMips = InNumMips;
NewDesc.NumSamples = 1;
NewDesc.Format = InFormat;
NewDesc.Flags = InFlags | InTargetableFlags;
NewDesc.DebugName = TEXT("UnknownTextureCubeArray");
check(NewDesc.IsCubemap());
return NewDesc;
}
/** Comparison operator to test if a render target can be reused */
bool Compare(const FPooledRenderTargetDesc& rhs, bool bExact) const
{
auto LhsFlags = Flags;
auto RhsFlags = rhs.Flags;
if (!bExact || !FPlatformMemory::SupportsFastVRAMMemory())
{
LhsFlags &= (~TexCreate_FastVRAM);
RhsFlags &= (~TexCreate_FastVRAM);
}
return ClearValue == rhs.ClearValue
&& LhsFlags == RhsFlags
&& Format == rhs.Format
&& UAVFormat == rhs.UAVFormat
&& Extent == rhs.Extent
&& Depth == rhs.Depth
&& ArraySize == rhs.ArraySize
&& NumMips == rhs.NumMips
&& NumSamples == rhs.NumSamples
&& PackedBits == rhs.PackedBits
&& FastVRAMPercentage == rhs.FastVRAMPercentage;
}
bool IsCubemap() const
{
return bIsCubemap;
}
bool Is2DTexture() const
{
return Extent.X != 0 && Extent.Y != 0 && Depth == 0 && !bIsCubemap;
}
bool Is3DTexture() const
{
return Extent.X != 0 && Extent.Y != 0 && Depth != 0 && !bIsCubemap;
}
// @return true if this texture is a texture array
bool IsArray() const
{
return bIsArray;
}
bool IsValid() const
{
if(NumSamples != 1)
{
if(NumSamples < 1 || NumSamples > 8)
{
// D3D11 limitations
return false;
}
if(!Is2DTexture())
{
return false;
}
}
return Extent.X != 0 && NumMips != 0 && NumSamples >=1 && NumSamples <=16 && Format != PF_Unknown
&& (EnumHasAnyFlags(Flags, TexCreate_UAV) || GMaxRHIFeatureLevel >= ERHIFeatureLevel::SM5 || GMaxRHIFeatureLevel == ERHIFeatureLevel::ES3_1);
}
FIntVector GetSize() const
{
return FIntVector(Extent.X, Extent.Y, Depth);
}
/**
* for debugging purpose
* @return e.g. (2D 128x64 PF_R8)
*/
FString GenerateInfoString() const
{
const TCHAR* FormatString = GetPixelFormatString(Format);
FString FlagsString = TEXT("");
ETextureCreateFlags LocalFlags = Flags;
if(EnumHasAnyFlags(LocalFlags, TexCreate_RenderTargetable))
{
FlagsString += TEXT(" RT");
}
if(EnumHasAnyFlags(LocalFlags, TexCreate_SRGB))
{
FlagsString += TEXT(" sRGB");
}
if(NumSamples > 1)
{
FlagsString += FString::Printf(TEXT(" %dxMSAA"), NumSamples);
}
if(EnumHasAnyFlags(LocalFlags, TexCreate_UAV))
{
FlagsString += TEXT(" UAV");
}
if(EnumHasAnyFlags(LocalFlags, TexCreate_FastVRAM))
{
FlagsString += TEXT(" VRam");
}
FString ArrayString;
if(IsArray())
{
ArrayString = FString::Printf(TEXT("[%d]"), ArraySize);
}
if(Is2DTexture())
{
return FString::Printf(TEXT("(2D%s %dx%d %s%s)"), *ArrayString, Extent.X, Extent.Y, FormatString, *FlagsString);
}
else if(Is3DTexture())
{
return FString::Printf(TEXT("(3D%s %dx%dx%d %s%s)"), *ArrayString, Extent.X, Extent.Y, Depth, FormatString, *FlagsString);
}
else if(IsCubemap())
{
return FString::Printf(TEXT("(Cube%s %d %s%s)"), *ArrayString, Extent.X, FormatString, *FlagsString);
}
else
{
return TEXT("(INVALID)");
}
}
// useful when compositing graph takes an input as output format
void Reset()
{
// Usually we don't want to propagate MSAA samples.
NumSamples = 1;
// Remove UAV flag for rendertargets that don't need it (some formats are incompatible)
Flags |= TexCreate_RenderTargetable;
Flags &= (~TexCreate_UAV);
}
/** only set a pointer to memory that never gets released */
const TCHAR* DebugName = TEXT("UnknownTexture");
/** Value allowed for fast clears for this target. */
FClearValueBinding ClearValue;
/** The flags that must be set on both the shader-resource and the targetable texture. bit mask combined from elements of ETextureCreateFlags e.g. TexCreate_UAV */
ETextureCreateFlags Flags = TexCreate_None;
/** Texture format e.g. PF_B8G8R8A8 */
EPixelFormat Format = PF_Unknown;
/** Texture format used when creating the UAV (if TexCreate_UAV is also passed in TargetableFlags, ignored otherwise). PF_Unknown == use default (same as Format) */
EPixelFormat UAVFormat = PF_Unknown;
/** In pixels, (0,0) if not set, (x,0) for cube maps, todo: make 3d int vector for volume textures */
FIntPoint Extent = FIntPoint::ZeroValue;
/** 0, unless it's texture array or volume texture */
uint16 Depth = 0;
/** >1 if a texture array should be used (not supported on DX9) */
uint16 ArraySize = 1;
/** Number of mips */
uint8 NumMips = 0;
/** Number of MSAA samples, default: 1 */
uint8 NumSamples = 1;
/** Resource memory percentage which should be allocated onto fast VRAM (hint-only). (encoding into 8bits, 0..255 -> 0%..100%) */
uint8 FastVRAMPercentage = 0xFF;
union
{
struct
{
/** true if an array texture. Note that ArraySize still can be 1 */
uint8 bIsArray : 1;
/** true if a cubemap texture */
uint8 bIsCubemap : 1;
/** Unused flags. */
uint8 bReserved0 : 6;
};
uint8 PackedBits;
};
};
/**
* Single render target item consists of a render surface and its resolve texture, Render thread side
*/
struct FSceneRenderTargetItem
{
/** default constructor */
FSceneRenderTargetItem() {}
/** constructor */
FSceneRenderTargetItem(FRHITexture* InTargetableTexture, FRHITexture* InShaderResourceTexture, FUnorderedAccessViewRHIRef InUAV)
: TargetableTexture(InTargetableTexture)
, ShaderResourceTexture(InShaderResourceTexture)
, UAV(InUAV)
{}
void SafeRelease()
{
TargetableTexture.SafeRelease();
ShaderResourceTexture.SafeRelease();
UAV.SafeRelease();
}
bool IsValid() const
{
return TargetableTexture != 0
|| ShaderResourceTexture != 0
|| UAV != 0;
}
FRHITexture* GetRHI() const { return TargetableTexture; }
/** The 2D or cubemap texture that may be used as a render or depth-stencil target. */
FTextureRHIRef TargetableTexture;
/** The 2D or cubemap shader-resource 2D texture that the targetable textures may be resolved to. */
FTextureRHIRef ShaderResourceTexture;
/** only created if requested through the flag. */
FUnorderedAccessViewRHIRef UAV;
};
/**
* Render thread side, use TRefCountPtr<IPooledRenderTarget>, allows sharing and VisualizeTexture
*/
struct IPooledRenderTarget
{
virtual ~IPooledRenderTarget() {}
/** Checks if the reference count indicated that the rendertarget is unused and can be reused. */
virtual bool IsFree() const = 0;
/** Get all the data that is needed to create the render target. */
virtual const FPooledRenderTargetDesc& GetDesc() const = 0;
/**
* Only for debugging purpose
* @return in bytes
**/
virtual uint32 ComputeMemorySize() const = 0;
/** Returns if the render target is tracked by a pool. */
virtual bool IsTracked() const = 0;
/** Returns a transient texture if this is a container for one. */
virtual FRHITransientTexture* GetTransientTexture() const { return nullptr; }
// Refcounting
virtual uint32 AddRef() const = 0;
virtual uint32 Release() = 0;
virtual uint32 GetRefCount() const = 0;
FRHITexture* GetRHI() const { return RenderTargetItem.TargetableTexture; }
protected:
/** The internal references to the created render target */
FSceneRenderTargetItem RenderTargetItem;
};
/** Creates an untracked pooled render target from an RHI texture. */
extern RENDERCORE_API TRefCountPtr<IPooledRenderTarget> CreateRenderTarget(FRHITexture* Texture, const TCHAR* Name);
/** Creates an untracked pooled render target from the RHI texture, but only if the pooled render target is
* empty or doesn't match the input texture. If the pointer already exists and points at the input texture,
* the function just returns. Useful to cache a pooled render target for an RHI texture. Returns true if the
* render target was created, or false if it was reused.
*/
extern RENDERCORE_API bool CacheRenderTarget(FRHITexture* Texture, const TCHAR* Name, TRefCountPtr<IPooledRenderTarget>& OutPooledRenderTarget);
// use r.DrawDenormalizedQuadMode to override the function call setting (quick way to see if an artifact is caused by this optimization)
enum EDrawRectangleFlags
{
// Rectangle is created by 2 triangles (diagonal can cause some slightly less efficient shader execution), this is the default as it has no artifacts
EDRF_Default,
//
EDRF_UseTriangleOptimization,
//
EDRF_UseTesselatedIndexBuffer
};
class FPostOpaqueRenderParameters
{
public:
FIntRect ViewportRect;
FMatrix ViewMatrix;
FMatrix ProjMatrix;
FRDGTexture* ColorTexture = nullptr;
FRDGTexture* DepthTexture = nullptr;
FRDGTexture* NormalTexture = nullptr;
FRDGTexture* VelocityTexture = nullptr;
FRDGTexture* SmallDepthTexture = nullptr;
FRDGBuilder* GraphBuilder = nullptr;
FRHIUniformBuffer* ViewUniformBuffer = nullptr;
TRDGUniformBufferRef<FSceneTextureUniformParameters> SceneTexturesUniformParams = nullptr;
TRDGUniformBufferRef<FMobileSceneTextureUniformParameters> MobileSceneTexturesUniformParams = nullptr;
const FGlobalDistanceFieldParameterData* GlobalDistanceFieldParams = nullptr;
void* Uid = nullptr; // A unique identifier for the view.
const FViewInfo* View = nullptr;
};
DECLARE_MULTICAST_DELEGATE_OneParam(FOnPostOpaqueRender, class FPostOpaqueRenderParameters&);
typedef FOnPostOpaqueRender::FDelegate FPostOpaqueRenderDelegate;
class ICustomVisibilityQuery: public IRefCountedObject
{
public:
/** prepares the query for visibility tests */
virtual bool Prepare() = 0;
/** test primitive visiblity */
virtual bool IsVisible(int32 VisibilityId, const FBoxSphereBounds& Bounds) = 0;
/** return true if we can call IsVisible from a ParallelFor */
virtual bool IsThreadsafe()
{
return false;
}
};
class ICustomCulling
{
public:
virtual ICustomVisibilityQuery* CreateQuery (const FSceneView& View) = 0;
};
/**
* Class use to add FScene pixel inspect request
*/
class FPixelInspectorRequest
{
public:
FPixelInspectorRequest()
{
SourceViewportUV = FVector2f(-1, -1);
BufferIndex = -1;
RenderingCommandSend = false;
RequestComplete = true;
ViewId = -1;
GBufferPrecision = 1;
AllowStaticLighting = true;
FrameCountAfterRenderingCommandSend = 0;
RequestTickSinceCreation = 0;
PreExposure = 1;
}
void SetRequestData(FVector2f SrcViewportUV, int32 TargetBufferIndex, int32 ViewUniqueId, int32 GBufferFormat, bool StaticLightingEnable, float InPreExposure)
{
SourceViewportUV = SrcViewportUV;
BufferIndex = TargetBufferIndex;
RenderingCommandSend = false;
RequestComplete = false;
ViewId = ViewUniqueId;
GBufferPrecision = GBufferFormat;
AllowStaticLighting = StaticLightingEnable;
PreExposure = InPreExposure;
FrameCountAfterRenderingCommandSend = 0;
RequestTickSinceCreation = 0;
}
void MarkSendToRendering() { RenderingCommandSend = true; }
~FPixelInspectorRequest()
{
}
bool RenderingCommandSend;
int32 FrameCountAfterRenderingCommandSend;
int32 RequestTickSinceCreation;
bool RequestComplete;
FVector2f SourceViewportUV;
int32 BufferIndex;
int32 ViewId;
//GPU state at capture time
int32 GBufferPrecision;
bool AllowStaticLighting;
float PreExposure;
};
class IPersistentViewUniformBufferExtension
{
public:
virtual void BeginFrame() {}
virtual void PrepareView(const FSceneView* View) {}
virtual void BeginRenderView(const FSceneView* View, bool bShouldWaitForJobs = true) {}
virtual void EndFrame() {}
};
/**
*/
class IScenePrimitiveRenderingContext
{
public:
virtual ~IScenePrimitiveRenderingContext() {}
virtual ISceneRenderer* GetSceneRenderer() = 0;
};
struct FScenePrimitiveRenderingContextScopeHelper
{
FScenePrimitiveRenderingContextScopeHelper(IScenePrimitiveRenderingContext* InScenePrimitiveRenderingContext)
: ScenePrimitiveRenderingContext(InScenePrimitiveRenderingContext)
{
}
~FScenePrimitiveRenderingContextScopeHelper()
{
// GPUCULL_TODO: Is new/delete reasonable here?
delete ScenePrimitiveRenderingContext;
}
IScenePrimitiveRenderingContext* ScenePrimitiveRenderingContext;
};
/**
* The public interface of the renderer module.
*/
class IRendererModule : public IModuleInterface
{
public:
/** Call from the game thread to send a message to the rendering thread to being rendering this view family. */
virtual void BeginRenderingViewFamily(FCanvas* Canvas, FSceneViewFamily* ViewFamily) = 0;
/** Call from the render thread to create and initalize a new FViewInfo with the specified options, and add it to the specified view family. */
virtual void CreateAndInitSingleView(FRHICommandListImmediate& RHICmdList, class FSceneViewFamily* ViewFamily, const struct FSceneViewInitOptions* ViewInitOptions) = 0;
/**
* Allocates a new instance of the private FScene implementation for the given world.
* @param World - An optional world to associate with the scene.
* @param bInRequiresHitProxies - Indicates that hit proxies should be rendered in the scene.
*/
virtual FSceneInterface* AllocateScene(UWorld* World, bool bInRequiresHitProxies, bool bCreateFXSystem, ERHIFeatureLevel::Type InFeatureLevel) = 0;
virtual void RemoveScene(FSceneInterface* Scene) = 0;
#if WITH_STATE_STREAM
virtual IStateStreamManager* AllocateStateStream(UWorld* World) = 0;
virtual void FreeStateStream(IStateStreamManager* Manager) = 0;
#endif
/**
* Updates all static draw lists for each allocated scene.
*/
virtual void UpdateStaticDrawLists() = 0;
/**
* Updates static draw lists for the given set of materials for each allocated scene.
*/
virtual void UpdateStaticDrawListsForMaterials(const TArray<const FMaterial*>& Materials) = 0;
/** Allocates a new instance of the private scene manager implementation of FSceneViewStateInterface */
virtual class FSceneViewStateInterface* AllocateViewState(ERHIFeatureLevel::Type FeatureLevel) = 0;
virtual class FSceneViewStateInterface* AllocateViewState(ERHIFeatureLevel::Type FeatureLevel, FSceneViewStateInterface* ShareOriginTarget) = 0;
/** @return The number of lights that affect a primitive. */
virtual uint32 GetNumDynamicLightsAffectingPrimitive(const class FPrimitiveSceneInfo* PrimitiveSceneInfo,const class FLightCacheInterface* LCI) = 0;
virtual void OnWorldCleanup(UWorld* World, bool bSessionEnded, bool bCleanupResources, bool bWorldChanged) = 0;
virtual void InitializeSystemTextures(FRHICommandListImmediate& RHICmdList) = 0;
/** Create a Scene Uniform Buffer containing only the scene representation for a single primitive */
virtual FSceneUniformBuffer* CreateSinglePrimitiveSceneUniformBuffer(FRDGBuilder& GraphBuilder, ERHIFeatureLevel::Type FeatureLevel, FMeshBatch& Mesh) = 0;
virtual FSceneUniformBuffer* CreateSinglePrimitiveSceneUniformBuffer(FRDGBuilder& GraphBuilder, const FViewInfo& SceneView, FMeshBatch& Mesh) = 0;
/** Create a Uniform Buffer containing representation for a single primitive. (For platforms that use "UniformView" path) */
virtual TRDGUniformBufferRef<FBatchedPrimitiveParameters> CreateSinglePrimitiveUniformView(FRDGBuilder& GraphBuilder, ERHIFeatureLevel::Type FeatureLevel, EShaderPlatform ShaderPlatform, FMeshBatch& Mesh) = 0;
virtual TRDGUniformBufferRef<FBatchedPrimitiveParameters> CreateSinglePrimitiveUniformView(FRDGBuilder& GraphBuilder, const FViewInfo& SceneView, FMeshBatch& Mesh) = 0;
/** Draws a tile mesh element with the specified view. */
virtual void DrawTileMesh(FCanvasRenderContext& RenderContext, struct FMeshPassProcessorRenderState& DrawRenderState, const FSceneView& View, FMeshBatch& Mesh, bool bIsHitTesting, const class FHitProxyId& HitProxyId, bool bUse128bitRT = false) = 0;
virtual const TSet<FSceneInterface*>& GetAllocatedScenes() = 0;
/** Renderer gets a chance to log some useful crash data */
virtual void DebugLogOnCrash() = 0;
// @param WorkScale >0, 10 for normal precision and runtime of less than a second
virtual void GPUBenchmark(FSynthBenchmarkResults& InOut, float WorkScale = 10.0f) = 0;
virtual void ExecVisualizeTextureCmd(const FString& Cmd) = 0;
virtual void UpdateMapNeedsLightingFullyRebuiltState(UWorld* World) = 0;
/**
* Draws a quad with the given vertex positions and UVs in denormalized pixel/texel coordinates.
* The platform-dependent mapping from pixels to texels is done automatically.
* Note that the positions are affected by the current viewport.
* NOTE: DrawRectangle should be used in the vertex shader to calculate the correct position and uv for vertices.
*
* X, Y Position in screen pixels of the top left corner of the quad
* SizeX, SizeY Size in screen pixels of the quad
* U, V Position in texels of the top left corner of the quad's UV's
* SizeU, SizeV Size in texels of the quad's UV's
* TargetSizeX, TargetSizeY Size in screen pixels of the target surface
* TextureSize Size in texels of the source texture
* VertexShader The vertex shader used for rendering
* Flags see EDrawRectangleFlags
*/
virtual void DrawRectangle(
FRHICommandList& RHICmdList,
float X,
float Y,
float SizeX,
float SizeY,
float U,
float V,
float SizeU,
float SizeV,
FIntPoint TargetSize,
FIntPoint TextureSize,
const TShaderRefBase<FShader, FShaderMapPointerTable>& VertexShader,
EDrawRectangleFlags Flags = EDRF_Default
) = 0;
/** Register/unregister a custom occlusion culling implementation */
virtual void RegisterCustomCullingImpl(ICustomCulling* impl) = 0;
virtual void UnregisterCustomCullingImpl(ICustomCulling* impl) = 0;
virtual FDelegateHandle RegisterPostOpaqueRenderDelegate(const FPostOpaqueRenderDelegate& PostOpaqueRenderDelegate) = 0;
virtual void RemovePostOpaqueRenderDelegate(FDelegateHandle PostOpaqueRenderDelegate) = 0;
virtual FDelegateHandle RegisterOverlayRenderDelegate(const FPostOpaqueRenderDelegate& OverlayRenderDelegate) = 0;
virtual void RemoveOverlayRenderDelegate(FDelegateHandle OverlayRenderDelegate) = 0;
/** Delegate that is called upon resolving scene color. */
DECLARE_MULTICAST_DELEGATE_TwoParams(FOnResolvedSceneColor, FRDGBuilder& /*GraphBuilder*/, const FSceneTextures& /*SceneTextures*/);
/** Accessor for post scene color resolve delegates */
virtual FOnResolvedSceneColor& GetResolvedSceneColorCallbacks() = 0;
virtual void PostRenderAllViewports() = 0;
/** Performs necessary per-frame cleanup. Only use when rendering through scene renderer (i.e. BeginRenderingViewFamily) is skipped */
virtual void PerFrameCleanupIfSkipRenderer() = 0;
virtual IAllocatedVirtualTexture* AllocateVirtualTexture(FRHICommandListBase& RHICmdList, const FAllocatedVTDescription& Desc) = 0;
RENDERCORE_API IAllocatedVirtualTexture* AllocateVirtualTexture(const FAllocatedVTDescription& Desc);
virtual void DestroyVirtualTexture(IAllocatedVirtualTexture* AllocatedVT) = 0;
virtual IAdaptiveVirtualTexture* AllocateAdaptiveVirtualTexture(FRHICommandListBase& RHICmdList, const FAdaptiveVTDescription& AdaptiveVTDesc, const FAllocatedVTDescription& AllocatedVTDesc) = 0;
RENDERCORE_API IAdaptiveVirtualTexture* AllocateAdaptiveVirtualTexture(const FAdaptiveVTDescription& AdaptiveVTDesc, const FAllocatedVTDescription& AllocatedVTDesc);
virtual void DestroyAdaptiveVirtualTexture(IAdaptiveVirtualTexture* AdaptiveVT) = 0;
virtual FVirtualTextureProducerHandle RegisterVirtualTextureProducer(FRHICommandListBase& RHICmdList, const FVTProducerDescription& Desc, IVirtualTexture* Producer) = 0;
RENDERCORE_API FVirtualTextureProducerHandle RegisterVirtualTextureProducer(const FVTProducerDescription& Desc, IVirtualTexture* Producer);
virtual void ReleaseVirtualTextureProducer(const FVirtualTextureProducerHandle& Handle) = 0;
virtual void AddVirtualTextureProducerDestroyedCallback(const FVirtualTextureProducerHandle& Handle, FVTProducerDestroyedFunction* Function, void* Baton) = 0;
virtual uint32 RemoveAllVirtualTextureProducerDestroyedCallbacks(const void* Baton) = 0;
virtual void ReleaseVirtualTexturePendingResources() = 0;
virtual void RequestVirtualTextureTiles(const FVector2D& InScreenSpaceSize, int32 InMipLevel) = 0;
virtual void RequestVirtualTextureTiles(const FMaterialRenderProxy* InMaterialRenderProxy, const FVector2D& InScreenSpaceSize, ERHIFeatureLevel::Type InFeatureLevel) = 0;
/**
* Helper function to request loading of tiles for a virtual texture that will be displayed in the UI.
* It will request only the tiles that will be visible after clipping to the provided viewport.
* @param AllocatedVT The virtual texture.
* @param InScreenSpaceSize Size on screen at which the texture is to be displayed.
* @param InViewportPosition Position in the viewport where the texture will be displayed.
* @param InViewportSize Size of the viewport.
* @param InUV0 UV coordinate to use for the top left corner of the texture.
* @param InUV1 UV coordinate to use for the bottom right corner of the texture.
* @param InMipLevel [optional] Specific mip level to fetch tiles for.
*/
virtual void RequestVirtualTextureTiles(IAllocatedVirtualTexture* AllocatedVT, const FVector2D& InScreenSpaceSize, const FVector2D& InViewportPosition, const FVector2D& InViewportSize, const FVector2D& InUV0, const FVector2D& InUV1, int32 InMipLevel) = 0;
UE_DEPRECATED(5.4, "Use RequestVirtualTextureTiles() overloads that takes similar parameters. Make sure not to negate the InViewportPosition.")
virtual void RequestVirtualTextureTilesForRegion(IAllocatedVirtualTexture* AllocatedVT, const FVector2D& InScreenSpaceSize, const FVector2D& InViewportPosition, const FVector2D& InViewportSize, const FVector2D& InUV0, const FVector2D& InUV1, int32 InMipLevel) = 0;
/** Ensure that any tiles requested by 'RequestVirtualTextureTiles' are loaded, must be called from render thread */
virtual void LoadPendingVirtualTextureTiles(FRHICommandListImmediate& RHICmdList, ERHIFeatureLevel::Type FeatureLevel) = 0;
/**
* Lock all tiles associated with a producer up to and including a given mip level.
* The mip level is stored on the producer, so that if we call twice then the second call will either lock or unlock tiles to reach the new level.
* Locked tiles should remain resident once loaded, though there is no guarantee over how quickly they will be loaded.
* Also if the virtual texture pools are already oversubscribed then we will not be able to satisfy the loading.
*/
virtual void LockVirtualTextureTiles(FVirtualTextureProducerHandle ProducerHandle, int32 InMipLevel) = 0;
/** Allocate a buffer and record all virtual texture page requests until the next call to either SetVirtualTextureRequestRecordBuffer or GetVirtualTextureRequestRecordBuffer. */
virtual void SetVirtualTextureRequestRecordBuffer(uint64 Handle) = 0;
/** Fetch the virtual texture page requests recorded since the last call to SetVirtualTextureRequestRecordBuffer. Returns the handle that was passed in. */
virtual uint64 GetVirtualTextureRequestRecordBuffer(TSet<uint64>& OutPageRequests) = 0;
/** Request an array of virtual texture page requests that was captured with SetVirtualTextureRequestRecordBuffer. Note that the array will be moved and ownership is taken. */
virtual void RequestVirtualTextureTiles(TArray<uint64>&& InPageRequests) = 0;
/** Evict all data from virtual texture caches. */
virtual void FlushVirtualTextureCache() = 0;
/** Evict all data from virtual texture cache for a given allocated virtual texture. */
virtual void FlushVirtualTextureCache(IAllocatedVirtualTexture* AllocatedVT, const FVector2f& InUV0, const FVector2f& InUV1) = 0;
/** Allocate a buffer and record all nanite page requests until the next call to either SetNaniteRequestRecordBuffer or GetNaniteRequestRecordBuffer. */
virtual void SetNaniteRequestRecordBuffer(uint64 Handle) = 0;
/** Fetch the page requests recorded since the last call to SetNaniteRequestRecordBuffer. Returns the handle that was passed in. */
virtual uint64 GetNaniteRequestRecordBuffer(TArray<uint32>& OutRequestData) = 0;
/** Request Nanite pages that were captured with SetNaniteRequestRecordBuffer. Note that the array will be moved and ownership is taken. */
virtual void RequestNanitePages(TArrayView<uint32> InRequestData) = 0;
/** Start prefetching streaming data for Nanite resource that will soon be used for rendering. TODO: Implement callback mechanism */
virtual void PrefetchNaniteResource(const Nanite::FResources* Resource, uint32 NumFramesUntilRender) = 0;
UE_DEPRECATED(5.4, "IPersistentViewUniformBufferExtension will be removed in a future version.")
virtual void RegisterPersistentViewUniformBufferExtension(IPersistentViewUniformBufferExtension* Extension) = 0;
/**
* Prepare Scene primitive rendering and return context. Ensures all primitives that are created are commited and GPU-Scene is updated and allocates a dynamic primitive context.
* The intended use is for stand-alone rendering that involves Scene proxies (that then may need the machinery to render GPU-Scene aware primitives.
*/
virtual IScenePrimitiveRenderingContext* BeginScenePrimitiveRendering(FRDGBuilder& GraphBuilder, FSceneViewFamily* ViewFamily) = 0;
virtual IScenePrimitiveRenderingContext* BeginScenePrimitiveRendering(FRDGBuilder& GraphBuilder, FSceneInterface& Scene) = 0;
/** Mark all the current scenes as needing to restart path tracer accumulation */
virtual void InvalidatePathTracedOutput(PathTracing::EInvalidateReason InvalidateReason = PathTracing::EInvalidateReason::Uncategorized) = 0;
/** Experimental: Render multiple view families in a single scene render call. All families must reference the same FScene. Scene Capture not yet supported. */
virtual void BeginRenderingViewFamilies(FCanvas* Canvas, TConstArrayView<FSceneViewFamily*> ViewFamilies) = 0;
/** Resets the scene texture extent history. Call this method after rendering with very large render
* targets. The next scene render will create them at the requested size.
*/
virtual void ResetSceneTextureExtentHistory() = 0;
virtual const FViewMatrices& GetPreviousViewMatrices(const FSceneView& View) = 0;
virtual const FGlobalDistanceFieldParameterData* GetGlobalDistanceFieldParameterData(const FSceneView& View) = 0;
virtual void RequestStaticMeshUpdate(FPrimitiveSceneInfo* Info) = 0;
virtual void AddMeshBatchToGPUScene(FGPUScenePrimitiveCollector* Collector, FMeshBatch& MeshBatch) = 0;
virtual TUniquePtr<ISceneRenderBuilder> CreateSceneRenderBuilder(FSceneInterface* Scene) = 0;
};