2031 lines
74 KiB
C++
2031 lines
74 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
ShaderParameterMacros.h: Macros to builds shader parameter structures and
|
|
their metadata.
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
#include "ShaderParameterStructDeclaration.h"
|
|
#include "ShaderParameterMetadata.h"
|
|
#include "RenderGraphAllocator.h"
|
|
#include "Algo/Reverse.h"
|
|
#include "Templates/IsArrayOrRefOfTypeByPredicate.h"
|
|
#include "Traits/IsCharEncodingCompatibleWith.h"
|
|
#include "Misc/AssertionMacros.h"
|
|
#include "RHICommandList.h"
|
|
#include "RenderGraphTextureSubresource.h"
|
|
|
|
PRAGMA_DISABLE_BUFFER_OVERRUN_WARNING
|
|
|
|
class FRDGTexture;
|
|
class FRDGTextureSRV;
|
|
class FRDGTextureUAV;
|
|
class FRDGBuffer;
|
|
class FRDGBufferSRV;
|
|
class FRDGBufferUAV;
|
|
class FRDGUniformBuffer;
|
|
enum class EShaderBindingLayoutFlags : uint8;
|
|
class FShaderBindingLayoutContainer;
|
|
template <typename TUniformStruct> class TRDGUniformBuffer;
|
|
|
|
/** Alignements tools because alignas() does not work on type in clang. */
|
|
template<typename T, int32 Alignment>
|
|
class TAlignedTypedef;
|
|
|
|
#define IMPLEMENT_ALIGNED_TYPE(Alignment) \
|
|
template<typename T> \
|
|
class TAlignedTypedef<T,Alignment> \
|
|
{ \
|
|
public: \
|
|
typedef MS_ALIGN(Alignment) T Type GCC_ALIGN(Alignment); \
|
|
};
|
|
|
|
IMPLEMENT_ALIGNED_TYPE(1);
|
|
IMPLEMENT_ALIGNED_TYPE(2);
|
|
IMPLEMENT_ALIGNED_TYPE(4);
|
|
IMPLEMENT_ALIGNED_TYPE(8);
|
|
IMPLEMENT_ALIGNED_TYPE(16);
|
|
#undef IMPLEMENT_ALIGNED_TYPE
|
|
|
|
|
|
#if PLATFORM_64BITS
|
|
|
|
/** Fixed 8bytes sized and aligned pointer for shader parameters. */
|
|
template<typename PtrType>
|
|
using TAlignedShaderParameterPtr = typename TAlignedTypedef<PtrType, SHADER_PARAMETER_POINTER_ALIGNMENT>::Type;
|
|
|
|
static_assert(sizeof(void*) == 8, "Wrong PLATFORM_64BITS settings.");
|
|
|
|
#else //!PLATFORM_64BITS
|
|
|
|
/** Fixed 8bytes sized pointer for shader parameters. */
|
|
template<typename PtrType>
|
|
class alignas(SHADER_PARAMETER_POINTER_ALIGNMENT) TAlignedShaderParameterPtr
|
|
{
|
|
public:
|
|
TAlignedShaderParameterPtr()
|
|
{ }
|
|
|
|
TAlignedShaderParameterPtr(const PtrType& Other)
|
|
: Ref(Other)
|
|
{ }
|
|
|
|
TAlignedShaderParameterPtr(const TAlignedShaderParameterPtr<PtrType>& Other)
|
|
: Ref(Other.Ref)
|
|
{ }
|
|
|
|
FORCEINLINE void operator=(const PtrType& Other)
|
|
{
|
|
Ref = Other;
|
|
}
|
|
|
|
FORCEINLINE operator PtrType&()
|
|
{
|
|
return Ref;
|
|
}
|
|
|
|
FORCEINLINE operator const PtrType&() const
|
|
{
|
|
return Ref;
|
|
}
|
|
|
|
FORCEINLINE const PtrType& operator->() const
|
|
{
|
|
return Ref;
|
|
}
|
|
|
|
private:
|
|
PtrType Ref;
|
|
#if !PLATFORM_64BITS
|
|
uint32 _Padding;
|
|
static_assert(sizeof(void*) == 4, "Wrong PLATFORM_64BITS settings.");
|
|
#endif
|
|
|
|
static_assert(sizeof(PtrType) == sizeof(void*), "T should be a pointer.");
|
|
};
|
|
|
|
#endif // !PLATFORM_64BITS
|
|
|
|
/** Retrieve the metadata of a UB type */
|
|
template<class UniformBufferStructType, typename = void>
|
|
struct TUniformBufferMetadataHelper
|
|
{
|
|
static const FShaderParametersMetadata* GetStructMetadata()
|
|
{
|
|
// This uses ADL rather than templates, because template specializations can't be defined in a different namespace
|
|
return GetForwardDeclaredShaderParametersStructMetadata((UniformBufferStructType*)nullptr);
|
|
}
|
|
};
|
|
|
|
template<class UniformBufferStructType>
|
|
struct TUniformBufferMetadataHelper<UniformBufferStructType, typename std::enable_if<!std::is_same<typename UniformBufferStructType::FTypeInfo, void>::value>::type>
|
|
{
|
|
static const FShaderParametersMetadata* GetStructMetadata()
|
|
{
|
|
return UniformBufferStructType::FTypeInfo::GetStructMetadata();
|
|
}
|
|
};
|
|
|
|
|
|
/** A reference to a uniform buffer RHI resource with a specific structure. */
|
|
template<typename TBufferStruct>
|
|
class TUniformBufferRef : public FUniformBufferRHIRef
|
|
{
|
|
static_assert(!TIsUECoreVariant<TBufferStruct, double>::Value, "UniformBufferRHIRef cannot be double core variants! Switch to float variant.");
|
|
|
|
public:
|
|
/** Initializes the reference to null. */
|
|
TUniformBufferRef() = default;
|
|
|
|
/** Construct an instance from an existing RHI uniform buffer pointer. Validates at runtime that the type of the uniform buffer matches the template struct type. */
|
|
explicit TUniformBufferRef(FRHIUniformBuffer* InRHIRef)
|
|
: FUniformBufferRHIRef(InRHIRef)
|
|
{
|
|
checkf(!InRHIRef || TUniformBufferMetadataHelper<TBufferStruct>::GetStructMetadata()->GetLayoutPtr() == InRHIRef->GetLayoutPtr(),
|
|
TEXT("Attempted to create a uniform buffer of type '%s' from uniform buffer pointer of type '%s'"),
|
|
*TUniformBufferMetadataHelper<TBufferStruct>::GetStructMetadata()->GetLayout().Name,
|
|
*InRHIRef->GetLayout().Name);
|
|
}
|
|
|
|
/** Creates a uniform buffer with the given value, and returns a structured reference to it. */
|
|
static TUniformBufferRef<TBufferStruct> CreateUniformBufferImmediate(const TBufferStruct& Value, EUniformBufferUsage Usage, EUniformBufferValidation Validation = EUniformBufferValidation::ValidateResources)
|
|
{
|
|
return TUniformBufferRef<TBufferStruct>(RHICreateUniformBuffer(&Value, TUniformBufferMetadataHelper<TBufferStruct>::GetStructMetadata()->GetLayoutPtr(), Usage, Validation));
|
|
}
|
|
/** Creates a uniform buffer with the given value, and returns a structured reference to it. */
|
|
static TUniformBufferRef<TBufferStruct> CreateEmptyUniformBufferImmediate(EUniformBufferUsage Usage)
|
|
{
|
|
return TUniformBufferRef<TBufferStruct>(RHICreateUniformBuffer(nullptr, TUniformBufferMetadataHelper<TBufferStruct>::GetStructMetadata()->GetLayoutPtr(), Usage, EUniformBufferValidation::ValidateResources));
|
|
}
|
|
|
|
UE_DEPRECATED(5.3, "UpdateUniformBufferImmediate requires a command list.")
|
|
void UpdateUniformBufferImmediate(const TBufferStruct& Value)
|
|
{
|
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
|
RHIUpdateUniformBuffer(GetReference(), &Value);
|
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
|
}
|
|
|
|
void UpdateUniformBufferImmediate(FRHICommandListBase& RHICmdList, const TBufferStruct& Value)
|
|
{
|
|
RHICmdList.UpdateUniformBuffer(GetReference(), &Value);
|
|
}
|
|
|
|
private:
|
|
|
|
template<typename TBufferStruct2>
|
|
friend class TUniformBuffer;
|
|
|
|
friend class TRDGUniformBuffer<TBufferStruct>;
|
|
};
|
|
|
|
class alignas(SHADER_PARAMETER_STRUCT_ALIGNMENT) FUniformBufferBinding
|
|
{
|
|
public:
|
|
FUniformBufferBinding() = default;
|
|
|
|
FORCEINLINE FRHIUniformBuffer* GetUniformBuffer() const
|
|
{
|
|
return UniformBuffer;
|
|
}
|
|
|
|
FORCEINLINE EUniformBufferBindingFlags GetBindingFlags() const
|
|
{
|
|
return BindingFlags;
|
|
}
|
|
|
|
FORCEINLINE bool IsStatic() const
|
|
{
|
|
return EnumHasAnyFlags(BindingFlags, EUniformBufferBindingFlags::Static);
|
|
}
|
|
|
|
FORCEINLINE bool IsShader() const
|
|
{
|
|
return EnumHasAnyFlags(BindingFlags, EUniformBufferBindingFlags::Shader);
|
|
}
|
|
|
|
FORCEINLINE operator bool() const
|
|
{
|
|
return UniformBuffer != nullptr;
|
|
}
|
|
|
|
protected:
|
|
FORCEINLINE FUniformBufferBinding(const FUniformBufferRHIRef& InUniformBuffer, EUniformBufferBindingFlags InBindingFlags)
|
|
: UniformBuffer(InUniformBuffer)
|
|
, BindingFlags(InBindingFlags)
|
|
{}
|
|
|
|
private:
|
|
FRHIUniformBuffer* UniformBuffer = nullptr;
|
|
EUniformBufferBindingFlags BindingFlags = EUniformBufferBindingFlags::Shader;
|
|
};
|
|
|
|
template<typename TBufferStruct>
|
|
class alignas(SHADER_PARAMETER_STRUCT_ALIGNMENT) TUniformBufferBinding
|
|
: public FUniformBufferBinding
|
|
{
|
|
public:
|
|
TUniformBufferBinding() = default;
|
|
|
|
TUniformBufferBinding(const TUniformBufferRef<TBufferStruct>& InUniformBuffer)
|
|
: FUniformBufferBinding(InUniformBuffer, TUniformBufferMetadataHelper<TBufferStruct>::GetStructMetadata()->GetPreferredBindingFlag())
|
|
{}
|
|
|
|
TUniformBufferBinding(const TUniformBufferRef<TBufferStruct>& InUniformBuffer, EUniformBufferBindingFlags InBindingFlags)
|
|
: FUniformBufferBinding(InUniformBuffer, InBindingFlags)
|
|
{
|
|
#if DO_CHECK
|
|
const auto* StructMetadata = TUniformBufferMetadataHelper<TBufferStruct>::GetStructMetadata();
|
|
checkf(
|
|
EnumHasAllFlags(StructMetadata->GetBindingFlags(), GetBindingFlags()),
|
|
TEXT("Uniform buffer binding flags don't match those supported by the uniform buffer layout '%s."),
|
|
StructMetadata->GetStructTypeName());
|
|
#endif
|
|
}
|
|
|
|
FORCEINLINE TUniformBufferRef<TBufferStruct> GetUniformBufferRef() const
|
|
{
|
|
return TUniformBufferRef<TBufferStruct>(FUniformBufferBinding::GetUniformBuffer());
|
|
}
|
|
|
|
FORCEINLINE TRDGUniformBuffer<TBufferStruct>* operator->() const
|
|
{
|
|
return GetUniformBuffer();
|
|
}
|
|
};
|
|
|
|
template <typename TBufferStruct>
|
|
inline TUniformBufferBinding<TBufferStruct> GetStaticBinding(const TUniformBufferRef<TBufferStruct>& InUniformBuffer)
|
|
{
|
|
return TUniformBufferBinding<TBufferStruct>(InUniformBuffer, EUniformBufferBindingFlags::Static);
|
|
}
|
|
|
|
template <typename TBufferStruct>
|
|
inline TUniformBufferBinding<TBufferStruct> GetShaderBinding(const TUniformBufferRef<TBufferStruct>& InUniformBuffer)
|
|
{
|
|
return TUniformBufferBinding<TBufferStruct>(InUniformBuffer, EUniformBufferBindingFlags::Shader);
|
|
}
|
|
|
|
class alignas(SHADER_PARAMETER_STRUCT_ALIGNMENT) FRDGUniformBufferBinding
|
|
{
|
|
public:
|
|
FRDGUniformBufferBinding() = default;
|
|
|
|
FORCEINLINE FRDGUniformBuffer* GetUniformBuffer() const
|
|
{
|
|
return UniformBuffer;
|
|
}
|
|
|
|
FORCEINLINE EUniformBufferBindingFlags GetBindingFlags() const
|
|
{
|
|
return BindingFlags;
|
|
}
|
|
|
|
FORCEINLINE bool IsStatic() const
|
|
{
|
|
return EnumHasAnyFlags(BindingFlags, EUniformBufferBindingFlags::Static);
|
|
}
|
|
|
|
FORCEINLINE bool IsShader() const
|
|
{
|
|
return EnumHasAnyFlags(BindingFlags, EUniformBufferBindingFlags::Shader);
|
|
}
|
|
|
|
FORCEINLINE operator bool() const
|
|
{
|
|
return UniformBuffer != nullptr;
|
|
}
|
|
|
|
FORCEINLINE FRDGUniformBuffer* operator->() const
|
|
{
|
|
return UniformBuffer;
|
|
}
|
|
|
|
protected:
|
|
FRDGUniformBufferBinding(FRDGUniformBuffer* InUniformBuffer, EUniformBufferBindingFlags InBindingFlags)
|
|
: UniformBuffer(InUniformBuffer)
|
|
, BindingFlags(InBindingFlags)
|
|
{}
|
|
|
|
private:
|
|
FRDGUniformBuffer* UniformBuffer = nullptr;
|
|
EUniformBufferBindingFlags BindingFlags = EUniformBufferBindingFlags::Shader;
|
|
};
|
|
|
|
template <typename TBufferStruct>
|
|
class alignas(SHADER_PARAMETER_STRUCT_ALIGNMENT) TRDGUniformBufferBinding
|
|
: public FRDGUniformBufferBinding
|
|
{
|
|
public:
|
|
TRDGUniformBufferBinding() = default;
|
|
|
|
TRDGUniformBufferBinding(TRDGUniformBuffer<TBufferStruct>* InUniformBuffer)
|
|
: FRDGUniformBufferBinding(InUniformBuffer, TUniformBufferMetadataHelper<TBufferStruct>::GetStructMetadata()->GetPreferredBindingFlag())
|
|
{}
|
|
|
|
TRDGUniformBufferBinding(TRDGUniformBuffer<TBufferStruct>* InUniformBuffer, EUniformBufferBindingFlags InBindingFlags)
|
|
: FRDGUniformBufferBinding(InUniformBuffer, InBindingFlags)
|
|
{
|
|
#if DO_CHECK
|
|
const auto* StructMetadata = TUniformBufferMetadataHelper<TBufferStruct>::GetStructMetadata();
|
|
checkf(
|
|
EnumHasAllFlags(StructMetadata->GetBindingFlags(), GetBindingFlags()),
|
|
TEXT("RDG uniform buffer binding flags don't match those supported by the uniform buffer layout '%s."),
|
|
StructMetadata->GetStructTypeName());
|
|
#endif
|
|
}
|
|
|
|
FORCEINLINE TRDGUniformBuffer<TBufferStruct>* GetUniformBuffer() const
|
|
{
|
|
return static_cast<TRDGUniformBuffer<TBufferStruct>*>(FRDGUniformBufferBinding::GetUniformBuffer());
|
|
}
|
|
|
|
FORCEINLINE TRDGUniformBuffer<TBufferStruct>* operator->() const
|
|
{
|
|
return GetUniformBuffer();
|
|
}
|
|
};
|
|
|
|
/** Constructs a uniform buffer binding that will utilize the shader binding model. */
|
|
template <typename TBufferStruct>
|
|
inline TRDGUniformBufferBinding<TBufferStruct> GetShaderBinding(TRDGUniformBuffer<TBufferStruct>* InUniformBuffer)
|
|
{
|
|
return TRDGUniformBufferBinding<TBufferStruct>(InUniformBuffer, EUniformBufferBindingFlags::Shader);
|
|
}
|
|
|
|
/** Constructs a uniform buffer binding that will utilize the static binding model. */
|
|
template <typename TBufferStruct>
|
|
inline TRDGUniformBufferBinding<TBufferStruct> GetStaticBinding(TRDGUniformBuffer<TBufferStruct>* InUniformBuffer)
|
|
{
|
|
return TRDGUniformBufferBinding<TBufferStruct>(InUniformBuffer, EUniformBufferBindingFlags::Static);
|
|
}
|
|
|
|
class alignas(SHADER_PARAMETER_POINTER_ALIGNMENT) FRDGBufferAccess
|
|
{
|
|
public:
|
|
FRDGBufferAccess() = default;
|
|
FRDGBufferAccess(FRDGBuffer* InBuffer, ERHIAccess InAccess)
|
|
: Buffer(InBuffer)
|
|
, Access(InAccess)
|
|
{
|
|
check(IsValidAccess(InAccess));
|
|
}
|
|
|
|
FORCEINLINE FRDGBuffer* GetBuffer() const { return Buffer; }
|
|
FORCEINLINE ERHIAccess GetAccess() const { return Access; }
|
|
|
|
FORCEINLINE operator bool() const
|
|
{
|
|
return Buffer != nullptr;
|
|
}
|
|
|
|
FORCEINLINE FRDGBuffer* operator->() const
|
|
{
|
|
check(Buffer);
|
|
return Buffer;
|
|
}
|
|
|
|
FORCEINLINE operator FRDGBuffer*() const
|
|
{
|
|
return Buffer;
|
|
}
|
|
|
|
FORCEINLINE bool operator==(const FRDGBufferAccess& RHS) const
|
|
{
|
|
return Buffer == RHS.Buffer && Access == RHS.Access;
|
|
}
|
|
|
|
FORCEINLINE bool operator!=(const FRDGBufferAccess& RHS) const
|
|
{
|
|
return Buffer != RHS.Buffer || Access != RHS.Access;
|
|
}
|
|
|
|
private:
|
|
TAlignedShaderParameterPtr<FRDGBuffer*> Buffer = nullptr;
|
|
ERHIAccess Access = ERHIAccess::Unknown;
|
|
};
|
|
|
|
template <ERHIAccess InAccess>
|
|
class alignas(SHADER_PARAMETER_POINTER_ALIGNMENT) TRDGBufferAccess
|
|
: public FRDGBufferAccess
|
|
{
|
|
public:
|
|
static_assert(IsValidAccess(InAccess), "Buffer access is invalid.");
|
|
|
|
TRDGBufferAccess()
|
|
: FRDGBufferAccess(nullptr, InAccess)
|
|
{
|
|
check(IsValidAccess(InAccess));
|
|
}
|
|
|
|
TRDGBufferAccess(FRDGBuffer* InBuffer)
|
|
: FRDGBufferAccess(InBuffer, InAccess)
|
|
{}
|
|
};
|
|
|
|
class alignas(SHADER_PARAMETER_POINTER_ALIGNMENT) FRDGTextureAccess
|
|
{
|
|
public:
|
|
FRDGTextureAccess() = default;
|
|
|
|
FRDGTextureAccess(FRDGTexture* InTexture, FRDGTextureSubresourceRange InSubresourceRange, ERHIAccess InAccess)
|
|
: Texture(InTexture)
|
|
, SubresourceRange(InSubresourceRange)
|
|
, Access(InAccess)
|
|
{}
|
|
|
|
RENDERCORE_API FRDGTextureAccess(FRDGTexture* InTexture, ERHIAccess InAccess);
|
|
RENDERCORE_API FRDGTextureAccess(FRDGTextureSRV* InTextureSRV, ERHIAccess InAccess);
|
|
RENDERCORE_API FRDGTextureAccess(FRDGTextureUAV* InTextureUAV, ERHIAccess InAccess);
|
|
|
|
FORCEINLINE FRDGTexture* GetTexture() const { return Texture; }
|
|
FORCEINLINE FRDGTextureSubresourceRange GetSubresourceRange() const { return SubresourceRange; }
|
|
FORCEINLINE ERHIAccess GetAccess() const { return Access; }
|
|
|
|
FORCEINLINE operator bool() const
|
|
{
|
|
return Texture != nullptr;
|
|
}
|
|
|
|
FORCEINLINE FRDGTexture* operator->() const
|
|
{
|
|
check(Texture);
|
|
return Texture;
|
|
}
|
|
|
|
FORCEINLINE operator FRDGTexture*() const
|
|
{
|
|
return Texture;
|
|
}
|
|
|
|
FORCEINLINE bool operator==(const FRDGTextureAccess& RHS) const
|
|
{
|
|
return Texture == RHS.Texture && Access == RHS.Access;
|
|
}
|
|
|
|
FORCEINLINE bool operator!=(const FRDGTextureAccess& RHS) const
|
|
{
|
|
return Texture != RHS.Texture || Access != RHS.Access;
|
|
}
|
|
|
|
private:
|
|
TAlignedShaderParameterPtr<FRDGTexture*> Texture = nullptr;
|
|
FRDGTextureSubresourceRange SubresourceRange;
|
|
ERHIAccess Access = ERHIAccess::Unknown;
|
|
};
|
|
|
|
template <ERHIAccess InAccess>
|
|
class alignas(SHADER_PARAMETER_POINTER_ALIGNMENT) TRDGTextureAccess
|
|
: public FRDGTextureAccess
|
|
{
|
|
public:
|
|
static_assert(IsValidAccess(InAccess), "Texture access is invalid.");
|
|
|
|
TRDGTextureAccess() = default;
|
|
|
|
TRDGTextureAccess(FRDGTexture* InTexture, FRDGTextureSubresourceRange InSubresourceRange)
|
|
: FRDGTextureAccess(InTexture, InSubresourceRange, InAccess)
|
|
{}
|
|
|
|
TRDGTextureAccess(FRDGTexture* InTexture)
|
|
: FRDGTextureAccess(InTexture, InAccess)
|
|
{}
|
|
|
|
TRDGTextureAccess(FRDGTextureSRV* InTextureSRV)
|
|
: FRDGTextureAccess(InTextureSRV, InAccess)
|
|
{}
|
|
|
|
TRDGTextureAccess(FRDGTextureUAV* InTextureUAV)
|
|
: FRDGTextureAccess(InTextureUAV, InAccess)
|
|
{}
|
|
};
|
|
|
|
template <typename ResourceAccessType>
|
|
class alignas(SHADER_PARAMETER_POINTER_ALIGNMENT) TRDGResourceAccessArray
|
|
: public TArray<ResourceAccessType, FRDGArrayAllocator>
|
|
{
|
|
using Super = TArray<ResourceAccessType, FRDGArrayAllocator>;
|
|
public:
|
|
using Super::Super;
|
|
|
|
private:
|
|
#if !PLATFORM_64BITS
|
|
uint32 _Padding;
|
|
#endif
|
|
};
|
|
|
|
using FRDGBufferAccessArray = TRDGResourceAccessArray<FRDGBufferAccess>;
|
|
using FRDGTextureAccessArray = TRDGResourceAccessArray<FRDGTextureAccess>;
|
|
|
|
/** Render graph information about how to bind a render target. */
|
|
struct FRenderTargetBinding
|
|
{
|
|
FRenderTargetBinding() = default;
|
|
|
|
FRenderTargetBinding(FRDGTexture* InTexture, ERenderTargetLoadAction InLoadAction, uint8 InMipIndex = 0, int16 InArraySlice = -1)
|
|
: Texture(InTexture)
|
|
, LoadAction(InLoadAction)
|
|
, MipIndex(InMipIndex)
|
|
, ArraySlice(InArraySlice)
|
|
{
|
|
check(Validate());
|
|
}
|
|
|
|
FRenderTargetBinding(FRDGTexture* InTexture, FRDGTexture* InResolveTexture, ERenderTargetLoadAction InLoadAction, uint8 InMipIndex = 0, int16 InArraySlice = -1)
|
|
: Texture(InTexture)
|
|
, ResolveTexture(InResolveTexture)
|
|
, LoadAction(InLoadAction)
|
|
, MipIndex(InMipIndex)
|
|
, ArraySlice(InArraySlice)
|
|
{
|
|
check(Validate());
|
|
}
|
|
|
|
FRDGTexture* GetTexture() const
|
|
{
|
|
return Texture;
|
|
}
|
|
|
|
FRDGTexture* GetResolveTexture() const
|
|
{
|
|
return ResolveTexture;
|
|
}
|
|
|
|
ERenderTargetLoadAction GetLoadAction() const
|
|
{
|
|
return LoadAction;
|
|
}
|
|
|
|
uint8 GetMipIndex() const
|
|
{
|
|
return MipIndex;
|
|
}
|
|
|
|
int16 GetArraySlice() const
|
|
{
|
|
return ArraySlice;
|
|
}
|
|
|
|
/** Whether we can merge a render pass using Other into a render pass using this render target binding. */
|
|
inline bool CanMergeBefore(const FRenderTargetBinding& Other) const
|
|
{
|
|
return
|
|
Texture == Other.Texture &&
|
|
ResolveTexture == Other.ResolveTexture &&
|
|
Other.LoadAction != ERenderTargetLoadAction::EClear &&
|
|
MipIndex == Other.MipIndex &&
|
|
ArraySlice == Other.ArraySlice;
|
|
}
|
|
|
|
void SetTexture(FRDGTexture* InTexture)
|
|
{
|
|
Texture = InTexture;
|
|
check(Validate());
|
|
}
|
|
|
|
void SetResolveTexture(FRDGTexture* InTexture)
|
|
{
|
|
ResolveTexture = InTexture;
|
|
check(Validate());
|
|
}
|
|
|
|
void SetLoadAction(ERenderTargetLoadAction InLoadAction)
|
|
{
|
|
LoadAction = InLoadAction;
|
|
check(Validate());
|
|
}
|
|
|
|
void SetMipIndex(uint8 InMipIndex)
|
|
{
|
|
MipIndex = InMipIndex;
|
|
check(Validate());
|
|
}
|
|
|
|
void SetArraySlice(int16 InArraySlice)
|
|
{
|
|
ArraySlice = InArraySlice;
|
|
check(Validate());
|
|
}
|
|
|
|
UE_DEPRECATED(5.1, "GetMipIndex has been renamed to SetMipIndex.")
|
|
void GetMipIndex(uint8 InMipIndex) { SetMipIndex(InMipIndex); }
|
|
|
|
private:
|
|
/** Intentionally kept private to force setting the load action in the constructor. */
|
|
TAlignedShaderParameterPtr<FRDGTexture*> Texture = nullptr;
|
|
TAlignedShaderParameterPtr<FRDGTexture*> ResolveTexture = nullptr;
|
|
ERenderTargetLoadAction LoadAction = ERenderTargetLoadAction::ENoAction;
|
|
uint8 MipIndex = 0;
|
|
int16 ArraySlice = -1;
|
|
|
|
RENDERCORE_API bool Validate() const;
|
|
};
|
|
|
|
|
|
/** Render graph information about how to bind a depth-stencil render target. */
|
|
struct FDepthStencilBinding
|
|
{
|
|
FDepthStencilBinding() = default;
|
|
|
|
/**
|
|
* Creates a render target binding informations for a depth/stencil texture.
|
|
*
|
|
* Notes: Load and store action are on explicit without default values, to force the user to not forget one of these.
|
|
*/
|
|
FORCEINLINE FDepthStencilBinding(
|
|
FRDGTexture* InTexture,
|
|
ERenderTargetLoadAction InDepthLoadAction,
|
|
ERenderTargetLoadAction InStencilLoadAction,
|
|
FExclusiveDepthStencil InDepthStencilAccess)
|
|
: Texture(InTexture)
|
|
, ResolveTexture(nullptr)
|
|
, DepthLoadAction(InDepthLoadAction)
|
|
, StencilLoadAction(InStencilLoadAction)
|
|
, DepthStencilAccess(InDepthStencilAccess)
|
|
{
|
|
check(Validate());
|
|
}
|
|
|
|
FORCEINLINE FDepthStencilBinding(
|
|
FRDGTexture* InTexture,
|
|
FRDGTexture* InResolveTexture,
|
|
ERenderTargetLoadAction InDepthLoadAction,
|
|
ERenderTargetLoadAction InStencilLoadAction,
|
|
FExclusiveDepthStencil InDepthStencilAccess)
|
|
: Texture(InTexture)
|
|
, ResolveTexture(InResolveTexture)
|
|
, DepthLoadAction(InDepthLoadAction)
|
|
, StencilLoadAction(InStencilLoadAction)
|
|
, DepthStencilAccess(InDepthStencilAccess)
|
|
{
|
|
check(Validate());
|
|
}
|
|
|
|
FORCEINLINE FDepthStencilBinding(
|
|
FRDGTexture* InTexture,
|
|
ERenderTargetLoadAction InDepthLoadAction,
|
|
FExclusiveDepthStencil InDepthStencilAccess)
|
|
: Texture(InTexture)
|
|
, ResolveTexture(nullptr)
|
|
, DepthLoadAction(InDepthLoadAction)
|
|
, DepthStencilAccess(InDepthStencilAccess)
|
|
{
|
|
check(Validate());
|
|
}
|
|
|
|
FORCEINLINE FDepthStencilBinding(
|
|
FRDGTexture* InTexture,
|
|
FRDGTexture* InResolveTexture,
|
|
ERenderTargetLoadAction InDepthLoadAction,
|
|
FExclusiveDepthStencil InDepthStencilAccess)
|
|
: Texture(InTexture)
|
|
, ResolveTexture(InResolveTexture)
|
|
, DepthLoadAction(InDepthLoadAction)
|
|
, DepthStencilAccess(InDepthStencilAccess)
|
|
{
|
|
check(Validate());
|
|
}
|
|
|
|
FORCEINLINE FRDGTexture* GetTexture() const
|
|
{
|
|
return Texture;
|
|
}
|
|
FORCEINLINE FRDGTexture* GetResolveTexture() const
|
|
{
|
|
return ResolveTexture;
|
|
}
|
|
FORCEINLINE ERenderTargetLoadAction GetDepthLoadAction() const
|
|
{
|
|
return DepthLoadAction;
|
|
}
|
|
FORCEINLINE ERenderTargetLoadAction GetStencilLoadAction() const
|
|
{
|
|
return StencilLoadAction;
|
|
}
|
|
FORCEINLINE FExclusiveDepthStencil GetDepthStencilAccess() const
|
|
{
|
|
return DepthStencilAccess;
|
|
}
|
|
|
|
// Whether we can merge a render pass using @ref Other into a render pass using this depth stencil binding.
|
|
inline bool CanMergeBefore(const FDepthStencilBinding& Other) const
|
|
{
|
|
return
|
|
Texture == Other.Texture &&
|
|
ResolveTexture == Other.ResolveTexture &&
|
|
Other.DepthLoadAction != ERenderTargetLoadAction::EClear &&
|
|
Other.StencilLoadAction != ERenderTargetLoadAction::EClear &&
|
|
DepthStencilAccess == Other.DepthStencilAccess;
|
|
}
|
|
|
|
void SetTexture(FRDGTexture* InTexture)
|
|
{
|
|
Texture = InTexture;
|
|
check(Validate());
|
|
}
|
|
|
|
void SetResolveTexture(FRDGTexture* InTexture)
|
|
{
|
|
ResolveTexture = InTexture;
|
|
check(Validate());
|
|
}
|
|
|
|
void SetDepthStencilAccess(FExclusiveDepthStencil InAccess)
|
|
{
|
|
DepthStencilAccess = InAccess;
|
|
check(Validate());
|
|
}
|
|
|
|
void SetDepthLoadAction(ERenderTargetLoadAction InAction)
|
|
{
|
|
DepthLoadAction = InAction;
|
|
check(Validate());
|
|
}
|
|
|
|
void SetStencilLoadAction(ERenderTargetLoadAction InAction)
|
|
{
|
|
StencilLoadAction = InAction;
|
|
check(Validate());
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* All parameters required to bind a depth render target deferred. This are purposefully private to
|
|
* force the user to call FDepthStencilBinding() constructors. No defaults allowed.
|
|
*/
|
|
TAlignedShaderParameterPtr<FRDGTexture*> Texture = nullptr;
|
|
TAlignedShaderParameterPtr<FRDGTexture*> ResolveTexture = nullptr;
|
|
ERenderTargetLoadAction DepthLoadAction = ERenderTargetLoadAction::ENoAction;
|
|
ERenderTargetLoadAction StencilLoadAction = ERenderTargetLoadAction::ENoAction;
|
|
FExclusiveDepthStencil DepthStencilAccess = FExclusiveDepthStencil::DepthNop_StencilNop;
|
|
|
|
RENDERCORE_API bool Validate() const;
|
|
};
|
|
|
|
/** Special shader parameters type for a pass parameter to setup render targets. */
|
|
struct alignas(SHADER_PARAMETER_STRUCT_ALIGNMENT) FRenderTargetBindingSlots
|
|
{
|
|
TStaticArray<FRenderTargetBinding, MaxSimultaneousRenderTargets> Output;
|
|
FDepthStencilBinding DepthStencil;
|
|
FResolveRect ResolveRect;
|
|
uint32 NumOcclusionQueries = 0;
|
|
ESubpassHint SubpassHint = ESubpassHint::None;
|
|
uint8 MultiViewCount = 0;
|
|
FRDGTexture* ShadingRateTexture = nullptr;
|
|
|
|
/** Accessors for regular output to simplify the syntax to:
|
|
*
|
|
* FRenderTargetParameters PassParameters;
|
|
* PassParameters.RenderTargets.DepthStencil = ... ;
|
|
* PassParameters.RenderTargets[0] = ... ;
|
|
*/
|
|
FRenderTargetBinding& operator[](uint32 Index)
|
|
{
|
|
return Output[Index];
|
|
}
|
|
|
|
const FRenderTargetBinding& operator[](uint32 Index) const
|
|
{
|
|
return Output[Index];
|
|
}
|
|
|
|
template <typename TFunction>
|
|
void Enumerate(TFunction Function)
|
|
{
|
|
for (int32 Index = 0; Index < Output.Num(); Index++)
|
|
{
|
|
if (Output[Index].GetTexture())
|
|
{
|
|
Function(Output[Index]);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename TFunction>
|
|
void Enumerate(TFunction Function) const
|
|
{
|
|
for (int32 Index = 0; Index < Output.Num(); Index++)
|
|
{
|
|
if (Output[Index].GetTexture())
|
|
{
|
|
Function(Output[Index]);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint32 GetActiveCount() const
|
|
{
|
|
uint32 Count = 0;
|
|
for (; Output[Count].GetTexture() != nullptr; ++Count) {};
|
|
return Count;
|
|
}
|
|
|
|
bool CanMergeBefore(const FRenderTargetBindingSlots& Other) const
|
|
{
|
|
for (int32 Index = 0; Index < MaxSimultaneousRenderTargets; ++Index)
|
|
{
|
|
if (!Output[Index].CanMergeBefore(Other.Output[Index]))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!DepthStencil.CanMergeBefore(Other.DepthStencil))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (ResolveRect != Other.ResolveRect ||
|
|
(NumOcclusionQueries != Other.NumOcclusionQueries && Other.NumOcclusionQueries != 0) ||
|
|
SubpassHint != Other.SubpassHint ||
|
|
MultiViewCount != Other.MultiViewCount ||
|
|
ShadingRateTexture != Other.ShadingRateTexture)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
struct FTypeInfo
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_STRUCT_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = false;
|
|
|
|
using TAlignedType = FRenderTargetBindingSlots;
|
|
|
|
static inline const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
};
|
|
|
|
static_assert(sizeof(FRenderTargetBindingSlots) == 256, "FRenderTargetBindingSlots needs to be same size on all platforms.");
|
|
|
|
/** Static array of shader resource shader that is initialized to nullptr. */
|
|
template<typename TElement, uint32 NumElements>
|
|
class alignas(SHADER_PARAMETER_POINTER_ALIGNMENT) TShaderResourceParameterArray : public TStaticArray<TElement, NumElements, SHADER_PARAMETER_POINTER_ALIGNMENT>
|
|
{
|
|
public:
|
|
FORCEINLINE TShaderResourceParameterArray()
|
|
{
|
|
for (uint32 i = 0; i < NumElements; i++)
|
|
{
|
|
(*this)[i] = nullptr;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
/** Template to transcode some meta data information for a type <TypeParameter> not specific to shader parameters API. */
|
|
template<typename TypeParameter>
|
|
struct TShaderParameterTypeInfo
|
|
{
|
|
/** Defines what the type actually is. */
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_INVALID;
|
|
|
|
/** Defines the number rows and columns for vector or matrix based data typed. */
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
|
|
/** Defines the number of elements in an array fashion. 0 means this is not a TStaticArray,
|
|
* which therefor means there is 1 element.
|
|
*/
|
|
static constexpr int32 NumElements = 0;
|
|
|
|
/** Defines the alignment of the elements in bytes. */
|
|
static constexpr int32 Alignment = alignof(TypeParameter);
|
|
|
|
/** Defines whether this element is stored in constant buffer or not.
|
|
* This informations is usefull to ensure at compile time everything in the
|
|
* structure get defined at the end of the structure, to reduce as much as possible
|
|
* the size of the constant buffer.
|
|
*/
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
/** Type that is actually alligned. */
|
|
using TAlignedType = TypeParameter;
|
|
|
|
/** Type that has a multiple of 4 components. */
|
|
using TInstancedType = TypeParameter;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return TypeParameter::FTypeInfo::GetStructMetadata(); }
|
|
};
|
|
|
|
// Compile SHADER_PARAMETER(bool, MyBool), just to give good error message to programmer why they shouldn't do that.
|
|
template<>
|
|
struct TShaderParameterTypeInfo<bool>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_BOOL;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 4;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<bool, Alignment>::Type;
|
|
using TInstancedType = FUintVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<uint32>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_UINT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 4;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<uint32, Alignment>::Type;
|
|
using TInstancedType = FUintVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<int32>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_INT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 4;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<int32, Alignment>::Type;
|
|
using TInstancedType = FIntVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<float>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_FLOAT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 4;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<float, Alignment>::Type;
|
|
using TInstancedType = FVector4f;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FVector2f>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_FLOAT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 2;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 8;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FVector2f, Alignment>::Type;
|
|
using TInstancedType = FVector4f;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FVector3f>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_FLOAT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 3;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FVector3f, Alignment>::Type;
|
|
using TInstancedType = FVector4f;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FVector4f>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_FLOAT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 4;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FVector4f, Alignment>::Type;
|
|
using TInstancedType = FVector4f;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FLinearColor>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_FLOAT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 4;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FLinearColor, Alignment>::Type;
|
|
using TInstancedType = FLinearColor;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FIntPoint>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_INT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 2;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 8;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FIntPoint, Alignment>::Type;
|
|
using TInstancedType = FIntVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FUintVector2>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_UINT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 2;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 8;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FUintVector2, Alignment>::Type;
|
|
using TInstancedType = FUintVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FIntVector>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_INT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 3;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FIntVector, Alignment>::Type;
|
|
using TInstancedType = FIntVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FUintVector3>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_UINT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 3;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FUintVector3, Alignment>::Type;
|
|
using TInstancedType = FUintVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FIntVector4>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_INT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 4;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FIntVector4, Alignment>::Type;
|
|
using TInstancedType = FIntVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FUintVector4>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_UINT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 4;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FUintVector4, Alignment>::Type;
|
|
using TInstancedType = FUintVector4;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FIntRect>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_INT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 4;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FIntRect, Alignment>::Type;
|
|
using TInstancedType = FIntRect;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FQuat4f>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_FLOAT32;
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 4;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FQuat4f, Alignment>::Type;
|
|
using TInstancedType = FQuat4f;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterTypeInfo<FMatrix44f>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = UBMT_FLOAT32;
|
|
static constexpr int32 NumRows = 4;
|
|
static constexpr int32 NumColumns = 4;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = 16;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TAlignedTypedef<FMatrix44f, Alignment>::Type;
|
|
using TInstancedType = FMatrix44f;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template <typename BufferAccessType>
|
|
struct TRDGResourceAccessTypeInfo
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_POINTER_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = false;
|
|
|
|
using TAlignedType = BufferAccessType;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
|
|
static_assert(sizeof(TAlignedType) == SHADER_PARAMETER_POINTER_ALIGNMENT * 2, "Uniform buffer layout must not be platform dependent.");
|
|
};
|
|
|
|
template <typename TextureAccessType>
|
|
struct TRDGTextureAccessTypeInfo
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_POINTER_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = false;
|
|
|
|
using TAlignedType = TextureAccessType;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
|
|
static_assert(sizeof(TAlignedType) == SHADER_PARAMETER_POINTER_ALIGNMENT * 3, "Uniform buffer layout must not be platform dependent.");
|
|
};
|
|
|
|
|
|
template<typename T, size_t InNumElements>
|
|
struct TShaderParameterTypeInfo<T[InNumElements]>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = TShaderParameterTypeInfo<T>::BaseType;
|
|
static constexpr int32 NumRows = TShaderParameterTypeInfo<T>::NumRows;
|
|
static constexpr int32 NumColumns = TShaderParameterTypeInfo<T>::NumColumns;
|
|
static constexpr int32 NumElements = InNumElements;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_ARRAY_ELEMENT_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = TShaderParameterTypeInfo<T>::bIsStoredInConstantBuffer;
|
|
|
|
using TAlignedType = TStaticArray<T, InNumElements, Alignment>;
|
|
using TInstancedType = T;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return TShaderParameterTypeInfo<T>::GetStructMetadata(); }
|
|
|
|
static_assert(((sizeof(T) % 16) == 0), "Array element size does not satisfy 16 byte alignment requirements. Try packing it with other values in a vector or using SHADER_PARAMETER_SCALAR_ARRAY.");
|
|
};
|
|
|
|
template<typename T,size_t InNumElements,uint32 IgnoredAlignment>
|
|
struct TShaderParameterTypeInfo<TStaticArray<T,InNumElements,IgnoredAlignment>>
|
|
{
|
|
static constexpr EUniformBufferBaseType BaseType = TShaderParameterTypeInfo<T>::BaseType;
|
|
static constexpr int32 NumRows = TShaderParameterTypeInfo<T>::NumRows;
|
|
static constexpr int32 NumColumns = TShaderParameterTypeInfo<T>::NumColumns;
|
|
static constexpr int32 NumElements = InNumElements;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_ARRAY_ELEMENT_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = TShaderParameterTypeInfo<T>::bIsStoredInConstantBuffer;
|
|
|
|
using TAlignedType = TStaticArray<T, InNumElements, Alignment>;
|
|
using TInstancedType = T;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return TShaderParameterTypeInfo<T>::GetStructMetadata(); }
|
|
|
|
static_assert(((sizeof(T) % 16) == 0), "Array element size does not satisfy 16 byte alignment requirements. Try packing it with other values in a vector or using SHADER_PARAMETER_SCALAR_ARRAY.");
|
|
};
|
|
|
|
template<typename ShaderResourceType>
|
|
struct TShaderResourceParameterTypeInfo
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_POINTER_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = false;
|
|
|
|
using TAlignedType = TAlignedShaderParameterPtr<ShaderResourceType>;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
|
|
static_assert(sizeof(TAlignedType) == SHADER_PARAMETER_POINTER_ALIGNMENT, "Uniform buffer layout must not be platform dependent.");
|
|
};
|
|
|
|
template<typename ShaderResourceType, size_t InNumElements>
|
|
struct TShaderResourceParameterTypeInfo<ShaderResourceType[InNumElements]>
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = InNumElements;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_POINTER_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = false;
|
|
|
|
using TAlignedType = TShaderResourceParameterArray<ShaderResourceType, InNumElements>;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return nullptr; }
|
|
};
|
|
|
|
template<class UniformBufferStructType>
|
|
struct TShaderParameterTypeInfo<TUniformBufferRef<UniformBufferStructType>>
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_POINTER_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = false;
|
|
|
|
using TAlignedType = TAlignedShaderParameterPtr<TUniformBufferRef<UniformBufferStructType>>;
|
|
using TInstancedType = UniformBufferStructType;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return TUniformBufferMetadataHelper<UniformBufferStructType>::GetStructMetadata(); }
|
|
};
|
|
|
|
template<class UniformBufferStructType>
|
|
struct TShaderParameterTypeInfo<TUniformBufferBinding<UniformBufferStructType>>
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_STRUCT_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = false;
|
|
|
|
using TAlignedType = TUniformBufferBinding<UniformBufferStructType>;
|
|
using TInstancedType = UniformBufferStructType;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return TUniformBufferMetadataHelper<UniformBufferStructType>::GetStructMetadata(); }
|
|
};
|
|
|
|
template<class UniformBufferStructType>
|
|
struct TShaderParameterTypeInfo<TRDGUniformBufferBinding<UniformBufferStructType>>
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_STRUCT_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = false;
|
|
|
|
using TAlignedType = TRDGUniformBufferBinding<UniformBufferStructType>;
|
|
using TInstancedType = UniformBufferStructType;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return TUniformBufferMetadataHelper<UniformBufferStructType>::GetStructMetadata(); }
|
|
};
|
|
|
|
template<typename StructType>
|
|
struct TShaderParameterStructTypeInfo
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = 0;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_STRUCT_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = StructType;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return StructType::FTypeInfo::GetStructMetadata(); }
|
|
};
|
|
|
|
template<typename StructType, size_t InNumElements>
|
|
struct TShaderParameterStructTypeInfo<StructType[InNumElements]>
|
|
{
|
|
static constexpr int32 NumRows = 1;
|
|
static constexpr int32 NumColumns = 1;
|
|
static constexpr int32 NumElements = InNumElements;
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_STRUCT_ALIGNMENT;
|
|
static constexpr bool bIsStoredInConstantBuffer = true;
|
|
|
|
using TAlignedType = TStaticArray<StructType, InNumElements>;
|
|
|
|
static const FShaderParametersMetadata* GetStructMetadata() { return StructType::FTypeInfo::GetStructMetadata(); }
|
|
};
|
|
|
|
#define INTERNAL_BEGIN_UNIFORM_BUFFER_STRUCT(DllStorage) \
|
|
static DllStorage const FShaderParametersMetadata* GetStructMetadata();
|
|
|
|
#define INTERNAL_UNIFORM_BUFFER_STRUCT_GET_STRUCT_METADATA(StructTypeName) \
|
|
{ return StructTypeName::GetStructMetadata(); }
|
|
|
|
#define INTERNAL_SHADER_PARAMETER_GET_STRUCT_METADATA(StructTypeName) \
|
|
{ \
|
|
static FShaderParametersMetadata StaticStructMetadata(\
|
|
FShaderParametersMetadata::EUseCase::ShaderParameterStruct, \
|
|
EUniformBufferBindingFlags::Shader, \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(#StructTypeName), \
|
|
nullptr, \
|
|
nullptr, \
|
|
FTypeInfo::FileName, \
|
|
FTypeInfo::FileLine, \
|
|
sizeof(StructTypeName), \
|
|
StructTypeName::zzGetMembers()); \
|
|
return &StaticStructMetadata; \
|
|
}
|
|
|
|
|
|
#define INTERNAL_SHADER_PARAMETER_STRUCT_CREATE_UNIFORM_BUFFER return nullptr;
|
|
|
|
#define INTERNAL_UNIFORM_BUFFER_STRUCT_CREATE_UNIFORM_BUFFER return RHICreateUniformBuffer(&InContents, FTypeInfo::GetStructMetadata()->GetLayoutPtr(), InUsage);
|
|
|
|
/** Begins a uniform buffer struct declaration. */
|
|
#define INTERNAL_SHADER_PARAMETER_STRUCT_BEGIN(StructTypeName,DllStorage,ConstructorSuffix,GetStructMetadataScope,CreateUniformBufferImpl) \
|
|
MS_ALIGN(SHADER_PARAMETER_STRUCT_ALIGNMENT) class StructTypeName \
|
|
{ \
|
|
public: \
|
|
DllStorage StructTypeName () ConstructorSuffix \
|
|
struct FTypeInfo { \
|
|
static constexpr int32 NumRows = 1; \
|
|
static constexpr int32 NumColumns = 1; \
|
|
static constexpr int32 NumElements = 0; \
|
|
static constexpr int32 Alignment = SHADER_PARAMETER_STRUCT_ALIGNMENT; \
|
|
static constexpr bool bIsStoredInConstantBuffer = true; \
|
|
static constexpr const ANSICHAR* const FileName = UE_LOG_SOURCE_FILE(__builtin_FILE()); \
|
|
static constexpr int32 FileLine = __builtin_LINE(); \
|
|
using TAlignedType = StructTypeName; \
|
|
static const FShaderParametersMetadata* GetStructMetadata() GetStructMetadataScope \
|
|
}; \
|
|
static FUniformBufferRHIRef CreateUniformBuffer(const StructTypeName& InContents, EUniformBufferUsage InUsage) \
|
|
{ \
|
|
CreateUniformBufferImpl \
|
|
} \
|
|
private: \
|
|
typedef StructTypeName zzTThisStruct; \
|
|
struct zzFirstMemberId { enum { HasDeclaredResource = 0 }; }; \
|
|
typedef void* zzFuncPtr; \
|
|
typedef zzFuncPtr(*zzMemberFunc)(zzFirstMemberId, TArray<FShaderParametersMetadata::FMember>*); \
|
|
static zzFuncPtr zzAppendMemberGetPrev(zzFirstMemberId, TArray<FShaderParametersMetadata::FMember>*) \
|
|
{ \
|
|
return nullptr; \
|
|
} \
|
|
typedef zzFirstMemberId
|
|
|
|
/** Declares a member of a uniform buffer struct. */
|
|
#define INTERNAL_SHADER_PARAMETER_EXPLICIT(BaseType,TypeInfo,MemberType,MemberName,ArrayDecl,DefaultValue,Precision,OptionalShaderType,IsMemberStruct) \
|
|
zzMemberId##MemberName; \
|
|
public: \
|
|
alignas(TypeInfo::Alignment) TypeInfo::TAlignedType MemberName DefaultValue; \
|
|
static_assert(BaseType != UBMT_INVALID, "Invalid type " #MemberType " of member " #MemberName "."); \
|
|
private: \
|
|
struct zzNextMemberId##MemberName { enum { HasDeclaredResource = zzMemberId##MemberName::HasDeclaredResource || !TypeInfo::bIsStoredInConstantBuffer }; }; \
|
|
static zzFuncPtr zzAppendMemberGetPrev(zzNextMemberId##MemberName, TArray<FShaderParametersMetadata::FMember>* Members) \
|
|
{ \
|
|
static_assert(TypeInfo::bIsStoredInConstantBuffer || TIsArrayOrRefOfTypeByPredicate<decltype(OptionalShaderType), TIsCharEncodingCompatibleWithTCHAR>::Value, "No shader type for " #MemberName "."); \
|
|
static_assert(\
|
|
(STRUCT_OFFSET(zzTThisStruct, MemberName) & (TypeInfo::Alignment - 1)) == 0, \
|
|
"Misaligned uniform buffer struct member " #MemberName "."); \
|
|
Members->Add(FShaderParametersMetadata::FMember( \
|
|
TEXT(#MemberName), \
|
|
(const TCHAR*)OptionalShaderType, \
|
|
__LINE__, \
|
|
STRUCT_OFFSET(zzTThisStruct,MemberName), \
|
|
EUniformBufferBaseType(BaseType), \
|
|
Precision, \
|
|
TypeInfo::NumRows, \
|
|
TypeInfo::NumColumns, \
|
|
TypeInfo::NumElements, \
|
|
TypeInfo::GetStructMetadata() \
|
|
)); \
|
|
zzFuncPtr(*PrevFunc)(zzMemberId##MemberName, TArray<FShaderParametersMetadata::FMember>*); \
|
|
PrevFunc = zzAppendMemberGetPrev; \
|
|
return (zzFuncPtr)PrevFunc; \
|
|
} \
|
|
typedef zzNextMemberId##MemberName
|
|
|
|
/** Finds the FShaderParametersMetadata corresponding to the given name, or NULL if not found. */
|
|
extern RENDERCORE_API FShaderParametersMetadata* FindUniformBufferStructByName(const TCHAR* StructName);
|
|
extern RENDERCORE_API FShaderParametersMetadata* FindUniformBufferStructByFName(FName StructName);
|
|
|
|
/** Finds the FShaderParameterMetadata corresponding to the given uniform buffer layout hash, or null if not found. */
|
|
extern RENDERCORE_API FShaderParametersMetadata* FindUniformBufferStructByLayoutHash(uint32 Hash);
|
|
|
|
extern RENDERCORE_API FShaderParametersMetadata* FindUniformBufferStructByShaderVariableName(const FHashedName& Name);
|
|
|
|
/** Build the shader binding layout desc from array of used Uniform buffers which will be bound as static uniform buffers to the rhi */
|
|
extern RENDERCORE_API void BuildShaderBindingLayout(TConstArrayView<FShaderParametersMetadata*> UniformBuffers, EShaderBindingLayoutFlags BaseShaderBindingLayoutFlags, FShaderBindingLayoutContainer& OutShaderBindingLayoutContainer);
|
|
|
|
/** Begins & ends a shader parameter structure.
|
|
*
|
|
* Example:
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FMyParameterStruct, RENDERER_API)
|
|
* END_SHADER_PARAMETER_STRUCT()
|
|
*/
|
|
#define BEGIN_SHADER_PARAMETER_STRUCT(StructTypeName, DllStorage) \
|
|
INTERNAL_SHADER_PARAMETER_STRUCT_BEGIN(StructTypeName,, {}, INTERNAL_SHADER_PARAMETER_GET_STRUCT_METADATA(StructTypeName), INTERNAL_SHADER_PARAMETER_STRUCT_CREATE_UNIFORM_BUFFER)
|
|
|
|
#define END_SHADER_PARAMETER_STRUCT() \
|
|
zzLastMemberId; \
|
|
public: \
|
|
static TArray<FShaderParametersMetadata::FMember> zzGetMembers() { \
|
|
TArray<FShaderParametersMetadata::FMember> Members; \
|
|
zzFuncPtr(*LastFunc)(zzLastMemberId, TArray<FShaderParametersMetadata::FMember>*); \
|
|
LastFunc = zzAppendMemberGetPrev; \
|
|
zzFuncPtr Ptr = (zzFuncPtr)LastFunc; \
|
|
do \
|
|
{ \
|
|
Ptr = reinterpret_cast<zzMemberFunc>(Ptr)(zzFirstMemberId(), &Members); \
|
|
} while (Ptr); \
|
|
Algo::Reverse(Members); \
|
|
return Members; \
|
|
} \
|
|
} GCC_ALIGN(SHADER_PARAMETER_STRUCT_ALIGNMENT);
|
|
|
|
/** Begins & ends a shader global parameter structure.
|
|
*
|
|
* Example:
|
|
* // header
|
|
* BEGIN_UNIFORM_BUFFER_STRUCT(FMyParameterStruct, RENDERER_API)
|
|
* END_UNIFORM_BUFFER_STRUCT()
|
|
*
|
|
* // C++ file
|
|
* IMPLEMENT_UNIFORM_BUFFER_STRUCT(FMyParameterStruct, "MyShaderBindingName");
|
|
*/
|
|
#define BEGIN_UNIFORM_BUFFER_STRUCT(StructTypeName, DllStorage) \
|
|
DECLARE_UNIFORM_BUFFER_STRUCT(StructTypeName, DllStorage) \
|
|
INTERNAL_SHADER_PARAMETER_STRUCT_BEGIN(StructTypeName,,{} INTERNAL_BEGIN_UNIFORM_BUFFER_STRUCT(DllStorage), INTERNAL_UNIFORM_BUFFER_STRUCT_GET_STRUCT_METADATA(StructTypeName), INTERNAL_UNIFORM_BUFFER_STRUCT_CREATE_UNIFORM_BUFFER)
|
|
|
|
#define BEGIN_UNIFORM_BUFFER_STRUCT_WITH_CONSTRUCTOR(StructTypeName, DllStorage) \
|
|
DECLARE_UNIFORM_BUFFER_STRUCT(StructTypeName, DllStorage) \
|
|
INTERNAL_SHADER_PARAMETER_STRUCT_BEGIN(StructTypeName,DllStorage,; INTERNAL_BEGIN_UNIFORM_BUFFER_STRUCT(DllStorage), INTERNAL_UNIFORM_BUFFER_STRUCT_GET_STRUCT_METADATA(StructTypeName), INTERNAL_UNIFORM_BUFFER_STRUCT_CREATE_UNIFORM_BUFFER)
|
|
|
|
#define END_UNIFORM_BUFFER_STRUCT() \
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
|
|
class FShaderParametersMetadataRegistration
|
|
{
|
|
public:
|
|
FShaderParametersMetadataRegistration(TFunctionRef<const FShaderParametersMetadata* ()> LazyShaderParametersMetadataAccessor)
|
|
: LazyShaderParametersMetadataAccessor(LazyShaderParametersMetadataAccessor)
|
|
{
|
|
GetInstances().Add(this);
|
|
}
|
|
|
|
static RENDERCORE_API TArray<const FShaderParametersMetadataRegistration*>& GetInstances();
|
|
|
|
// Actually register all the instances and clear the array
|
|
static RENDERCORE_API void CommitAll();
|
|
static RENDERCORE_API bool IsReadyForRegistration();
|
|
|
|
private:
|
|
TFunctionRef<const FShaderParametersMetadata* ()> LazyShaderParametersMetadataAccessor;
|
|
};
|
|
|
|
#define IMPLEMENT_UNIFORM_BUFFER_STRUCT_EX(StructTypeName,ShaderVariableName,UsageFlags) \
|
|
const FShaderParametersMetadata* GetForwardDeclaredShaderParametersStructMetadata(const StructTypeName* DummyPtr) { return StructTypeName::FTypeInfo::GetStructMetadata(); } \
|
|
const FShaderParametersMetadata* StructTypeName::GetStructMetadata() \
|
|
{ \
|
|
ensureMsgf(FShaderParametersMetadataRegistration::IsReadyForRegistration(), TEXT("GetStructMetadata should not be called from a static initializer")); \
|
|
static const FShaderParametersMetadata StaticStructMetadata( \
|
|
FShaderParametersMetadata::EUseCase::UniformBuffer, \
|
|
EUniformBufferBindingFlags::Shader, \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(ShaderVariableName), \
|
|
nullptr, \
|
|
StructTypeName::FTypeInfo::FileName, \
|
|
StructTypeName::FTypeInfo::FileLine, \
|
|
sizeof(StructTypeName), \
|
|
StructTypeName::zzGetMembers(), \
|
|
false, \
|
|
nullptr, \
|
|
UsageFlags); \
|
|
return &StaticStructMetadata; \
|
|
} \
|
|
FShaderParametersMetadataRegistration StructTypeName##MetadataRegistration { TFunctionRef<const ::FShaderParametersMetadata* ()>{StructTypeName::GetStructMetadata} };
|
|
|
|
#define IMPLEMENT_UNIFORM_BUFFER_STRUCT(StructTypeName,ShaderVariableName) \
|
|
IMPLEMENT_UNIFORM_BUFFER_STRUCT_EX(StructTypeName,ShaderVariableName,FShaderParametersMetadata::EUsageFlags::None)
|
|
|
|
#define IMPLEMENT_UNIFORM_BUFFER_ALIAS_STRUCT(StructTypeName, UniformBufferAlias) \
|
|
static const FShaderParametersMetadata UniformBufferAlias( \
|
|
FShaderParametersMetadata::EUseCase::UniformBuffer, \
|
|
EUniformBufferBindingFlags::Shader, \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(#UniformBufferAlias), \
|
|
nullptr, \
|
|
StructTypeName::FTypeInfo::FileName, \
|
|
StructTypeName::FTypeInfo::FileLine, \
|
|
sizeof(StructTypeName), \
|
|
StructTypeName::zzGetMembers())
|
|
|
|
#define IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT_EX(StructTypeName,ShaderVariableName,StaticSlotName,BindingFlagsEnum) \
|
|
static_assert(EnumHasAnyFlags(EUniformBufferBindingFlags::BindingFlagsEnum, EUniformBufferBindingFlags::Static), "Shader bindings must include 'Static'."); \
|
|
const FShaderParametersMetadata* GetForwardDeclaredShaderParametersStructMetadata(const StructTypeName* DummyPtr) { return StructTypeName::FTypeInfo::GetStructMetadata(); } \
|
|
const FShaderParametersMetadata* StructTypeName::GetStructMetadata() \
|
|
{ \
|
|
ensureMsgf(FShaderParametersMetadataRegistration::IsReadyForRegistration(), TEXT("GetStructMetadata should not be called from a static initializer")); \
|
|
static const FShaderParametersMetadata StaticStructMetadata( \
|
|
FShaderParametersMetadata::EUseCase::UniformBuffer, \
|
|
EUniformBufferBindingFlags::BindingFlagsEnum, \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(ShaderVariableName), \
|
|
TEXT(#StaticSlotName), \
|
|
StructTypeName::FTypeInfo::FileName, \
|
|
StructTypeName::FTypeInfo::FileLine, \
|
|
sizeof(StructTypeName), \
|
|
StructTypeName::zzGetMembers()); \
|
|
return &StaticStructMetadata; \
|
|
} \
|
|
FShaderParametersMetadataRegistration StructTypeName##MetadataRegistration { TFunctionRef<const ::FShaderParametersMetadata* ()>{StructTypeName::GetStructMetadata} };
|
|
|
|
#define IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT_EX2(StructTypeName,ShaderVariableName,StaticSlotName,BindingFlagsEnum,UsageFlags) \
|
|
static_assert(EnumHasAnyFlags(EUniformBufferBindingFlags::BindingFlagsEnum, EUniformBufferBindingFlags::Static), "Shader bindings must include 'Static'."); \
|
|
const FShaderParametersMetadata* GetForwardDeclaredShaderParametersStructMetadata(const StructTypeName* DummyPtr) { return StructTypeName::FTypeInfo::GetStructMetadata(); } \
|
|
const FShaderParametersMetadata* StructTypeName::GetStructMetadata() \
|
|
{ \
|
|
ensureMsgf(FShaderParametersMetadataRegistration::IsReadyForRegistration(), TEXT("GetStructMetadata should not be called from a static initializer")); \
|
|
static const FShaderParametersMetadata StaticStructMetadata( \
|
|
FShaderParametersMetadata::EUseCase::UniformBuffer, \
|
|
EUniformBufferBindingFlags::BindingFlagsEnum, \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(#StructTypeName), \
|
|
TEXT(ShaderVariableName), \
|
|
TEXT(#StaticSlotName), \
|
|
StructTypeName::FTypeInfo::FileName, \
|
|
StructTypeName::FTypeInfo::FileLine, \
|
|
sizeof(StructTypeName), \
|
|
StructTypeName::zzGetMembers(), \
|
|
false, \
|
|
nullptr, \
|
|
UsageFlags); \
|
|
return &StaticStructMetadata; \
|
|
} \
|
|
FShaderParametersMetadataRegistration StructTypeName##MetadataRegistration { TFunctionRef<const ::FShaderParametersMetadata* ()>{StructTypeName::GetStructMetadata} };
|
|
|
|
/** Implements the same contract as IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT, with the addition of the 'StaticAndShader' binding
|
|
* flag. This means that the uniform buffer may be bound statically or through SetShaderParameters. The uniform buffer is NOT
|
|
* removed from the parameter map, which means it is possible to end up with both global and shader bindings. The RHI validation
|
|
* layer will catch and report these cases, as they are both inefficient and would produce confusing behavior if the two bindings
|
|
* differ. Only one binding model should be used at a time.
|
|
*/
|
|
#define IMPLEMENT_STATIC_AND_SHADER_UNIFORM_BUFFER_STRUCT(StructTypeName,ShaderVariableName,StaticSlotName) \
|
|
IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT_EX(StructTypeName, ShaderVariableName, StaticSlotName, StaticAndShader)
|
|
|
|
#define IMPLEMENT_STATIC_AND_SHADER_UNIFORM_BUFFER_STRUCT_EX(StructTypeName,ShaderVariableName,StaticSlotName,UsageFlags) \
|
|
IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT_EX2(StructTypeName, ShaderVariableName, StaticSlotName, StaticAndShader, UsageFlags)
|
|
|
|
/** Implements a uniform buffer tied to a static binding slot. The third parameter is the name of the slot.
|
|
* Multiple uniform buffers can be associated to a slot; only one uniform buffer can be bound to a slot
|
|
* at one time.
|
|
*
|
|
* Example:
|
|
* BEGIN_UNIFORM_BUFFER_STRUCT(FMyParameterStruct, RENDERER_API)
|
|
* END_UNIFORM_BUFFER_STRUCT()
|
|
*
|
|
* // C++ file
|
|
*
|
|
* // Define uniform buffer slot.
|
|
* IMPLEMENT_STATIC_UNIFORM_BUFFER_SLOT(MySlot)
|
|
*
|
|
* // Associate uniform buffer with slot.
|
|
* IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT(FMyParameterStruct, "MyShaderBindingName", MySlot);
|
|
*/
|
|
#define IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT(StructTypeName,ShaderVariableName,StaticSlotName) \
|
|
IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT_EX(StructTypeName, ShaderVariableName, StaticSlotName, Static)
|
|
|
|
/** Implements a uniform buffer static binding slot. */
|
|
#define IMPLEMENT_STATIC_UNIFORM_BUFFER_SLOT(SlotName) \
|
|
static FUniformBufferStaticSlotRegistrar UniformBufferStaticSlot_##SlotName(TEXT(#SlotName));
|
|
|
|
/** Legacy macro definitions. */
|
|
#define BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT \
|
|
BEGIN_UNIFORM_BUFFER_STRUCT
|
|
|
|
#define BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT_WITH_CONSTRUCTOR \
|
|
BEGIN_UNIFORM_BUFFER_STRUCT_WITH_CONSTRUCTOR
|
|
|
|
#define END_GLOBAL_SHADER_PARAMETER_STRUCT \
|
|
END_UNIFORM_BUFFER_STRUCT
|
|
|
|
#define IMPLEMENT_GLOBAL_SHADER_PARAMETER_STRUCT \
|
|
IMPLEMENT_UNIFORM_BUFFER_STRUCT
|
|
|
|
#define IMPLEMENT_GLOBAL_SHADER_PARAMETER_ALIAS_STRUCT \
|
|
IMPLEMENT_UNIFORM_BUFFER_ALIAS_STRUCT
|
|
|
|
/** Adds a constant-buffer stored value.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER(float, MyScalar)
|
|
* SHADER_PARAMETER(FMatrix44f, MyMatrix)
|
|
*/
|
|
#define SHADER_PARAMETER(MemberType,MemberName) \
|
|
SHADER_PARAMETER_EX(MemberType,MemberName,EShaderPrecisionModifier::Float)
|
|
|
|
#define SHADER_PARAMETER_EX(MemberType,MemberName,Precision) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(TShaderParameterTypeInfo<MemberType>::BaseType, TShaderParameterTypeInfo<MemberType>, MemberType,MemberName,,,Precision,TEXT(""),false)
|
|
|
|
/** Adds a constant-buffer stored array of values.
|
|
* MemberType size must be a multiple of 16byte (see SHADER_PARAMETER_SCALAR_ARRAY for scalar arrays).
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_ARRAY(FMatrix44f, MyMatrixArray, [2])
|
|
*/
|
|
#define SHADER_PARAMETER_ARRAY(MemberType,MemberName,ArrayDecl) \
|
|
SHADER_PARAMETER_ARRAY_EX(MemberType,MemberName,ArrayDecl,EShaderPrecisionModifier::Float)
|
|
|
|
#define SHADER_PARAMETER_ARRAY_EX(MemberType,MemberName,ArrayDecl,Precision) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(TShaderParameterTypeInfo<MemberType ArrayDecl>::BaseType, TShaderParameterTypeInfo<MemberType ArrayDecl>, MemberType,MemberName,ArrayDecl,,Precision,TEXT(""),false)
|
|
|
|
/** Adds a texture.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_TEXTURE(Texture2D, MyTexture)
|
|
* SHADER_PARAMETER_TEXTURE_ARRAY(Texture2D, MyArrayOfTextures, [8])
|
|
*/
|
|
#define SHADER_PARAMETER_TEXTURE(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_TEXTURE, TShaderResourceParameterTypeInfo<FRHITexture*>, FRHITexture*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_TEXTURE_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_TEXTURE, TShaderResourceParameterTypeInfo<FRHITexture* ArrayDecl>, FRHITexture*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a shader resource view.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_SRV(Texture2D, MySRV)
|
|
* SHADER_PARAMETER_SRV_ARRAY(Texture2D, MyArrayOfSRVs, [8])
|
|
*/
|
|
#define SHADER_PARAMETER_SRV(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_SRV, TShaderResourceParameterTypeInfo<FRHIShaderResourceView*>, FRHIShaderResourceView*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_SRV_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_SRV, TShaderResourceParameterTypeInfo<FRHIShaderResourceView* ArrayDecl>, FRHIShaderResourceView*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds an unordered access view.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_UAV(RWTexture2D, MyUAV)
|
|
*/
|
|
#define SHADER_PARAMETER_UAV(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_UAV, TShaderResourceParameterTypeInfo<FRHIUnorderedAccessView*>, FRHIUnorderedAccessView*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a sampler.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_SAMPLER(SamplerState, MySampler)
|
|
* SHADER_PARAMETER_SAMPLER_ARRAY(SamplerState, MyArrayOfSamplers, [8])
|
|
*/
|
|
#define SHADER_PARAMETER_SAMPLER(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_SAMPLER, TShaderResourceParameterTypeInfo<FRHISamplerState*>, FRHISamplerState*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_SAMPLER_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_SAMPLER, TShaderResourceParameterTypeInfo<FRHISamplerState* ArrayDecl>, FRHISamplerState*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a render graph tracked texture.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_RDG_TEXTURE(Texture2D, MyTexture)
|
|
* SHADER_PARAMETER_RDG_TEXTURE_ARRAY(Texture2D, MyArrayOfTextures, [4])
|
|
*/
|
|
#define SHADER_PARAMETER_RDG_TEXTURE(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE, TShaderResourceParameterTypeInfo<FRDGTexture*>, FRDGTexture*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_RDG_TEXTURE_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE, TShaderResourceParameterTypeInfo<FRDGTexture* ArrayDecl>, FRDGTexture*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a shader resource view for a render graph tracked texture.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, MySRV)
|
|
* SHADER_PARAMETER_RDG_TEXTURE_SRV_ARRAY(Texture2D, MyArrayOfSRVs, [4])
|
|
*/
|
|
#define SHADER_PARAMETER_RDG_TEXTURE_SRV(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_SRV, TShaderResourceParameterTypeInfo<FRDGTextureSRV*>, FRDGTextureSRV*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_RDG_TEXTURE_SRV_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_SRV, TShaderResourceParameterTypeInfo<FRDGTextureSRV* ArrayDecl>, FRDGTextureSRV*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a non-pixel shader resource view for a render graph tracked texture.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_RDG_TEXTURE_NON_PIXEL_SRV(Texture2D, MySRV)
|
|
* SHADER_PARAMETER_RDG_TEXTURE_NON_PIXEL_SRV_ARRAY(Texture2D, MyArrayOfSRVs, [4])
|
|
*/
|
|
#define SHADER_PARAMETER_RDG_TEXTURE_NON_PIXEL_SRV(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_NON_PIXEL_SRV, TShaderResourceParameterTypeInfo<FRDGTextureSRV*>, FRDGTextureSRV*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_RDG_TEXTURE_NON_PIXEL_SRV_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_NON_PIXEL_SRV, TShaderResourceParameterTypeInfo<FRDGTextureSRV* ArrayDecl>, FRDGTextureSRV*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a unordered access view for a render graph tracked texture.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, MyUAV)
|
|
* SHADER_PARAMETER_RDG_TEXTURE_UAV_ARRAY(Texture2D, MyArrayOfUAVs, [4])
|
|
*/
|
|
#define SHADER_PARAMETER_RDG_TEXTURE_UAV(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_UAV, TShaderResourceParameterTypeInfo<FRDGTextureUAV*>, FRDGTextureUAV*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_RDG_TEXTURE_UAV_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_UAV, TShaderResourceParameterTypeInfo<FRDGTextureUAV* ArrayDecl>, FRDGTextureUAV*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a shader resource view for a render graph tracked buffer.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<float4>, MySRV)
|
|
* SHADER_PARAMETER_RDG_BUFFER_SRV_ARRAY(Buffer<float4>, MyArrayOfSRVs, [4])
|
|
*/
|
|
#define SHADER_PARAMETER_RDG_BUFFER_SRV(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_BUFFER_SRV, TShaderResourceParameterTypeInfo<FRDGBufferSRV*>, FRDGBufferSRV*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_RDG_BUFFER_SRV_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_BUFFER_SRV, TShaderResourceParameterTypeInfo<FRDGBufferSRV* ArrayDecl>, FRDGBufferSRV*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a unordered access view for a render graph tracked buffer.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<float4>, MyUAV)
|
|
* SHADER_PARAMETER_RDG_BUFFER_UAV_ARRAY(RWBuffer<float4>, MyArrayOfUAVs, [4])
|
|
*/
|
|
#define SHADER_PARAMETER_RDG_BUFFER_UAV(ShaderType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_BUFFER_UAV, TShaderResourceParameterTypeInfo<FRDGBufferUAV*>, FRDGBufferUAV*,MemberName,, = nullptr,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
#define SHADER_PARAMETER_RDG_BUFFER_UAV_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_BUFFER_UAV, TShaderResourceParameterTypeInfo<FRDGBufferUAV* ArrayDecl>, FRDGBufferUAV*,MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#ShaderType),false)
|
|
|
|
/** Adds a render graph tracked uniform buffer.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FMyStruct, MemberName)
|
|
*/
|
|
#define SHADER_PARAMETER_RDG_UNIFORM_BUFFER(StructType, MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_UNIFORM_BUFFER, TShaderParameterTypeInfo<TRDGUniformBufferBinding<StructType>>, TRDGUniformBufferBinding<StructType>,MemberName,,,EShaderPrecisionModifier::Float,TEXT(#StructType),false)
|
|
|
|
/** Nests a shader parameter structure into another one, in C++ and shader code.
|
|
*
|
|
* Example:
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FMyNestedStruct,)
|
|
* SHADER_PARAMETER(float, MyScalar)
|
|
* // ...
|
|
* END_SHADER_PARAMETER_STRUCT()
|
|
*
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FOtherStruct)
|
|
* SHADER_PARAMETER_STRUCT(FMyNestedStruct, MyStruct)
|
|
*
|
|
* C++ use case:
|
|
* FOtherStruct Parameters;
|
|
* Parameters.MyStruct.MyScalar = 1.0f;
|
|
*
|
|
* Shader code for a globally named shader parameter struct:
|
|
* float MyScalar = MyGlobalShaderBindingName.MyStruct.MyScalar;
|
|
*
|
|
* Shader code for a unnamed shader parameter struct:
|
|
* float MyScalar = MyStruct_MyScalar;
|
|
*/
|
|
#define SHADER_PARAMETER_STRUCT(StructType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_NESTED_STRUCT, StructType::FTypeInfo, StructType, MemberName,,,EShaderPrecisionModifier::Float,TEXT(#StructType),true)
|
|
|
|
/** Nests an array of shader parameter structure into another one, in C++ and shader code.
|
|
*
|
|
* Example:
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FMyNestedStruct,)
|
|
* SHADER_PARAMETER(float, MyScalar)
|
|
* // ...
|
|
* END_SHADER_PARAMETER_STRUCT()
|
|
*
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FOtherStruct)
|
|
* SHADER_PARAMETER_STRUCT_ARRAY(FMyNestedStruct, MyStructArray, [4])
|
|
*
|
|
* C++ use case:
|
|
* FOtherStruct Parameters;
|
|
* Parameters.MyStructArray[0].MyScalar = 1.0f;
|
|
*
|
|
* Shader code for a globally named shader parameter struct (UNSUPPORTED):
|
|
* float MyScalar = MyGlobalShaderBindingName.MyStructArray_0.MyScalar;
|
|
*
|
|
* Shader code for a unnamed shader parameter struct:
|
|
* float MyScalar = MyStructArray_0_MyScalar;
|
|
*/
|
|
#define SHADER_PARAMETER_STRUCT_ARRAY(StructType,MemberName, ArrayDecl) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_NESTED_STRUCT, TShaderParameterStructTypeInfo<StructType ArrayDecl>, StructType, MemberName,ArrayDecl,,EShaderPrecisionModifier::Float,TEXT(#StructType),true)
|
|
|
|
/** Include a shader parameter structure into another one in shader code.
|
|
*
|
|
* Example:
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FMyNestedStruct,)
|
|
* SHADER_PARAMETER(float, MyScalar)
|
|
* // ...
|
|
* END_SHADER_PARAMETER_STRUCT()
|
|
*
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FOtherStruct)
|
|
* SHADER_PARAMETER_STRUCT_INCLUDE(FMyNestedStruct, MyStruct)
|
|
*
|
|
* C++ use case:
|
|
* FOtherStruct Parameters;
|
|
* Parameters.MyStruct.MyScalar = 1.0f;
|
|
*
|
|
* Shader code for a globally named shader parameter struct:
|
|
* float MyScalar = MyGlobalShaderBindingName.MyScalar;
|
|
*
|
|
* Shader code for a unnamed shader parameter struct:
|
|
* float MyScalarValue = MyScalar;
|
|
*/
|
|
#define SHADER_PARAMETER_STRUCT_INCLUDE(StructType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_INCLUDED_STRUCT, StructType::FTypeInfo, StructType, MemberName,,,EShaderPrecisionModifier::Float,TEXT(#StructType),true)
|
|
|
|
/** Include a binding slot for a globally named shader parameter structure
|
|
*
|
|
* Example:
|
|
* BEGIN_UNIFORM_BUFFER_STRUCT(FGlobalViewParameters,)
|
|
* SHADER_PARAMETER(FVector4f, ViewSizeAndInvSize)
|
|
* // ...
|
|
* END_UNIFORM_BUFFER_STRUCT()
|
|
*
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FOtherStruct)
|
|
* SHADER_PARAMETER_STRUCT_REF(FMyNestedStruct, MyStruct)
|
|
*/
|
|
#define SHADER_PARAMETER_STRUCT_REF(StructType,MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_REFERENCED_STRUCT, TShaderParameterTypeInfo<TUniformBufferBinding<StructType>>, TUniformBufferBinding<StructType>,MemberName,,,EShaderPrecisionModifier::Float,TEXT(#StructType),false)
|
|
|
|
/** Informs the RDG pass to transition the buffer into the requested state.
|
|
*
|
|
* Example:
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FParameters,)
|
|
* RDG_BUFFER_ACCESS(MyBuffer)
|
|
* // ...
|
|
* END_SHADER_PARAMETER_STRUCT()
|
|
*
|
|
* FParameters Parameters;
|
|
* Parameters.MyBuffer = FRDGBufferAccess(Buffer, ERHIAccess::CopyDest);
|
|
**/
|
|
#define RDG_BUFFER_ACCESS(MemberName, Access) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_BUFFER_ACCESS, TRDGResourceAccessTypeInfo<TRDGBufferAccess<Access>>, TRDGBufferAccess<Access>,MemberName,,,EShaderPrecisionModifier::Float,TEXT(""),false)
|
|
|
|
#define RDG_BUFFER_ACCESS_DYNAMIC(MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_BUFFER_ACCESS, TRDGResourceAccessTypeInfo<FRDGBufferAccess>, FRDGBufferAccess,MemberName,,,EShaderPrecisionModifier::Float,TEXT(""),false)
|
|
|
|
#define RDG_BUFFER_ACCESS_ARRAY(MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_BUFFER_ACCESS_ARRAY, TRDGResourceAccessTypeInfo<FRDGBufferAccessArray>, FRDGBufferAccessArray,MemberName,,,EShaderPrecisionModifier::Float,TEXT(""),false)
|
|
|
|
/** Informs the RDG pass to transition the texture into the requested state. */
|
|
#define RDG_TEXTURE_ACCESS(MemberName, Access) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_ACCESS, TRDGTextureAccessTypeInfo<TRDGTextureAccess<Access>>, TRDGTextureAccess<Access>,MemberName,,,EShaderPrecisionModifier::Float,TEXT(""),false)
|
|
|
|
#define RDG_TEXTURE_ACCESS_DYNAMIC(MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_ACCESS, TRDGTextureAccessTypeInfo<FRDGTextureAccess>, FRDGTextureAccess,MemberName,,,EShaderPrecisionModifier::Float,TEXT(""),false)
|
|
|
|
#define RDG_TEXTURE_ACCESS_ARRAY(MemberName) \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RDG_TEXTURE_ACCESS_ARRAY, TRDGResourceAccessTypeInfo<FRDGTextureAccessArray>, FRDGTextureAccessArray,MemberName,,,EShaderPrecisionModifier::Float,TEXT(""),false)
|
|
|
|
/** Adds bindings slots for render targets on the structure. This is important for rasterizer based pass bind the
|
|
* render target at the RHI pass creation. The name of the struct member will forced to RenderTargets, and
|
|
* its type is a FRenderTargetBindingSlots.
|
|
*
|
|
* Example:
|
|
* BEGIN_SHADER_PARAMETER_STRUCT(FGlobalViewParameters,)
|
|
* RENDER_TARGET_BINDING_SLOTS()
|
|
* // ...
|
|
* END_SHADER_PARAMETER_STRUCT()
|
|
*
|
|
* FGlobalViewParameters Parameters;
|
|
* Parameters.RenderTargets.DepthStencil = FDepthStencilBinding( //... );
|
|
*/
|
|
#define RENDER_TARGET_BINDING_SLOTS() \
|
|
INTERNAL_SHADER_PARAMETER_EXPLICIT(UBMT_RENDER_TARGET_BINDING_SLOTS, FRenderTargetBindingSlots::FTypeInfo, FRenderTargetBindingSlots,RenderTargets,,,EShaderPrecisionModifier::Float,TEXT(""),false)
|
|
|
|
/** An empty shader parameter structure ready to be used anywhere. */
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FEmptyShaderParameters, RENDERCORE_API)
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
/** Useful parameter struct that only have render targets.
|
|
*
|
|
* FRenderTargetParameters PassParameters;
|
|
* PassParameters.RenderTargets.DepthStencil = ... ;
|
|
* PassParameters.RenderTargets[0] = ... ;
|
|
*/
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FRenderTargetParameters, RENDERCORE_API)
|
|
RENDER_TARGET_BINDING_SLOTS()
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
/** Returns the name of the macro that should be used for a given shader parameter base type. */
|
|
const TCHAR* GetShaderParameterMacroName(EUniformBufferBaseType ShaderParameterBaseType);
|
|
|
|
/** Deprecated buffer macros. */
|
|
#define SHADER_PARAMETER_RDG_BUFFER_UPLOAD(MemberName) \
|
|
UE_DEPRECATED_MACRO(5.0, "SHADER_PARAMETER_RDG_BUFFER_UPLOAD has been deprecated. Use RDG_BUFFER_ACCESS(Buffer, ERHIAccess::CopyDest) instead.") \
|
|
RDG_BUFFER_ACCESS(MemberName, ERHIAccess::CopyDest)
|
|
|
|
#define SHADER_PARAMETER_RDG_BUFFER(ShaderType,MemberName) \
|
|
UE_DEPRECATED_MACRO(5.0, "SHADER_PARAMETER_RDG_BUFFER has been deprecated. Use RDG_BUFFER_ACCESS with an explicit RHI state instead.") \
|
|
RDG_BUFFER_ACCESS(MemberName, ERHIAccess::SRVMask | ERHIAccess::IndirectArgs)
|
|
|
|
#define SHADER_PARAMETER_RDG_BUFFER_ARRAY(ShaderType,MemberName, ArrayDecl) \
|
|
UE_DEPRECATED_MACRO(5.0, "SHADER_PARAMETER_RDG_BUFFER_ARRAY has been deprecated. Use RDG_BUFFER_ACCESS_ARRAY instead.")
|
|
|
|
|
|
|
|
|
|
/** Upgrade the scalar type to a vector for storage. */
|
|
|
|
template<typename TypeParameter>
|
|
struct TShaderParameterScalarArrayTypeInfo
|
|
{
|
|
static_assert(sizeof(TypeParameter) == 0, "This type is not supported for automatic packing.");
|
|
using PackedArrayType = void;
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterScalarArrayTypeInfo<uint32>
|
|
{
|
|
using PackedArrayType = FUintVector4;
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterScalarArrayTypeInfo<int32>
|
|
{
|
|
using PackedArrayType = FIntVector4;
|
|
};
|
|
|
|
template<>
|
|
struct TShaderParameterScalarArrayTypeInfo<float>
|
|
{
|
|
using PackedArrayType = FVector4f;
|
|
};
|
|
|
|
constexpr uint32 CalcPackedArraySize(uint32 NumElements) { return (NumElements + 3) / 4; }
|
|
constexpr uint32 CalcPackedArrayIndex(uint32 ElementIndex) { return (ElementIndex >> 2); }
|
|
constexpr uint32 CalcPackedComponentIndex(uint32 ElementIndex) { return (ElementIndex & 3); }
|
|
|
|
/** Adds a packed constant-buffer stored array of values.
|
|
*
|
|
* Example:
|
|
* SHADER_PARAMETER_SCALAR_ARRAY(float, MyScalarArray, 8)
|
|
*/
|
|
#define SHADER_PARAMETER_SCALAR_ARRAY(MemberType,MemberName,ArrayDecl) \
|
|
SHADER_PARAMETER_ARRAY(TShaderParameterScalarArrayTypeInfo<MemberType>::PackedArrayType, MemberName, [CalcPackedArraySize(TShaderParameterTypeInfo<TShaderParameterScalarArrayTypeInfo<MemberType>::PackedArrayType ArrayDecl>::NumElements)])
|
|
|
|
#define GET_SCALAR_ARRAY_ELEMENT(PackedArray, ElementIndex) \
|
|
PackedArray[CalcPackedArrayIndex(ElementIndex)][CalcPackedComponentIndex(ElementIndex)]
|
|
|
|
PRAGMA_ENABLE_BUFFER_OVERRUN_WARNING |