337 lines
8.1 KiB
C
337 lines
8.1 KiB
C
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Containers/UnrealString.h"
|
|
#include "CoreMinimal.h"
|
|
#include "HAL/Platform.h"
|
|
#include "PixelFormat.h"
|
|
#include "RHIDefinitions.h"
|
|
#include "RHIShaderPlatform.h"
|
|
|
|
enum EGBufferSlot
|
|
{
|
|
GBS_Invalid,
|
|
GBS_SceneColor, // RGB 11.11.10
|
|
GBS_WorldNormal, // RGB 10.10.10
|
|
GBS_PerObjectGBufferData, // 2
|
|
GBS_Metallic, // R8
|
|
GBS_Specular, // R8
|
|
GBS_Roughness, // R8
|
|
GBS_ShadingModelId, // 4 bits
|
|
GBS_SelectiveOutputMask, // 4 bits
|
|
GBS_BaseColor, // RGB8
|
|
GBS_GenericAO, // R8
|
|
GBS_IndirectIrradiance, // R8
|
|
GBS_AO, // R8
|
|
GBS_Velocity, // RG, float16
|
|
GBS_PrecomputedShadowFactor, // RGBA8
|
|
GBS_WorldTangent, // RGB8
|
|
GBS_Anisotropy, // R8
|
|
GBS_CustomData, // RGBA8, no compression
|
|
GBS_SubsurfaceColor, // RGB8
|
|
GBS_Opacity, // R8
|
|
GBS_SubsurfaceProfile, //RGB8
|
|
GBS_ClearCoat, // R8
|
|
GBS_ClearCoatRoughness, // R8
|
|
GBS_HairSecondaryWorldNormal, // RG8
|
|
GBS_HairBacklit, // R8
|
|
GBS_Cloth, // R8
|
|
GBS_SubsurfaceProfileX, // R8
|
|
GBS_IrisNormal, // RG8
|
|
GBS_SeparatedMainDirLight, // RGB 11.11.10
|
|
GBS_Num
|
|
};
|
|
|
|
|
|
enum EGBufferCompression
|
|
{
|
|
GBC_Invalid,
|
|
GBC_Raw_Float_16_16_16_16,
|
|
GBC_Raw_Float_16_16_16,
|
|
GBC_Raw_Float_11_11_10,
|
|
GBC_Raw_Float_10_10_10,
|
|
GBC_Raw_Unorm_8_8_8_8,
|
|
GBC_Raw_Unorm_8_8_8,
|
|
GBC_Raw_Unorm_8_8,
|
|
GBC_Raw_Unorm_8,
|
|
GBC_Raw_Unorm_2, // a float value normalized to use 2 bits
|
|
GBC_Raw_Float_16_16,
|
|
GBC_Raw_Float_16,
|
|
GBC_Bits_4, // an int value, that is fundamentally 4 bits
|
|
GBC_Bits_2, // an int value, that is fundamentally 2 bits
|
|
|
|
GBC_Packed_Normal_Octahedral_8_8,
|
|
GBC_EncodeNormal_Normal_16_16_16,
|
|
GBC_EncodeNormal_Normal_10_10_10,
|
|
GBC_EncodeNormal_Normal_8_8_8,
|
|
|
|
GBC_Packed_Color_5_6_5, // a unorm value, packed to 565
|
|
GBC_Packed_Color_5_6_5_Sqrt, // a unorm value, packed to 565, with sqrt
|
|
GBC_Packed_Color_4_4_4, // a unorm value, packed to 444
|
|
GBC_Packed_Color_4_4_4_Sqrt, // a unorm value, packed to 444, with sqrt
|
|
GBC_Packed_Color_3_3_2, // a unorm value, packed to 332
|
|
GBC_Packed_Color_3_3_2_Sqrt, // a unorm value, packed to 332, with sqrt
|
|
GBC_Packed_Quantized_6, // a unorm value, quantized to 6 bits
|
|
GBC_Packed_Quantized_4, // a unorm value, quantized to 4 bits
|
|
GBC_Packed_Quantized_2, // a unorm value, quantized to 2 bits
|
|
|
|
GBC_Num
|
|
};
|
|
|
|
// the actual format of the output texture
|
|
enum EGBufferType
|
|
{
|
|
GBT_Invalid,
|
|
GBT_Unorm_16_16,
|
|
GBT_Unorm_8_8_8_8,
|
|
GBT_Unorm_11_11_10,
|
|
GBT_Unorm_10_10_10_2,
|
|
GBT_Unorm_16_16_16_16,
|
|
GBT_Float_16_16,
|
|
GBT_Float_16_16_16_16,
|
|
GBT_Float_32,
|
|
GBT_Num
|
|
};
|
|
|
|
enum EGBufferChecker
|
|
{
|
|
GBCH_Invalid,
|
|
GBCH_Even,
|
|
GBCH_Odd,
|
|
GBCH_Both,
|
|
GBCH_Num
|
|
};
|
|
|
|
enum EGBufferLayout
|
|
{
|
|
GBL_Default, // Default GBuffer Layout
|
|
GBL_ForceVelocity, // Force the inclusion of the velocity target (if it's not included in GBL_Default)
|
|
|
|
GBL_Num
|
|
};
|
|
|
|
|
|
struct FGBufferCompressionInfo
|
|
{
|
|
EGBufferCompression Type; // compression type
|
|
int32 SrcNumChan; // how many channels before compression
|
|
int32 DstNumChan; // how many channels after copression
|
|
int32 ChanBits[4]; // how many bits are each destination channel
|
|
bool bIsPackedBits; //
|
|
bool bIsConversion; //
|
|
const TCHAR* EncodeFuncName; // name of the function to do this conversion
|
|
const TCHAR* DecodeFuncName; // name of the function to do this conversion
|
|
};
|
|
|
|
|
|
struct FGBufferPacking
|
|
{
|
|
FGBufferPacking()
|
|
{
|
|
bIsValid = false;
|
|
bFull = false;
|
|
TargetIndex = -1;
|
|
DstChannelIndex = -1;
|
|
SrcChannelIndex = -1;
|
|
DstBitStart = -1;
|
|
SrcBitStart = -1;
|
|
BitNum = -1;
|
|
}
|
|
|
|
// if we pass in 2 values, it means we use the entire channel
|
|
FGBufferPacking(int32 InTargetIndex, int32 InSrcChannelIndex, int32 InDstChannelIndex)
|
|
{
|
|
bIsValid = true;
|
|
bFull = true;
|
|
TargetIndex = InTargetIndex;
|
|
DstChannelIndex = InDstChannelIndex;
|
|
SrcChannelIndex = InSrcChannelIndex;
|
|
DstBitStart = -1;
|
|
SrcBitStart = -1;
|
|
BitNum = -1;
|
|
}
|
|
|
|
// if we pass in 4 values, it means we also need to pack the bits
|
|
FGBufferPacking(int32 InTargetIndex, int32 InSrcChannelIndex, int32 InDstChannelIndex, int32 InSrcBitStart, int32 InDstBitStart, int32 InBitNum)
|
|
{
|
|
bIsValid = true;
|
|
bFull = false;
|
|
TargetIndex = InTargetIndex;
|
|
DstChannelIndex = InDstChannelIndex;
|
|
SrcChannelIndex = InSrcChannelIndex;
|
|
DstBitStart = InDstBitStart;
|
|
SrcBitStart = InSrcBitStart;
|
|
BitNum = InBitNum;
|
|
}
|
|
|
|
bool bIsValid;
|
|
bool bFull;
|
|
int32 TargetIndex;
|
|
int32 DstChannelIndex;
|
|
int32 DstBitStart;
|
|
int32 SrcChannelIndex;
|
|
int32 SrcBitStart;
|
|
int32 BitNum;
|
|
};
|
|
|
|
|
|
// the texture positions in the GBuffer
|
|
struct FGBufferItem
|
|
{
|
|
FGBufferItem()
|
|
{
|
|
bIsValid = false;
|
|
bQuantizationBias = false;
|
|
BufferSlot = GBS_Invalid;
|
|
Compression = GBC_Invalid;
|
|
Checker = GBCH_Invalid;
|
|
|
|
for (int32 I = 0; I < 4; I++)
|
|
{
|
|
Packing[I] = {};
|
|
}
|
|
}
|
|
|
|
FGBufferItem(EGBufferSlot InBufferSlot, EGBufferCompression InCompression, EGBufferChecker InChecker)
|
|
{
|
|
bIsValid = true;
|
|
bQuantizationBias = false;
|
|
BufferSlot = InBufferSlot;
|
|
Compression = InCompression;
|
|
Checker = InChecker;
|
|
|
|
for (int32 I = 0; I < 4; I++)
|
|
{
|
|
Packing[I] = {};
|
|
}
|
|
}
|
|
|
|
static const int MaxPacking = 8;
|
|
|
|
bool bIsValid;
|
|
bool bQuantizationBias;
|
|
EGBufferSlot BufferSlot;
|
|
EGBufferCompression Compression;
|
|
EGBufferChecker Checker;
|
|
FGBufferPacking Packing[MaxPacking]; // 8 should be plenty, can always make it larger
|
|
};
|
|
|
|
struct FGBufferTarget
|
|
{
|
|
FGBufferTarget()
|
|
{
|
|
TargetType = GBT_Invalid;
|
|
bIsSrgb = false;
|
|
bIsRenderTargetable = false;
|
|
bIsShaderResource = false;
|
|
bIsUsingExtraFlags = false;
|
|
}
|
|
|
|
bool operator==(const FGBufferTarget & Rhs) const
|
|
{
|
|
return TargetType == Rhs.TargetType &&
|
|
TargetName == Rhs.TargetName &&
|
|
bIsSrgb == Rhs.bIsSrgb &&
|
|
bIsRenderTargetable == Rhs.bIsRenderTargetable &&
|
|
bIsShaderResource == Rhs.bIsShaderResource &&
|
|
bIsUsingExtraFlags == Rhs.bIsUsingExtraFlags;
|
|
}
|
|
|
|
void Init(EGBufferType InTargetType,
|
|
FString InTargetName,
|
|
bool bInIsSrgb,
|
|
bool bInIsRenderTargetable,
|
|
bool bInIsShaderResource,
|
|
bool bInIsUsingExtraFlags)
|
|
{
|
|
TargetType = InTargetType;
|
|
TargetName = InTargetName;
|
|
bIsSrgb = bInIsSrgb;
|
|
bIsRenderTargetable = bInIsRenderTargetable;
|
|
bIsShaderResource = bInIsShaderResource;
|
|
bIsUsingExtraFlags = bInIsUsingExtraFlags;
|
|
}
|
|
|
|
EGBufferType TargetType;
|
|
FString TargetName;
|
|
bool bIsSrgb;
|
|
bool bIsRenderTargetable;
|
|
bool bIsShaderResource;
|
|
bool bIsUsingExtraFlags;
|
|
};
|
|
|
|
struct FGBufferBinding
|
|
{
|
|
int32 Index = -1;
|
|
EPixelFormat Format = PF_Unknown;
|
|
ETextureCreateFlags Flags = TexCreate_None;
|
|
};
|
|
|
|
// Describes the bindings of the GBuffer for a given layout
|
|
struct FGBufferBindings
|
|
{
|
|
FGBufferBinding GBufferA;
|
|
FGBufferBinding GBufferB;
|
|
FGBufferBinding GBufferC;
|
|
FGBufferBinding GBufferD;
|
|
FGBufferBinding GBufferE;
|
|
FGBufferBinding GBufferVelocity;
|
|
};
|
|
|
|
struct FGBufferInfo
|
|
{
|
|
static const int MaxTargets = 8;
|
|
|
|
int32 NumTargets;
|
|
FGBufferTarget Targets[MaxTargets];
|
|
|
|
FGBufferItem Slots[GBS_Num];
|
|
|
|
};
|
|
|
|
struct FGBufferParams
|
|
{
|
|
EShaderPlatform ShaderPlatform = SP_NumPlatforms;
|
|
int32 LegacyFormatIndex = 0;
|
|
bool bHasVelocity = false;
|
|
bool bHasTangent = false;
|
|
bool bHasPrecShadowFactor = false;
|
|
bool bUsesVelocityDepth = false;
|
|
bool bHasSingleLayerWaterSeparatedMainLight = false;
|
|
|
|
bool operator == (const FGBufferParams& RHS) const
|
|
{
|
|
return
|
|
ShaderPlatform == RHS.ShaderPlatform &&
|
|
LegacyFormatIndex == RHS.LegacyFormatIndex &&
|
|
bHasVelocity == RHS.bHasVelocity &&
|
|
bHasTangent == RHS.bHasTangent &&
|
|
bHasPrecShadowFactor == RHS.bHasPrecShadowFactor &&
|
|
bUsesVelocityDepth == RHS.bUsesVelocityDepth &&
|
|
bHasSingleLayerWaterSeparatedMainLight == RHS.bHasSingleLayerWaterSeparatedMainLight;
|
|
}
|
|
|
|
bool operator != (const FGBufferParams& RHS) const
|
|
{
|
|
return !(*this == RHS);
|
|
}
|
|
};
|
|
|
|
|
|
int32 RENDERCORE_API FindGBufferTargetByName(const FGBufferInfo& GBufferInfo, const FString& Name);
|
|
|
|
FGBufferBinding RENDERCORE_API FindGBufferBindingByName(const FGBufferInfo& GBufferInfo, const FString& Name, EShaderPlatform ShaderPlatform);
|
|
|
|
UE_DEPRECATED(5.4, "Please use the overload which takes a shader platform parameter")
|
|
inline FGBufferBinding FindGBufferBindingByName(const FGBufferInfo& GBufferInfo, const FString& Name)
|
|
{
|
|
return FindGBufferBindingByName(GBufferInfo, Name, GMaxRHIShaderPlatform);
|
|
}
|
|
|
|
FGBufferInfo RENDERCORE_API FetchFullGBufferInfo(const FGBufferParams& Params);
|
|
|
|
bool RENDERCORE_API IsGBufferInfoEqual(const FGBufferInfo& Lhs, const FGBufferInfo& Rhs);
|
|
|
|
|