You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
1317 lines
36 KiB
C++
1317 lines
36 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "RenderGraphParameter.h"
|
|
#include "RenderGraphTextureSubresource.h"
|
|
#include "RendererInterface.h"
|
|
|
|
struct FPooledRenderTarget;
|
|
class FRenderTargetPool;
|
|
|
|
/** Used for tracking pass producer / consumer edges in the graph for culling and pipe fencing. */
|
|
struct FRDGProducerState
|
|
{
|
|
/** Returns whether the next state is dependent on the last producer in the producer graph. */
|
|
static bool IsDependencyRequired(FRDGProducerState LastProducer, ERHIPipeline LastPipeline, FRDGProducerState NextState, ERHIPipeline NextPipeline);
|
|
|
|
FRDGProducerState() = default;
|
|
|
|
ERHIAccess Access = ERHIAccess::Unknown;
|
|
FRDGPassHandle PassHandle;
|
|
FRDGViewHandle NoUAVBarrierHandle;
|
|
};
|
|
|
|
using FRDGProducerStatesByPipeline = TRHIPipelineArray<FRDGProducerState>;
|
|
|
|
/** Used for tracking the state of an individual subresource during execution. */
|
|
struct FRDGSubresourceState
|
|
{
|
|
/** Given a before and after state, returns whether a resource barrier is required. */
|
|
static bool IsTransitionRequired(const FRDGSubresourceState& Previous, const FRDGSubresourceState& Next);
|
|
|
|
/** Given a before and after state, returns whether they can be merged into a single state. */
|
|
static bool IsMergeAllowed(ERDGParentResourceType ResourceType, const FRDGSubresourceState& Previous, const FRDGSubresourceState& Next);
|
|
|
|
FRDGSubresourceState() = default;
|
|
|
|
/** Initializes the first and last pass and the pipeline. Clears any other pass state. */
|
|
void SetPass(ERHIPipeline Pipeline, FRDGPassHandle PassHandle);
|
|
|
|
/** Finalizes the state at the end of the transition chain; keeps access intact. */
|
|
void Finalize();
|
|
|
|
/** Validates that the state is in a correct configuration for use. */
|
|
void Validate();
|
|
|
|
/** Returns whether the state is used by the pipeline. */
|
|
bool IsUsedBy(ERHIPipeline Pipeline) const;
|
|
|
|
/** Returns the last pass across either pipe. */
|
|
FRDGPassHandle GetLastPass() const;
|
|
|
|
/** Returns the first pass across either pipe. */
|
|
FRDGPassHandle GetFirstPass() const;
|
|
|
|
/** Returns the pipeline mask this state is used on. */
|
|
ERHIPipeline GetPipelines() const;
|
|
|
|
/** The last used access on the pass. */
|
|
ERHIAccess Access = ERHIAccess::Unknown;
|
|
|
|
/** The last used transition flags on the pass. */
|
|
EResourceTransitionFlags Flags = EResourceTransitionFlags::None;
|
|
|
|
/** The first pass in this state. */
|
|
FRDGPassHandlesByPipeline FirstPass;
|
|
|
|
/** The last pass in this state. */
|
|
FRDGPassHandlesByPipeline LastPass;
|
|
|
|
/** The last no-UAV barrier to be used by this subresource. */
|
|
FRDGViewUniqueFilter NoUAVBarrierFilter;
|
|
};
|
|
|
|
using FRDGTextureSubresourceState = TRDGTextureSubresourceArray<FRDGSubresourceState, FDefaultAllocator>;
|
|
using FRDGTextureTransientSubresourceState = TRDGTextureSubresourceArray<FRDGSubresourceState, FRDGArrayAllocator>;
|
|
using FRDGTextureTransientSubresourceStateIndirect = TRDGTextureSubresourceArray<FRDGSubresourceState*, FRDGArrayAllocator>;
|
|
|
|
/** Generic graph resource. */
|
|
class RENDERCORE_API FRDGResource
|
|
{
|
|
public:
|
|
FRDGResource(const FRDGResource&) = delete;
|
|
virtual ~FRDGResource() = default;
|
|
|
|
// Name of the resource for debugging purpose.
|
|
const TCHAR* const Name = nullptr;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//! The following methods may only be called during pass execution.
|
|
|
|
/** Marks this resource as actually used by a resource. This is to track what dependencies on pass was actually unnecessary. */
|
|
#if RDG_ENABLE_DEBUG
|
|
virtual void MarkResourceAsUsed();
|
|
#else
|
|
inline void MarkResourceAsUsed() {}
|
|
#endif
|
|
|
|
FRHIResource* GetRHI() const
|
|
{
|
|
IF_RDG_ENABLE_DEBUG(ValidateRHIAccess());
|
|
return ResourceRHI;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
protected:
|
|
FRDGResource(const TCHAR* InName)
|
|
: Name(InName)
|
|
{}
|
|
|
|
FRHIResource* GetRHIUnchecked() const
|
|
{
|
|
return ResourceRHI;
|
|
}
|
|
|
|
FRHIResource* ResourceRHI = nullptr;
|
|
|
|
#if RDG_ENABLE_DEBUG
|
|
void ValidateRHIAccess() const;
|
|
#endif
|
|
|
|
private:
|
|
#if RDG_ENABLE_DEBUG
|
|
struct FRDGResourceDebugData* DebugData = nullptr;
|
|
FRDGResourceDebugData& GetDebugData() const;
|
|
bool IsPassthrough() const;
|
|
#endif
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGUserValidation;
|
|
};
|
|
|
|
class FRDGUniformBuffer
|
|
: public FRDGResource
|
|
{
|
|
public:
|
|
FORCEINLINE const FRDGParameterStruct& GetParameters() const
|
|
{
|
|
return ParameterStruct;
|
|
}
|
|
|
|
#if RDG_ENABLE_DEBUG
|
|
RENDERCORE_API void MarkResourceAsUsed() override;
|
|
#else
|
|
inline void MarkResourceAsUsed() {}
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//! The following methods may only be called during pass execution.
|
|
|
|
FRHIUniformBuffer* GetRHI() const
|
|
{
|
|
return static_cast<FRHIUniformBuffer*>(FRDGResource::GetRHI());
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
protected:
|
|
template <typename TParameterStruct>
|
|
explicit FRDGUniformBuffer(const TParameterStruct* InParameters, const TCHAR* InName)
|
|
: FRDGResource(InName)
|
|
, ParameterStruct(InParameters)
|
|
{}
|
|
|
|
private:
|
|
|
|
const FRDGParameterStruct ParameterStruct;
|
|
TRefCountPtr<FRHIUniformBuffer> UniformBufferRHI;
|
|
FRDGUniformBufferHandle Handle;
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGUniformBufferRegistry;
|
|
friend FRDGAllocator;
|
|
};
|
|
|
|
template <typename ParameterStructType>
|
|
class TRDGUniformBuffer : public FRDGUniformBuffer
|
|
{
|
|
public:
|
|
FORCEINLINE const TRDGParameterStruct<ParameterStructType>& GetParameters() const
|
|
{
|
|
return static_cast<const TRDGParameterStruct<ParameterStructType>&>(FRDGUniformBuffer::GetParameters());
|
|
}
|
|
|
|
FORCEINLINE TUniformBufferRef<ParameterStructType> GetRHIRef() const
|
|
{
|
|
return TUniformBufferRef<ParameterStructType>(GetRHI());
|
|
}
|
|
|
|
FORCEINLINE const ParameterStructType* operator->() const
|
|
{
|
|
return Parameters;
|
|
}
|
|
|
|
private:
|
|
explicit TRDGUniformBuffer(const ParameterStructType* InParameters, const TCHAR* InName)
|
|
: FRDGUniformBuffer(InParameters, InName)
|
|
, Parameters(InParameters)
|
|
{}
|
|
|
|
const ParameterStructType* Parameters;
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGUniformBufferRegistry;
|
|
friend FRDGAllocator;
|
|
};
|
|
|
|
/** A render graph resource with an allocation lifetime tracked by the graph. May have child resources which reference it (e.g. views). */
|
|
class RENDERCORE_API FRDGParentResource
|
|
: public FRDGResource
|
|
{
|
|
public:
|
|
/** The type of this resource; useful for casting between types. */
|
|
const ERDGParentResourceType Type;
|
|
|
|
/** Whether this resource is externally registered with the graph (i.e. the user holds a reference to the underlying resource outside the graph). */
|
|
bool IsExternal() const
|
|
{
|
|
return bExternal;
|
|
}
|
|
|
|
/** Whether this resource is has been queued for extraction at the end of graph execution. */
|
|
bool IsExtracted() const
|
|
{
|
|
return bExtracted;
|
|
}
|
|
|
|
/** Whether a prior pass added to the graph produced contents for this resource. External resources are not considered produced
|
|
* until used for a write operation. This is a union of all subresources, so any subresource write will set this to true.
|
|
*/
|
|
bool HasBeenProduced() const
|
|
{
|
|
return bProduced;
|
|
}
|
|
|
|
protected:
|
|
FRDGParentResource(const TCHAR* InName, ERDGParentResourceType InType);
|
|
|
|
/** Whether this is an externally registered resource. */
|
|
uint8 bExternal : 1;
|
|
|
|
/** Whether this is an extracted resource. */
|
|
uint8 bExtracted : 1;
|
|
|
|
/** Whether any sub-resource has been used for write by a pass. */
|
|
uint8 bProduced : 1;
|
|
|
|
/** Whether this resource needs acquire / discard. */
|
|
uint8 bTransient : 1;
|
|
|
|
/** Whether this resource is the last owner of its allocation (i.e. nothing aliases the allocation later in the execution timeline). */
|
|
uint8 bLastOwner : 1;
|
|
|
|
/** If true, the resource was not used by any pass not culled by the graph. */
|
|
uint8 bCulled : 1;
|
|
|
|
/** If true, the resource has been used on an async compute pass and may have async compute states. */
|
|
uint8 bUsedByAsyncComputePass : 1;
|
|
|
|
/** Assigns this resource as a simple passthrough container for an RHI resource. */
|
|
void SetPassthroughRHI(FRHIResource* InResourceRHI);
|
|
|
|
private:
|
|
/** Number of references in passes and deferred queries. */
|
|
uint16 ReferenceCount = 0;
|
|
|
|
/** The initial and final states of the resource assigned by the user, if known. */
|
|
ERHIAccess AccessInitial = ERHIAccess::Unknown;
|
|
ERHIAccess AccessFinal = ERHIAccess::Unknown;
|
|
|
|
FRDGPassHandle AcquirePass;
|
|
FRDGPassHandle FirstPass;
|
|
FRDGPassHandle LastPass;
|
|
|
|
#if RDG_ENABLE_TRACE
|
|
uint16 TraceOrder = 0;
|
|
TArray<FRDGPassHandle, FRDGArrayAllocator> TracePasses;
|
|
#endif
|
|
|
|
#if RDG_ENABLE_DEBUG
|
|
struct FRDGParentResourceDebugData* ParentDebugData = nullptr;
|
|
FRDGParentResourceDebugData& GetParentDebugData() const;
|
|
#endif
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGUserValidation;
|
|
friend FRDGBarrierBatchBegin;
|
|
friend FRDGTrace;
|
|
};
|
|
|
|
/** A render graph resource (e.g. a view) which references a single parent resource (e.g. a texture / buffer). Provides an abstract way to access the parent resource. */
|
|
class FRDGView
|
|
: public FRDGResource
|
|
{
|
|
public:
|
|
/** The type of this child resource; useful for casting between types. */
|
|
const ERDGViewType Type;
|
|
|
|
/** Returns the referenced parent render graph resource. */
|
|
virtual FRDGParentResourceRef GetParent() const = 0;
|
|
|
|
FRDGViewHandle GetHandle() const
|
|
{
|
|
return Handle;
|
|
}
|
|
|
|
protected:
|
|
FRDGView(const TCHAR* Name, ERDGViewType InType)
|
|
: FRDGResource(Name)
|
|
, Type(InType)
|
|
{}
|
|
|
|
private:
|
|
FRDGViewHandle Handle;
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGViewRegistry;
|
|
friend FRDGAllocator;
|
|
};
|
|
|
|
/** Descriptor used to create a render graph texture. */
|
|
struct RENDERCORE_API FRDGTextureDesc
|
|
{
|
|
static FRDGTextureDesc Create2D(
|
|
FIntPoint InExtent,
|
|
EPixelFormat InFormat,
|
|
FClearValueBinding InClearValue,
|
|
ETextureCreateFlags InFlags,
|
|
uint8 InNumMips = 1,
|
|
uint8 InNumSamples = 1)
|
|
{
|
|
return FRDGTextureDesc(InClearValue, ETextureDimension::Texture2D, InFlags, InFormat, InExtent, 1, 1, InNumMips, InNumSamples);
|
|
}
|
|
|
|
static FRDGTextureDesc Create2DArray(
|
|
FIntPoint InExtent,
|
|
EPixelFormat InFormat,
|
|
FClearValueBinding InClearValue,
|
|
ETextureCreateFlags InFlags,
|
|
uint32 InArraySize,
|
|
uint8 InNumMips = 1,
|
|
uint8 InNumSamples = 1)
|
|
{
|
|
return FRDGTextureDesc(InClearValue, ETextureDimension::Texture2DArray, InFlags, InFormat, InExtent, 1, InArraySize, InNumMips, InNumSamples);
|
|
}
|
|
|
|
static FRDGTextureDesc Create3D(
|
|
FIntVector InSize,
|
|
EPixelFormat InFormat,
|
|
FClearValueBinding InClearValue,
|
|
ETextureCreateFlags InFlags,
|
|
uint8 InNumMips = 1,
|
|
uint8 InNumSamples = 1)
|
|
{
|
|
return FRDGTextureDesc(InClearValue, ETextureDimension::Texture3D, InFlags, InFormat, FIntPoint(InSize.X, InSize.Y), InSize.Z, 1, InNumMips, InNumSamples);
|
|
}
|
|
|
|
static FRDGTextureDesc CreateCube(
|
|
uint32 InSizeInPixels,
|
|
EPixelFormat InFormat,
|
|
FClearValueBinding InClearValue,
|
|
ETextureCreateFlags InFlags,
|
|
uint8 InNumMips = 1,
|
|
uint8 InNumSamples = 1)
|
|
{
|
|
return FRDGTextureDesc(InClearValue, ETextureDimension::TextureCube, InFlags, InFormat, FIntPoint(InSizeInPixels, InSizeInPixels), 1, 1, InNumMips, InNumSamples);
|
|
}
|
|
|
|
static FRDGTextureDesc CreateCubeArray(
|
|
uint32 InSizeInPixels,
|
|
EPixelFormat InFormat,
|
|
FClearValueBinding InClearValue,
|
|
ETextureCreateFlags InFlags,
|
|
uint32 InArraySize,
|
|
uint8 InNumMips = 1,
|
|
uint8 InNumSamples = 1)
|
|
{
|
|
return FRDGTextureDesc(InClearValue, ETextureDimension::TextureCubeArray, InFlags, InFormat, FIntPoint(InSizeInPixels, InSizeInPixels), 1, InArraySize, InNumMips, InNumSamples);
|
|
}
|
|
|
|
FRDGTextureDesc() = default;
|
|
FRDGTextureDesc(
|
|
FClearValueBinding InClearValue,
|
|
ETextureDimension InDimension,
|
|
ETextureCreateFlags InFlags,
|
|
EPixelFormat InFormat,
|
|
FIntPoint InExtent,
|
|
uint16 InDepth = 1,
|
|
uint16 InArraySize = 1,
|
|
uint8 InNumMips = 1,
|
|
uint8 InNumSamples = 1)
|
|
: ClearValue(InClearValue)
|
|
, Dimension(InDimension)
|
|
, Flags(InFlags)
|
|
, Format(InFormat)
|
|
, Extent(InExtent)
|
|
, Depth(InDepth)
|
|
, ArraySize(InArraySize)
|
|
, NumMips(InNumMips)
|
|
, NumSamples(InNumSamples)
|
|
{}
|
|
|
|
bool operator == (const FRDGTextureDesc& Other) const
|
|
{
|
|
return ClearValue == Other.ClearValue
|
|
&& Dimension == Other.Dimension
|
|
&& Flags == Other.Flags
|
|
&& Format == Other.Format
|
|
&& Extent == Other.Extent
|
|
&& Depth == Other.Depth
|
|
&& ArraySize == Other.ArraySize
|
|
&& NumMips == Other.NumMips
|
|
&& NumSamples == Other.NumSamples;
|
|
}
|
|
|
|
bool operator != (const FRDGTextureDesc& Other) const
|
|
{
|
|
return !(*this == Other);
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
// Usually we don't want to propagate MSAA samples.
|
|
NumSamples = 1;
|
|
|
|
// Remove UAV flag for textures that don't need it (some formats are incompatible).
|
|
Flags |= TexCreate_RenderTargetable;
|
|
Flags &= ~(TexCreate_UAV | TexCreate_FastVRAM | TexCreate_Transient | TexCreate_ResolveTargetable | TexCreate_DepthStencilResolveTarget);
|
|
}
|
|
|
|
bool IsTexture2D() const
|
|
{
|
|
return Dimension == ETextureDimension::Texture2D || Dimension == ETextureDimension::Texture2DArray;
|
|
}
|
|
|
|
bool IsTexture3D() const
|
|
{
|
|
return Dimension == ETextureDimension::Texture3D;
|
|
}
|
|
|
|
bool IsTextureCube() const
|
|
{
|
|
return Dimension == ETextureDimension::TextureCube || Dimension == ETextureDimension::TextureCubeArray;
|
|
}
|
|
|
|
bool IsTextureArray() const
|
|
{
|
|
return Dimension == ETextureDimension::Texture2DArray || Dimension == ETextureDimension::TextureCubeArray;
|
|
}
|
|
|
|
bool IsMipChain() const
|
|
{
|
|
return NumMips > 1;
|
|
}
|
|
|
|
bool IsMultisample() const
|
|
{
|
|
return NumSamples > 1;
|
|
}
|
|
|
|
FIntVector GetSize() const
|
|
{
|
|
return FIntVector(Extent.X, Extent.Y, Depth);
|
|
}
|
|
|
|
FRDGTextureSubresourceLayout GetSubresourceLayout() const
|
|
{
|
|
return FRDGTextureSubresourceLayout(NumMips, ArraySize * (IsTextureCube() ? 6 : 1), IsStencilFormat(Format) ? 2 : 1);
|
|
}
|
|
|
|
/** Returns whether this descriptor conforms to requirements. */
|
|
bool IsValid() const;
|
|
|
|
/** Clear value to use when fast-clearing the texture. */
|
|
FClearValueBinding ClearValue;
|
|
|
|
/** Texture dimension to use when creating the RHI texture. */
|
|
ETextureDimension Dimension = ETextureDimension::Texture2D;
|
|
|
|
/** Texture flags passed on to RHI texture. */
|
|
ETextureCreateFlags Flags = TexCreate_None;
|
|
|
|
/** Pixel format used to create RHI texture. */
|
|
EPixelFormat Format = PF_Unknown;
|
|
|
|
/** Extent of the texture in x and y. */
|
|
FIntPoint Extent = FIntPoint(1, 1);
|
|
|
|
/** Depth of the texture if the dimension is 3D. */
|
|
uint16 Depth = 1;
|
|
|
|
/** The number of array elements in the texture. (Keep at 1 if dimension is 3D). */
|
|
uint16 ArraySize = 1;
|
|
|
|
/** Number of mips in the texture mip-map chain. */
|
|
uint8 NumMips = 1;
|
|
|
|
/** Number of samples in the texture. >1 for MSAA. */
|
|
uint8 NumSamples = 1;
|
|
};
|
|
|
|
/** Translates from a pooled render target descriptor to an RDG texture descriptor. */
|
|
inline FRDGTextureDesc Translate(const FPooledRenderTargetDesc& InDesc, ERenderTargetTexture InTexture = ERenderTargetTexture::Targetable);
|
|
|
|
/** Translates from an RDG texture descriptor to a pooled render target descriptor. */
|
|
inline FPooledRenderTargetDesc Translate(const FRDGTextureDesc& InDesc);
|
|
|
|
class RENDERCORE_API FRDGPooledTexture
|
|
{
|
|
public:
|
|
const FRDGTextureDesc Desc;
|
|
|
|
FRHITexture* GetRHI() const
|
|
{
|
|
return Texture;
|
|
}
|
|
|
|
FRDGTexture* GetOwner() const
|
|
{
|
|
return Owner;
|
|
}
|
|
|
|
uint32 GetRefCount() const
|
|
{
|
|
return RefCount;
|
|
}
|
|
|
|
uint32 AddRef() const
|
|
{
|
|
return ++RefCount;
|
|
}
|
|
|
|
uint32 Release() const
|
|
{
|
|
if (--RefCount == 0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return RefCount;
|
|
}
|
|
|
|
private:
|
|
FRDGPooledTexture(FRHITexture* InTexture, const FRDGTextureDesc& InDesc, const FUnorderedAccessViewRHIRef& FirstMipUAV)
|
|
: Desc(InDesc)
|
|
, Texture(InTexture)
|
|
, Layout(InDesc.GetSubresourceLayout())
|
|
{
|
|
InitViews(FirstMipUAV);
|
|
Reset();
|
|
}
|
|
|
|
/** Initializes cached views. Safe to call multiple times; each call will recreate. */
|
|
void InitViews(const FUnorderedAccessViewRHIRef& FirstMipUAV);
|
|
|
|
void Finalize()
|
|
{
|
|
for (FRDGSubresourceState& SubresourceState : State)
|
|
{
|
|
SubresourceState.Finalize();
|
|
}
|
|
Owner = nullptr;
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
InitAsWholeResource(State);
|
|
Owner = nullptr;
|
|
}
|
|
|
|
FRHITexture* Texture = nullptr;
|
|
FRDGTexture* Owner = nullptr;
|
|
FRDGTextureSubresourceLayout Layout;
|
|
FRDGTextureSubresourceState State;
|
|
|
|
/** Cached views created for the RHI texture. */
|
|
TArray<FUnorderedAccessViewRHIRef, TInlineAllocator<1>> MipUAVs;
|
|
TArray<TPair<FRHITextureSRVCreateInfo, FShaderResourceViewRHIRef>, TInlineAllocator<1>> SRVs;
|
|
FUnorderedAccessViewRHIRef HTileUAV;
|
|
FShaderResourceViewRHIRef HTileSRV;
|
|
FUnorderedAccessViewRHIRef StencilUAV;
|
|
FShaderResourceViewRHIRef FMaskSRV;
|
|
FShaderResourceViewRHIRef CMaskSRV;
|
|
|
|
mutable uint32 RefCount = 0;
|
|
|
|
friend FRDGTexture;
|
|
friend FRDGBuilder;
|
|
friend FPooledRenderTarget;
|
|
friend FRenderTargetPool;
|
|
};
|
|
|
|
/** Render graph tracked Texture. */
|
|
class RENDERCORE_API FRDGTexture final
|
|
: public FRDGParentResource
|
|
{
|
|
public:
|
|
/** Creates a passthrough texture suitable for filling RHI uniform buffers with RDG parameters for passes not yet ported to RDG. */
|
|
static FRDGTextureRef GetPassthrough(const TRefCountPtr<IPooledRenderTarget>& PooledRenderTarget);
|
|
|
|
const FRDGTextureDesc Desc;
|
|
const ERDGTextureFlags Flags;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//! The following methods may only be called during pass execution.
|
|
|
|
/** Returns the allocated pooled render target. */
|
|
IPooledRenderTarget* GetPooledRenderTarget() const
|
|
{
|
|
IF_RDG_ENABLE_DEBUG(ValidateRHIAccess());
|
|
check(PooledRenderTarget);
|
|
return PooledRenderTarget;
|
|
}
|
|
|
|
/** Returns the allocated RHI texture. */
|
|
FRHITexture* GetRHI() const
|
|
{
|
|
return static_cast<FRHITexture*>(FRDGResource::GetRHI());
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
FRDGTextureHandle GetHandle() const
|
|
{
|
|
return Handle;
|
|
}
|
|
|
|
FRDGTextureSubresourceLayout GetSubresourceLayout() const
|
|
{
|
|
return Layout;
|
|
}
|
|
|
|
FRDGTextureSubresourceRange GetSubresourceRange() const
|
|
{
|
|
return FRDGTextureSubresourceRange(Layout);
|
|
}
|
|
|
|
FRDGTextureSubresourceRange GetSubresourceRangeSRV() const;
|
|
|
|
private:
|
|
FRDGTexture(const TCHAR* InName, const FRDGTextureDesc& InDesc, ERDGTextureFlags InFlags, ERenderTargetTexture InRenderTargetTexture)
|
|
: FRDGParentResource(InName, ERDGParentResourceType::Texture)
|
|
, Desc(InDesc)
|
|
, Flags(InFlags)
|
|
, RenderTargetTexture(InRenderTargetTexture)
|
|
, Layout(InDesc.GetSubresourceLayout())
|
|
{
|
|
InitAsWholeResource(MergeState);
|
|
InitAsWholeResource(LastProducers);
|
|
}
|
|
|
|
/** Assigns the pooled texture to this texture; returns the previous texture to own the allocation. */
|
|
void SetRHI(FPooledRenderTarget* PooledRenderTarget, FRDGTextureRef& OutPreviousOwner);
|
|
|
|
/** Finalizes the texture for execution; no other transitions are allowed after calling this. */
|
|
void Finalize();
|
|
|
|
/** Returns RHI texture without access checks. */
|
|
FRHITexture* GetRHIUnchecked() const
|
|
{
|
|
return static_cast<FRHITexture*>(FRDGResource::GetRHIUnchecked());
|
|
}
|
|
|
|
/** Whether this texture is the last owner of the allocation in the graph. */
|
|
bool IsLastOwner() const
|
|
{
|
|
return NextOwner.IsNull();
|
|
}
|
|
|
|
/** Returns the current texture state. Only valid to call after SetRHI. */
|
|
FRDGTextureSubresourceState& GetState()
|
|
{
|
|
check(State);
|
|
return *State;
|
|
}
|
|
|
|
/** Describes which RHI texture this RDG texture represents on a pooled texture. Must be default unless the texture is externally registered. */
|
|
const ERenderTargetTexture RenderTargetTexture;
|
|
|
|
/** The layout used to facilitate subresource transitions. */
|
|
FRDGTextureSubresourceLayout Layout;
|
|
|
|
/** The next texture to own the PooledTexture allocation during execution. */
|
|
FRDGTextureHandle NextOwner;
|
|
|
|
/** The handle registered with the builder. */
|
|
FRDGTextureHandle Handle;
|
|
|
|
/** The assigned pooled render target to use during execution. Never reset. */
|
|
IPooledRenderTarget* PooledRenderTarget = nullptr;
|
|
|
|
/** The assigned pooled texture to use during execution. Never reset. */
|
|
FRDGPooledTexture* PooledTexture = nullptr;
|
|
|
|
/** Cached state pointer from the pooled texture. */
|
|
FRDGTextureSubresourceState* State = nullptr;
|
|
|
|
/** Valid strictly when holding a strong reference; use PooledRenderTarget instead. */
|
|
TRefCountPtr<IPooledRenderTarget> Allocation;
|
|
|
|
/** Tracks merged subresource states as the graph is built. */
|
|
FRDGTextureTransientSubresourceStateIndirect MergeState;
|
|
|
|
/** Tracks pass producers for each subresource as the graph is built. */
|
|
TRDGTextureSubresourceArray<FRDGProducerStatesByPipeline> LastProducers;
|
|
|
|
#if RDG_ENABLE_DEBUG
|
|
struct FRDGTextureDebugData* TextureDebugData = nullptr;
|
|
FRDGTextureDebugData& GetTextureDebugData() const;
|
|
#endif
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGUserValidation;
|
|
friend FRDGBarrierValidation;
|
|
friend FRDGTextureRegistry;
|
|
friend FRDGAllocator;
|
|
friend FPooledRenderTarget;
|
|
friend FRDGTrace;
|
|
};
|
|
|
|
/** Render graph tracked SRV. */
|
|
class FRDGShaderResourceView
|
|
: public FRDGView
|
|
{
|
|
public:
|
|
/** Returns the allocated RHI SRV. */
|
|
FRHIShaderResourceView* GetRHI() const
|
|
{
|
|
return static_cast<FRHIShaderResourceView*>(FRDGResource::GetRHI());
|
|
}
|
|
|
|
protected:
|
|
FRDGShaderResourceView(const TCHAR* InName, ERDGViewType InType)
|
|
: FRDGView(InName, InType)
|
|
{}
|
|
|
|
/** Returns the allocated RHI SRV without access checks. */
|
|
FRHIShaderResourceView* GetRHIUnchecked() const
|
|
{
|
|
return static_cast<FRHIShaderResourceView*>(FRDGResource::GetRHIUnchecked());
|
|
}
|
|
};
|
|
|
|
/** Render graph tracked UAV. */
|
|
class FRDGUnorderedAccessView
|
|
: public FRDGView
|
|
{
|
|
public:
|
|
const ERDGUnorderedAccessViewFlags Flags;
|
|
|
|
/** Returns the allocated RHI UAV. */
|
|
FRHIUnorderedAccessView* GetRHI() const
|
|
{
|
|
return static_cast<FRHIUnorderedAccessView*>(FRDGResource::GetRHI());
|
|
}
|
|
|
|
protected:
|
|
FRDGUnorderedAccessView(const TCHAR* InName, ERDGViewType InType, ERDGUnorderedAccessViewFlags InFlags)
|
|
: FRDGView(InName, InType)
|
|
, Flags(InFlags)
|
|
{}
|
|
|
|
/** Returns the allocated RHI UAV without access checks. */
|
|
FRHIUnorderedAccessView* GetRHIUnchecked() const
|
|
{
|
|
return static_cast<FRHIUnorderedAccessView*>(FRDGResource::GetRHIUnchecked());
|
|
}
|
|
};
|
|
|
|
/** Descriptor for render graph tracked SRV. */
|
|
class FRDGTextureSRVDesc final
|
|
: public FRHITextureSRVCreateInfo
|
|
{
|
|
public:
|
|
FRDGTextureSRVDesc() = default;
|
|
|
|
FRDGTextureRef Texture = nullptr;
|
|
ERDGTextureMetaDataAccess MetaData = ERDGTextureMetaDataAccess::None;
|
|
|
|
/** Create SRV that access all sub resources of texture. */
|
|
static FRDGTextureSRVDesc Create(FRDGTextureRef Texture)
|
|
{
|
|
FRDGTextureSRVDesc Desc;
|
|
Desc.Texture = Texture;
|
|
Desc.NumMipLevels = Texture->Desc.NumMips;
|
|
return Desc;
|
|
}
|
|
|
|
/** Create SRV that access one specific mip level. */
|
|
static FRDGTextureSRVDesc CreateForMipLevel(FRDGTextureRef Texture, int32 MipLevel)
|
|
{
|
|
FRDGTextureSRVDesc Desc;
|
|
Desc.Texture = Texture;
|
|
Desc.MipLevel = MipLevel;
|
|
Desc.NumMipLevels = 1;
|
|
return Desc;
|
|
}
|
|
|
|
/** Create SRV that access one specific mip level. */
|
|
static FRDGTextureSRVDesc CreateWithPixelFormat(FRDGTextureRef Texture, EPixelFormat PixelFormat)
|
|
{
|
|
FRDGTextureSRVDesc Desc = FRDGTextureSRVDesc::Create(Texture);
|
|
Desc.Format = PixelFormat;
|
|
return Desc;
|
|
}
|
|
|
|
/** Create SRV with access to a specific meta data plane */
|
|
static FRDGTextureSRVDesc CreateForMetaData(FRDGTextureRef Texture, ERDGTextureMetaDataAccess MetaData)
|
|
{
|
|
FRDGTextureSRVDesc Desc = FRDGTextureSRVDesc::Create(Texture);
|
|
Desc.MetaData = MetaData;
|
|
return Desc;
|
|
}
|
|
};
|
|
|
|
/** Render graph tracked SRV. */
|
|
class FRDGTextureSRV final
|
|
: public FRDGShaderResourceView
|
|
{
|
|
public:
|
|
/** Descriptor of the graph tracked SRV. */
|
|
const FRDGTextureSRVDesc Desc;
|
|
|
|
FRDGTextureRef GetParent() const override
|
|
{
|
|
return Desc.Texture;
|
|
}
|
|
|
|
FRDGTextureSubresourceRange GetSubresourceRange() const;
|
|
|
|
private:
|
|
FRDGTextureSRV(const TCHAR* InName, const FRDGTextureSRVDesc& InDesc)
|
|
: FRDGShaderResourceView(InName, ERDGViewType::TextureSRV)
|
|
, Desc(InDesc)
|
|
{}
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGViewRegistry;
|
|
friend FRDGAllocator;
|
|
};
|
|
|
|
/** Descriptor for render graph tracked UAV. */
|
|
class FRDGTextureUAVDesc
|
|
{
|
|
public:
|
|
FRDGTextureUAVDesc() = default;
|
|
|
|
FRDGTextureUAVDesc(FRDGTextureRef InTexture, uint8 InMipLevel = 0)
|
|
: Texture(InTexture)
|
|
, MipLevel(InMipLevel)
|
|
{}
|
|
|
|
/** Create UAV with access to a specific meta data plane */
|
|
static FRDGTextureUAVDesc CreateForMetaData(FRDGTextureRef Texture, ERDGTextureMetaDataAccess MetaData)
|
|
{
|
|
FRDGTextureUAVDesc Desc = FRDGTextureUAVDesc(Texture, 0);
|
|
Desc.MetaData = MetaData;
|
|
return Desc;
|
|
}
|
|
|
|
FRDGTextureRef Texture = nullptr;
|
|
uint8 MipLevel = 0;
|
|
ERDGTextureMetaDataAccess MetaData = ERDGTextureMetaDataAccess::None;
|
|
};
|
|
|
|
/** Render graph tracked texture UAV. */
|
|
class FRDGTextureUAV final
|
|
: public FRDGUnorderedAccessView
|
|
{
|
|
public:
|
|
/** Descriptor of the graph tracked UAV. */
|
|
const FRDGTextureUAVDesc Desc;
|
|
|
|
FRDGTextureRef GetParent() const override
|
|
{
|
|
return Desc.Texture;
|
|
}
|
|
|
|
FRDGTextureSubresourceRange GetSubresourceRange() const;
|
|
|
|
private:
|
|
FRDGTextureUAV(const TCHAR* InName, const FRDGTextureUAVDesc& InDesc, ERDGUnorderedAccessViewFlags InFlags)
|
|
: FRDGUnorderedAccessView(InName, ERDGViewType::TextureUAV, InFlags)
|
|
, Desc(InDesc)
|
|
{}
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGViewRegistry;
|
|
friend FRDGAllocator;
|
|
};
|
|
|
|
/** Descriptor for render graph tracked Buffer. */
|
|
struct FRDGBufferDesc
|
|
{
|
|
enum class EUnderlyingType
|
|
{
|
|
VertexBuffer,
|
|
StructuredBuffer
|
|
};
|
|
|
|
/** Create the descriptor for an indirect RHI call.
|
|
*
|
|
* Note, IndirectParameterStruct should be one of the:
|
|
* struct FRHIDispatchIndirectParameters
|
|
* struct FRHIDrawIndirectParameters
|
|
* struct FRHIDrawIndexedIndirectParameters
|
|
*/
|
|
template<typename IndirectParameterStruct>
|
|
static FRDGBufferDesc CreateIndirectDesc(uint32 NumElements = 1)
|
|
{
|
|
FRDGBufferDesc Desc;
|
|
Desc.UnderlyingType = EUnderlyingType::VertexBuffer;
|
|
Desc.Usage = (EBufferUsageFlags)(BUF_Static | BUF_DrawIndirect | BUF_UnorderedAccess | BUF_ShaderResource);
|
|
Desc.BytesPerElement = sizeof(IndirectParameterStruct);
|
|
Desc.NumElements = NumElements;
|
|
return Desc;
|
|
}
|
|
|
|
static FRDGBufferDesc CreateIndirectDesc(uint32 NumElements = 1)
|
|
{
|
|
FRDGBufferDesc Desc;
|
|
Desc.UnderlyingType = EUnderlyingType::VertexBuffer;
|
|
Desc.Usage = (EBufferUsageFlags)(BUF_Static | BUF_DrawIndirect | BUF_UnorderedAccess | BUF_ShaderResource);
|
|
Desc.BytesPerElement = 4;
|
|
Desc.NumElements = NumElements;
|
|
return Desc;
|
|
}
|
|
|
|
static FRDGBufferDesc CreateStructuredDesc(uint32 BytesPerElement, uint32 NumElements)
|
|
{
|
|
FRDGBufferDesc Desc;
|
|
Desc.UnderlyingType = EUnderlyingType::StructuredBuffer;
|
|
Desc.Usage = (EBufferUsageFlags)(BUF_Static | BUF_UnorderedAccess | BUF_ShaderResource);
|
|
Desc.BytesPerElement = BytesPerElement;
|
|
Desc.NumElements = NumElements;
|
|
return Desc;
|
|
}
|
|
|
|
static FRDGBufferDesc CreateBufferDesc(uint32 BytesPerElement, uint32 NumElements)
|
|
{
|
|
FRDGBufferDesc Desc;
|
|
Desc.UnderlyingType = EUnderlyingType::VertexBuffer;
|
|
Desc.Usage = (EBufferUsageFlags)(BUF_Static | BUF_UnorderedAccess | BUF_ShaderResource);
|
|
Desc.BytesPerElement = BytesPerElement;
|
|
Desc.NumElements = NumElements;
|
|
return Desc;
|
|
}
|
|
|
|
static FRDGBufferDesc CreateByteAddressDesc(uint32 NumBytes)
|
|
{
|
|
check(NumBytes % 4 == 0);
|
|
FRDGBufferDesc Desc;
|
|
Desc.UnderlyingType = EUnderlyingType::StructuredBuffer;
|
|
Desc.Usage = (EBufferUsageFlags)(BUF_UnorderedAccess | BUF_ShaderResource | BUF_ByteAddressBuffer);
|
|
Desc.BytesPerElement = 4;
|
|
Desc.NumElements = NumBytes / 4;
|
|
return Desc;
|
|
}
|
|
|
|
static FRDGBufferDesc CreateUploadDesc(uint32 BytesPerElement, uint32 NumElements)
|
|
{
|
|
FRDGBufferDesc Desc;
|
|
Desc.UnderlyingType = EUnderlyingType::VertexBuffer;
|
|
Desc.Usage = (EBufferUsageFlags)(BUF_Static | BUF_ShaderResource);
|
|
Desc.BytesPerElement = BytesPerElement;
|
|
Desc.NumElements = NumElements;
|
|
return Desc;
|
|
}
|
|
|
|
/** Returns the total number of bytes allocated for a such buffer. */
|
|
uint32 GetTotalNumBytes() const
|
|
{
|
|
return BytesPerElement * NumElements;
|
|
}
|
|
|
|
bool operator == (const FRDGBufferDesc& Other) const
|
|
{
|
|
return (
|
|
BytesPerElement == Other.BytesPerElement &&
|
|
NumElements == Other.NumElements &&
|
|
Usage == Other.Usage &&
|
|
UnderlyingType == Other.UnderlyingType);
|
|
}
|
|
|
|
bool operator != (const FRDGBufferDesc& Other) const
|
|
{
|
|
return !(*this == Other);
|
|
}
|
|
|
|
/** Stride in bytes for index and structured buffers. */
|
|
uint32 BytesPerElement = 1;
|
|
|
|
/** Number of elements. */
|
|
uint32 NumElements = 1;
|
|
|
|
/** Bitfields describing the uses of that buffer. */
|
|
EBufferUsageFlags Usage = BUF_None;
|
|
|
|
/** The underlying RHI type to use. */
|
|
EUnderlyingType UnderlyingType = EUnderlyingType::VertexBuffer;
|
|
};
|
|
|
|
struct FRDGBufferSRVDesc
|
|
{
|
|
FRDGBufferSRVDesc() = default;
|
|
|
|
FRDGBufferSRVDesc(FRDGBufferRef InBuffer);
|
|
|
|
FRDGBufferSRVDesc(FRDGBufferRef InBuffer, EPixelFormat InFormat)
|
|
: Buffer(InBuffer)
|
|
, Format(InFormat)
|
|
{
|
|
BytesPerElement = GPixelFormats[Format].BlockBytes;
|
|
}
|
|
|
|
FRDGBufferRef Buffer = nullptr;
|
|
|
|
/** Number of bytes per element (used for vertex buffer). */
|
|
uint32 BytesPerElement = 1;
|
|
|
|
/** Encoding format for the element (used for vertex buffer). */
|
|
EPixelFormat Format = PF_Unknown;
|
|
};
|
|
|
|
struct FRDGBufferUAVDesc
|
|
{
|
|
FRDGBufferUAVDesc() = default;
|
|
|
|
FRDGBufferUAVDesc(FRDGBufferRef InBuffer);
|
|
|
|
FRDGBufferUAVDesc(FRDGBufferRef InBuffer, EPixelFormat InFormat)
|
|
: Buffer(InBuffer)
|
|
, Format(InFormat)
|
|
{}
|
|
|
|
FRDGBufferRef Buffer = nullptr;
|
|
|
|
/** Number of bytes per element (used for vertex buffer). */
|
|
EPixelFormat Format = PF_Unknown;
|
|
|
|
/** Whether the uav supports atomic counter or append buffer operations (used for structured buffers) */
|
|
bool bSupportsAtomicCounter = false;
|
|
bool bSupportsAppendBuffer = false;
|
|
};
|
|
|
|
class RENDERCORE_API FRDGPooledBuffer
|
|
{
|
|
public:
|
|
const FRDGBufferDesc Desc;
|
|
|
|
/** Finds a UAV matching the descriptor in the cache or creates a new one and updates the cache. */
|
|
FRHIUnorderedAccessView* GetOrCreateUAV(FRDGBufferUAVDesc UAVDesc);
|
|
|
|
/** Finds a SRV matching the descriptor in the cache or creates a new one and updates the cache. */
|
|
FRHIShaderResourceView* GetOrCreateSRV(FRDGBufferSRVDesc SRVDesc);
|
|
|
|
/** Returns the RHI buffer. */
|
|
FRHIBuffer* GetRHI() const
|
|
{
|
|
return Buffer;
|
|
}
|
|
|
|
UE_DEPRECATED(5.0, "Buffers types have been consolidated; use GetRHI() instead.")
|
|
FRHIBuffer* GetVertexBufferRHI() const
|
|
{
|
|
return Buffer;
|
|
}
|
|
|
|
UE_DEPRECATED(5.0, "Buffers types have been consolidated; use GetRHI() instead.")
|
|
FRHIBuffer* GetStructuredBufferRHI() const
|
|
{
|
|
return Buffer;
|
|
}
|
|
|
|
uint32 GetRefCount() const
|
|
{
|
|
return RefCount;
|
|
}
|
|
|
|
uint32 AddRef() const
|
|
{
|
|
return ++RefCount;
|
|
}
|
|
|
|
uint32 Release() const
|
|
{
|
|
const uint32 LocalRefCount = --RefCount;
|
|
if (LocalRefCount == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
return LocalRefCount;
|
|
}
|
|
|
|
template<typename KeyType, typename ValueType>
|
|
struct TSRVFuncs : BaseKeyFuncs<TPair<KeyType, ValueType>, KeyType, /* bInAllowDuplicateKeys = */ false>
|
|
{
|
|
typedef typename TTypeTraits<KeyType>::ConstPointerType KeyInitType;
|
|
typedef const TPairInitializer<typename TTypeTraits<KeyType>::ConstInitType, typename TTypeTraits<ValueType>::ConstInitType>& ElementInitType;
|
|
|
|
static FORCEINLINE KeyInitType GetSetKey(ElementInitType Element)
|
|
{
|
|
return Element.Key;
|
|
}
|
|
static FORCEINLINE bool Matches(KeyInitType A, KeyInitType B)
|
|
{
|
|
return A.BytesPerElement == B.BytesPerElement && A.Format == B.Format;
|
|
}
|
|
static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
|
|
{
|
|
return HashCombine(uint32(Key.BytesPerElement), uint32(Key.Format));
|
|
}
|
|
};
|
|
|
|
template<typename KeyType, typename ValueType>
|
|
struct TUAVFuncs : BaseKeyFuncs<TPair<KeyType, ValueType>, KeyType, /* bInAllowDuplicateKeys = */ false>
|
|
{
|
|
typedef typename TTypeTraits<KeyType>::ConstPointerType KeyInitType;
|
|
typedef const TPairInitializer<typename TTypeTraits<KeyType>::ConstInitType, typename TTypeTraits<ValueType>::ConstInitType>& ElementInitType;
|
|
|
|
static FORCEINLINE KeyInitType GetSetKey(ElementInitType Element)
|
|
{
|
|
return Element.Key;
|
|
}
|
|
static FORCEINLINE bool Matches(KeyInitType A, KeyInitType B)
|
|
{
|
|
return A.Format == B.Format && A.bSupportsAtomicCounter == B.bSupportsAtomicCounter && A.bSupportsAppendBuffer == B.bSupportsAppendBuffer;
|
|
}
|
|
static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
|
|
{
|
|
return (uint32(Key.bSupportsAtomicCounter) << 8) | (uint32(Key.bSupportsAppendBuffer) << 9) | uint32(Key.Format);
|
|
}
|
|
};
|
|
|
|
private:
|
|
FRDGPooledBuffer(const FRDGBufferDesc& InDesc)
|
|
: Desc(InDesc)
|
|
{}
|
|
|
|
TRefCountPtr<FRHIBuffer> Buffer;
|
|
TMap<FRDGBufferUAVDesc, FUnorderedAccessViewRHIRef, FDefaultSetAllocator, TUAVFuncs<FRDGBufferUAVDesc, FUnorderedAccessViewRHIRef>> UAVs;
|
|
TMap<FRDGBufferSRVDesc, FShaderResourceViewRHIRef, FDefaultSetAllocator, TSRVFuncs<FRDGBufferSRVDesc, FShaderResourceViewRHIRef>> SRVs;
|
|
|
|
void Reset()
|
|
{
|
|
Owner = nullptr;
|
|
State = {};
|
|
}
|
|
|
|
void Finalize()
|
|
{
|
|
Owner = nullptr;
|
|
State.Finalize();
|
|
}
|
|
|
|
const TCHAR* Name = nullptr;
|
|
|
|
FRDGBufferRef Owner = nullptr;
|
|
FRDGSubresourceState State;
|
|
|
|
mutable uint32 RefCount = 0;
|
|
uint32 LastUsedFrame = 0;
|
|
|
|
friend FRenderGraphResourcePool;
|
|
friend FRDGBuilder;
|
|
friend FRDGBuffer;
|
|
};
|
|
|
|
/** A render graph tracked buffer. */
|
|
class RENDERCORE_API FRDGBuffer final
|
|
: public FRDGParentResource
|
|
{
|
|
public:
|
|
const FRDGBufferDesc Desc;
|
|
const ERDGBufferFlags Flags;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//! The following methods may only be called during pass execution.
|
|
|
|
/** Returns the underlying RHI buffer resource */
|
|
FRHIBuffer* GetRHI() const
|
|
{
|
|
return static_cast<FRHIBuffer*>(FRDGParentResource::GetRHI());
|
|
}
|
|
|
|
/** Returns the buffer to use for indirect RHI calls. */
|
|
FORCEINLINE FRHIBuffer* GetIndirectRHICallBuffer() const
|
|
{
|
|
checkf(Desc.Usage & BUF_DrawIndirect, TEXT("Buffer %s was not flagged for indirect draw usage."), Name);
|
|
return GetRHI();
|
|
}
|
|
|
|
/** Returns the buffer to use for RHI calls, eg RHILockVertexBuffer. */
|
|
UE_DEPRECATED(5.0, "Buffers types have been consolidated; use GetRHI() instead.")
|
|
FORCEINLINE FRHIBuffer* GetRHIVertexBuffer() const
|
|
{
|
|
return GetRHI();
|
|
}
|
|
|
|
/** Returns the buffer to use for structured buffer calls. */
|
|
UE_DEPRECATED(5.0, "Buffers types have been consolidated; use GetRHI() instead.")
|
|
FORCEINLINE FRHIBuffer* GetRHIStructuredBuffer() const
|
|
{
|
|
return GetRHI();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
FRDGBufferHandle GetHandle() const
|
|
{
|
|
return Handle;
|
|
}
|
|
|
|
private:
|
|
FRDGBuffer(const TCHAR* InName, const FRDGBufferDesc& InDesc, ERDGBufferFlags InFlags)
|
|
: FRDGParentResource(InName, ERDGParentResourceType::Buffer)
|
|
, Desc(InDesc)
|
|
, Flags(InFlags)
|
|
{}
|
|
|
|
/** Assigns the pooled buffer to this buffer; returns the previous buffer to own the allocation. */
|
|
void SetRHI(FRDGPooledBuffer* InPooledBuffer, FRDGBufferRef& OutPreviousOwner);
|
|
|
|
/** Finalizes the buffer for execution; no other transitions are allowed after calling this. */
|
|
void Finalize();
|
|
|
|
/** Returns the current buffer state. Only valid to call after SetRHI. */
|
|
FRDGSubresourceState& GetState() const
|
|
{
|
|
check(State);
|
|
return *State;
|
|
}
|
|
|
|
/** Registered handle set by the builder. */
|
|
FRDGBufferHandle Handle;
|
|
|
|
/** Tracks the last pass that produced this resource as the graph is built. */
|
|
FRDGProducerStatesByPipeline LastProducer;
|
|
|
|
/** The next buffer to own the PooledBuffer allocation during execution. */
|
|
FRDGBufferHandle NextOwner;
|
|
|
|
/** Assigned pooled buffer pointer. Never reset once assigned. */
|
|
FRDGPooledBuffer* PooledBuffer = nullptr;
|
|
|
|
/** Cached state pointer from the pooled buffer. */
|
|
FRDGSubresourceState* State = nullptr;
|
|
|
|
/** Valid strictly when holding a strong reference; use PooledBuffer instead. */
|
|
TRefCountPtr<FRDGPooledBuffer> Allocation;
|
|
|
|
/** Tracks the merged subresource state as the graph is built. */
|
|
FRDGSubresourceState* MergeState = nullptr;
|
|
|
|
#if RDG_ENABLE_DEBUG
|
|
struct FRDGBufferDebugData* BufferDebugData = nullptr;
|
|
FRDGBufferDebugData& GetBufferDebugData() const;
|
|
#endif
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGBarrierValidation;
|
|
friend FRDGUserValidation;
|
|
friend FRDGBufferRegistry;
|
|
friend FRDGAllocator;
|
|
friend FRDGTrace;
|
|
};
|
|
|
|
/** Render graph tracked buffer SRV. */
|
|
class FRDGBufferSRV final
|
|
: public FRDGShaderResourceView
|
|
{
|
|
public:
|
|
/** Descriptor of the graph tracked SRV. */
|
|
const FRDGBufferSRVDesc Desc;
|
|
|
|
FRDGBufferRef GetParent() const override
|
|
{
|
|
return Desc.Buffer;
|
|
}
|
|
|
|
private:
|
|
FRDGBufferSRV(const TCHAR* InName, const FRDGBufferSRVDesc& InDesc)
|
|
: FRDGShaderResourceView(InName, ERDGViewType::BufferSRV)
|
|
, Desc(InDesc)
|
|
{}
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGViewRegistry;
|
|
friend FRDGAllocator;
|
|
};
|
|
|
|
/** Render graph tracked buffer UAV. */
|
|
class FRDGBufferUAV final
|
|
: public FRDGUnorderedAccessView
|
|
{
|
|
public:
|
|
/** Descriptor of the graph tracked UAV. */
|
|
const FRDGBufferUAVDesc Desc;
|
|
|
|
FRDGBufferRef GetParent() const override
|
|
{
|
|
return Desc.Buffer;
|
|
}
|
|
|
|
private:
|
|
FRDGBufferUAV(const TCHAR* InName, const FRDGBufferUAVDesc& InDesc, ERDGUnorderedAccessViewFlags InFlags)
|
|
: FRDGUnorderedAccessView(InName, ERDGViewType::BufferUAV, InFlags)
|
|
, Desc(InDesc)
|
|
{}
|
|
|
|
friend FRDGBuilder;
|
|
friend FRDGViewRegistry;
|
|
friend FRDGAllocator;
|
|
};
|
|
|
|
#include "RenderGraphResources.inl" |