Strata - moving SSSData at the end of the strata material buffer to reduce UAV count limitation on dx11.

Fixed a bug wehre loadiung fast material would not be done correctly inside the classification pass for the sharedmemeory path.
#rb none
#jira UE-161415
#preflight https://horde.devtools.epicgames.com/job/630909b9987e7155b1af0aec
#fyi charles.derousiers

[CL 21661992 by Sebastien Hillaire in ue5-main branch]
This commit is contained in:
Sebastien Hillaire
2022-08-29 02:55:17 -04:00
parent c0865adebe
commit e27b68cc9b
14 changed files with 80 additions and 75 deletions

View File

@@ -1681,10 +1681,10 @@ void FPixelShaderInOut_MainPS(
BRANCH
if(StrataSubSurfaceHeaderGetIsValid(SSSData.Header))
{
StrataStruct.SSSTextureUAV[uint3(PixelPos, 0)] = SSSData.Header.Bytes;
StrataStoreSubsurfaceHeader(StrataStruct.MaterialTextureArrayUAVWithoutRTs, StrataStruct.FirstSliceStoringStrataSSSDataWithoutMRT, PixelPos, SSSData.Header.Bytes);
if (StrataSubSurfaceHeaderHasExtras(SSSData.Header))
{
StrataStruct.SSSTextureUAV[uint3(PixelPos, 1)] = SSSData.Extras.Bytes;
StrataStoreSubsurfaceExtras(StrataStruct.MaterialTextureArrayUAVWithoutRTs, StrataStruct.FirstSliceStoringStrataSSSDataWithoutMRT, PixelPos, SSSData.Extras.Bytes);
}
}

View File

@@ -723,7 +723,7 @@ void DistanceFieldShadowingCS(
#if !FORWARD_SHADING && DF_SHADOW_QUALITY > 1 && !SHADING_PATH_MOBILE
#if STRATA_ENABLED
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, ScreenPosition);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, ScreenPosition);
BRANCH
if (StrataSubSurfaceHeaderGetIsValid(SSSHeader))
{

View File

@@ -208,7 +208,7 @@ FLumenMaterialData InternalReadMaterialData_Strata(uint2 InPixelPos)
FStrataAddressing StrataAddressing = GetStrataPixelDataByteOffset(InPixelPos, uint2(View.BufferSizeAndInvSize.xy), Strata.MaxBytesPerPixel);
const FStrataPixelHeader StrataPixelHeader = UnpackStrataHeaderIn(Strata.MaterialTextureArray, StrataAddressing, Strata.TopLayerTexture);
const FStrataTopLayerData TopLayerData = StrataUnpackTopLayerData(Strata.TopLayerTexture.Load(uint3(InPixelPos, 0)));
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, InPixelPos);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, InPixelPos);
// When Lumen is not used, only MaterialAO and ShadingID (see IsValid) are read, sourced form the single UINT read for the StrataPixelHeader.
@@ -263,7 +263,7 @@ FLumenMaterialData InternalReadMaterialData_Strata(uint2 InCoord, uint InBSDFInd
StrataSeekBSDF(StrataAddressing, AddressOffset);
}
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, InCoord);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, InCoord);
const FStrataBSDF BSDF = UnpackStrataBSDFIn(Strata.MaterialTextureArray, StrataAddressing, StrataPixelHeader);
const FStrataIrradianceAndOcclusion IrradianceAO = StrataGetIrradianceAndAO(StrataPixelHeader);

View File

@@ -125,12 +125,12 @@ float GetMaskFromDepthInAlpha(float Alpha)
FStrataSubsurfaceData LoadStrataSSSData(float2 UV)
{
const float2 PixelPos = UV.xy * View.BufferSizeAndInvSize.xy;
return StrataLoadSubsurfaceData(Strata.SSSTexture, PixelPos);
return StrataLoadSubsurfaceData(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, PixelPos);
}
FStrataSubsurfaceHeader LoadStrataSSSHeader(float2 UV)
{
const float2 PixelPos = UV.xy * View.BufferSizeAndInvSize.xy;
return StrataLoadSubsurfaceHeader(Strata.SSSTexture, PixelPos);
return StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, PixelPos);
}
#endif

View File

@@ -619,7 +619,7 @@ RAY_TRACING_ENTRY_RAYGEN(OcclusionRGS)
const FStrataPixelHeader StrataPixelHeader = UnpackStrataHeaderIn(Strata.MaterialTextureArray, StrataAddressing, Strata.TopLayerTexture);
const FStrataTopLayerData TopLayerData = StrataUnpackTopLayerData(Strata.TopLayerTexture.Load(uint3(PixelCoord, 0)));
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, PixelCoord);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, PixelCoord);
const bool bSSSIsValid = StrataSubSurfaceHeaderGetUseDiffusion(SSSHeader);
const bool bSSSIsProfile = StrataSubSurfaceHeaderGetIsProfile(SSSHeader);

View File

@@ -269,7 +269,7 @@ void Main(
if (bIsSubsurfaceCompatible && bHasSubsurface)
{
#if STRATA_ENABLED
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, SVPos.xy);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, SVPos.xy);
const uint SSSType = StrataSubSurfaceHeaderGetSSSType(SSSHeader);
#endif
@@ -457,7 +457,7 @@ void MainOnePassPointLightPS(
const FStrataTopLayerData TopLayerData = StrataUnpackTopLayerData(Strata.TopLayerTexture.Load(uint3(SVPos.xy, 0)));
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, SVPos.xy);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, SVPos.xy);
const bool IsSubsurfaceProfile = StrataSubSurfaceHeaderGetUseDiffusion(SSSHeader);
const float3 WorldNormal = TopLayerData.WorldNormal;

View File

@@ -874,26 +874,35 @@ struct FStrataSubsurfaceData
FStrataSubsurfaceHeader Header;
FStrataSubsurfaceExtras Extras;
};
FStrataSubsurfaceHeader StrataLoadSubsurfaceHeader(Texture2DArray<uint> SSSTexture, uint2 PixelPos)
FStrataSubsurfaceHeader StrataLoadSubsurfaceHeader(Texture2DArray<uint> StrataBuffer, uint FirstSliceStoringStrataSSSData, uint2 PixelPos)
{
FStrataSubsurfaceHeader Header;
Header.Bytes = SSSTexture.Load(uint4(PixelPos, 0, 0));
Header.Bytes = StrataBuffer.Load(uint4(PixelPos, FirstSliceStoringStrataSSSData + 0, 0));
return Header;
}
FStrataSubsurfaceExtras StrataLoadSubsurfaceExtras(Texture2DArray<uint> SSSTexture, uint2 PixelPos)
FStrataSubsurfaceExtras StrataLoadSubsurfaceExtras(Texture2DArray<uint> StrataBuffer, uint FirstSliceStoringStrataSSSData, uint2 PixelPos)
{
FStrataSubsurfaceExtras Extras;
Extras.Bytes = SSSTexture.Load(uint4(PixelPos, 1, 0));
Extras.Bytes = StrataBuffer.Load(uint4(PixelPos, FirstSliceStoringStrataSSSData + 1, 0));
return Extras;
}
FStrataSubsurfaceData StrataLoadSubsurfaceData(Texture2DArray<uint> SSSTexture, uint2 PixelPos)
FStrataSubsurfaceData StrataLoadSubsurfaceData(Texture2DArray<uint> StrataBuffer, uint FirstSliceStoringStrataSSSData, uint2 PixelPos)
{
FStrataSubsurfaceData SSSData;
SSSData.Header = StrataLoadSubsurfaceHeader(SSSTexture, PixelPos);
SSSData.Extras = StrataLoadSubsurfaceExtras(SSSTexture, PixelPos);
SSSData.Header = StrataLoadSubsurfaceHeader(StrataBuffer, FirstSliceStoringStrataSSSData, PixelPos);
SSSData.Extras = StrataLoadSubsurfaceExtras(StrataBuffer, FirstSliceStoringStrataSSSData, PixelPos);
return SSSData;
}
void StrataStoreSubsurfaceHeader(RWTexture2DArray<uint> StrataBuffer, uint FirstSliceStoringStrataSSSData, uint2 PixelPos, uint HeaderBytes)
{
StrataBuffer[uint3(PixelPos, FirstSliceStoringStrataSSSData + 0)] = HeaderBytes;
}
void StrataStoreSubsurfaceExtras(RWTexture2DArray<uint> StrataBuffer, uint FirstSliceStoringStrataSSSData, uint2 PixelPos, uint ExtraBytes)
{
StrataBuffer[uint3(PixelPos, FirstSliceStoringStrataSSSData + 1)] = ExtraBytes;
}
uint StrataSubsurfaceProfileIdTo8bits(float In)
{
// Similar encoding than ExtractSubsurfaceProfileInt. Valid profile ID start at 1.
@@ -3487,11 +3496,9 @@ uint PackStrataHeader(uint InBSDFCount, FStrataPixelHeader InHeader)
// Unpack only strata header
// If this is changed, please update the compiler side material size evaluation in StrataMaterial.cpp
FStrataPixelHeader UnpackStrataHeaderIn(FStrataMaterialContainer StrataBuffer, inout FStrataAddressing StrataAddressing, FStrataTopLayerDataContainer InStrataTopLayerTexture)
FStrataPixelHeader UnpackStrataHeaderIn(uint PackedHeader, inout FStrataAddressing StrataAddressing, FStrataTopLayerDataContainer InStrataTopLayerTexture)
{
FStrataPixelHeader Out = InitialiseStrataPixelHeader();
uint PackedHeader = StrataLoadUint1(StrataBuffer, StrataAddressing);
Out.State = HEADER_GETCOMMONSTATES(PackedHeader); // Unpack state and AO data at the same time
Out.BSDFCount = HEADER_GETBSDFCOUNT(PackedHeader);
@@ -3504,7 +3511,6 @@ FStrataPixelHeader UnpackStrataHeaderIn(FStrataMaterialContainer StrataBuffer, i
Out.BSDFCount = IsStrataMaterial(Out) ? 1 : 0;
#if STRATA_DEFERRED_SHADING
Out.StrataBuffer = StrataBuffer;
Out.SharedLocalBasesTypes_PackedHeader = PackedHeader;
Out.SharedLocalBasesIndexOffset = 0; // Unused
@@ -3519,7 +3525,6 @@ FStrataPixelHeader UnpackStrataHeaderIn(FStrataMaterialContainer StrataBuffer, i
uint SharedLocalBasesTypes = HEADER_GETSHAREDLOCALBASESTYPE(PackedHeader);
#if STRATA_DEFERRED_SHADING
Out.StrataBuffer = StrataBuffer;
Out.SharedLocalBasesTypes_PackedHeader = SharedLocalBasesTypes;
Out.PackedTopLayerData = 0;
@@ -3538,6 +3543,18 @@ FStrataPixelHeader UnpackStrataHeaderIn(FStrataMaterialContainer StrataBuffer, i
return Out;
}
FStrataPixelHeader UnpackStrataHeaderIn(FStrataMaterialContainer StrataBuffer, inout FStrataAddressing StrataAddressing, FStrataTopLayerDataContainer InStrataTopLayerTexture)
{
uint PackedHeader = StrataLoadUint1(StrataBuffer, StrataAddressing);
FStrataPixelHeader Out = UnpackStrataHeaderIn(PackedHeader, StrataAddressing, InStrataTopLayerTexture);
#if STRATA_DEFERRED_SHADING
Out.StrataBuffer = StrataBuffer;
#endif
return Out;
}
bool IsStrataSlabFastPathCompatible(in FStrataBSDF BSDF)
{
return (BSDF.State & SLAB_COMPLEX_PATH_MASK) == 0;

View File

@@ -15,13 +15,12 @@
int bRectPrimitive;
int2 ViewResolution;
uint MaxBytesPerPixel;
int FirstSliceStoringStrataSSSData;
Texture2D<uint> TopLayerTexture;
#if PERMUTATION_CMASK
Texture2D<uint> TopLayerCmaskTexture;
RWTexture2D<uint> MaterialHeaderTextureUAV;
#else
Texture2DArray<uint> MaterialTextureArray;
#endif
RWTexture2DArray<uint> MaterialTextureArrayUAV;
// Indirect draw data buffer for all tile types
RWBuffer<uint> TileDrawIndirectDataBuffer;
@@ -40,8 +39,6 @@ Texture2D<float3> OpaqueRoughRefractionTexture;
groupshared uint s_TileFlags[GROUP_THREAD_COUNT];
#endif
RWTexture2DArray<uint> SSSTextureUAV;
[numthreads(STRATA_TILE_SIZE, STRATA_TILE_SIZE, 1)]
void TileMainCS(uint2 DispatchThreadId : SV_DispatchThreadID, uint LinearIndex : SV_GroupIndex, uint3 GroupId : SV_GroupID)
{
@@ -69,8 +66,8 @@ void TileMainCS(uint2 DispatchThreadId : SV_DispatchThreadID, uint LinearIndex :
BRANCH
if (CMask == 0x0)
{
MaterialHeaderTextureUAV[PixelCoord] = 0u;
SSSTextureUAV[uint3(PixelCoord, 0)] = 0; // This is a good clear for FStrataSubsurfaceHeader, and we only need to clear the header.
MaterialTextureArrayUAV[uint3(PixelCoord, 0)] = 0u;
StrataStoreSubsurfaceHeader(MaterialTextureArrayUAV, FirstSliceStoringStrataSSSData, PixelCoord, 0u); // This is a good clear for FStrataSubsurfaceHeader, and we only need to clear the header.
}
else
{
@@ -87,21 +84,17 @@ void TileMainCS(uint2 DispatchThreadId : SV_DispatchThreadID, uint LinearIndex :
if (bIsValid)
{
FStrataAddressing StrataAddressing = GetStrataPixelDataByteOffset(PixelCoord, uint2(View.BufferSizeAndInvSize.xy), MaxBytesPerPixel);
#if PERMUTATION_CMASK
FStrataPixelHeader StrataPixelHeader = InitialiseStrataPixelHeader();
const uint PackedHeader = MaterialHeaderTextureUAV[PixelCoord];
StrataPixelHeader.State = HEADER_GETCOMMONSTATES(PackedHeader);
StrataPixelHeader.BSDFCount = HEADER_GETBSDFCOUNT(PackedHeader);
#else
FStrataPixelHeader StrataPixelHeader = UnpackStrataHeaderIn(MaterialTextureArray, StrataAddressing, TopLayerTexture);
#endif
// Load mini header.
const uint PackedHeader = MaterialTextureArrayUAV[uint3(PixelCoord, 0)];
FStrataPixelHeader StrataPixelHeader = UnpackStrataHeaderIn(PackedHeader, StrataAddressing, TopLayerTexture);
const bool bIsSimple = IsSimpleMaterial(StrataPixelHeader) || StrataPixelHeader.BSDFCount == 0; // BSDFCount == 0 ensures that non-strata pixel, like sky pixels, won't make a simple tile flagged as complex
const bool bIsSingle = !IsSimpleMaterial(StrataPixelHeader) && IsSingleMaterial(StrataPixelHeader);
bContainsStrataMaterial = StrataPixelHeader.BSDFCount > 0;
bContainsSimpleMaterial = bIsSimple;
bContainsSingleMaterial = bIsSingle;
bContainsComplexMaterial = !bIsSingle & !bIsSimple;
bContainsComplexMaterial = !bIsSingle && !bIsSimple;
bContainsScreenSpaceSubsurfaceScattering = HasSubsurface(StrataPixelHeader);
#if STRATA_OPAQUE_ROUGH_REFRACTION_ENABLED
@@ -123,7 +116,7 @@ void TileMainCS(uint2 DispatchThreadId : SV_DispatchThreadID, uint LinearIndex :
BRANCH
if (bClearHeader)
{
MaterialHeaderTextureUAV[PixelCoord] = 0u;
MaterialTextureArrayUAV[uint3(PixelCoord, 0)] = 0u;
}
#endif
}
@@ -132,7 +125,7 @@ void TileMainCS(uint2 DispatchThreadId : SV_DispatchThreadID, uint LinearIndex :
if (!bContainsScreenSpaceSubsurfaceScattering)
{
// We must fill all the pixel which does not have subsurface scattering by default so that the SSS code is not executed where it should not.
SSSTextureUAV[uint3(PixelCoord, 0)] = 0; // This is a good clear for FStrataSubsurfaceHeader, and we only need to clear the header.
StrataStoreSubsurfaceHeader(MaterialTextureArrayUAV, FirstSliceStoringStrataSSSData, PixelCoord, 0u); // This is a good clear for FStrataSubsurfaceHeader, and we only need to clear the header.
}
#if PERMUTATION_WAVE_OPS

View File

@@ -58,7 +58,7 @@ void AddDrawPixelFootprint(float3 P, float3 dPdx, float3 dPdy, float2 Scale, boo
void DrawPixelFootprint(float3 P, float3 dPdx, float3 dPdy, uint2 PixelCoord)
{
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, PixelCoord);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, PixelCoord);
const uint SubsurfaceProfileInt = StrataSubSurfaceHeaderGetProfileId(SSSHeader);
const bool bIsValid = StrataSubSurfaceHeaderGetIsValid(SSSHeader);
const bool bIsProfile = StrataSubSurfaceHeaderGetIsProfile(SSSHeader);
@@ -265,7 +265,7 @@ void PrintBSDF(inout FShaderPrintContext Context, inout FStrataAddressing Strata
if (BSDF_GETSSSTYPE(BSDF) != SSS_TYPE_INVALID || BSDF_GETISSIMPLEVOLUME(BSDF) || BSDF_GETISTHIN(BSDF))
{
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, StrataAddressing.PixelCoords);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, StrataAddressing.PixelCoords);
const uint SSSType = StrataSubSurfaceHeaderGetSSSType(SSSHeader);
const float Opacity = StrataSubSurfaceHeaderGetWrapOpacity(SSSHeader);
Print(Context, TEXT(" SSS Type "), FontBSDFPropName); PrintSSSType(Context, SSSType, FontYellow); Newline(Context, RectMax);
@@ -361,7 +361,7 @@ void PrintBSDF(inout FShaderPrintContext Context, inout FStrataAddressing Strata
DrawReferentialTWS(WorldPosition, IrisPlaneTangentBasis[0], IrisPlaneTangentBasis[1], IrisPlaneTangentBasis[2], float3(1, 0, 1));
const bool bHasSSS = HasSubsurface(Header);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, StrataAddressing.PixelCoords);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, StrataAddressing.PixelCoords);
const bool bIsValid = StrataSubSurfaceHeaderGetIsValid(SSSHeader);
const bool bIsProfile = StrataSubSurfaceHeaderGetIsProfile(SSSHeader);
if (bHasSSS && bIsValid && bIsProfile)
@@ -488,7 +488,7 @@ void PrintPixel(uint2 InCoord, float3 InWorldPosition, float3 V)
const uint FootPrint_PostBSDFs = StrataAddressing.ReadBytes;
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, StrataAddressing.PixelCoords);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, StrataAddressing.PixelCoords);
const bool bHasSSSData = StrataSubSurfaceHeaderGetIsValid(SSSHeader);
const uint TopLayerDataBytes = 4; // bytes

View File

@@ -51,7 +51,7 @@ FProjectionShadingInfo GetProjectionShadingInfo(uint2 PixelPos)
const FStrataPixelHeader StrataPixelHeader = UnpackStrataHeaderIn(Strata.MaterialTextureArray, StrataAddressing, Strata.TopLayerTexture);
const FStrataTopLayerData TopLayerData = StrataUnpackTopLayerData(Strata.TopLayerTexture.Load(uint3(PixelPos, 0)));
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.SSSTexture, PixelPos);
const FStrataSubsurfaceHeader SSSHeader = StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, PixelPos);
const bool bIsValid = StrataSubSurfaceHeaderGetIsValid(SSSHeader);
const bool bIsProfile = StrataSubSurfaceHeaderGetIsProfile(SSSHeader);
Out.bIsSubsurface = bIsValid && !bIsProfile;

View File

@@ -15,7 +15,7 @@ float GetSubsurfaceOpacityFromGbuffer(uint2 PixelPos)
float Opacity = 1.0;
#if STRATA_ENABLED
Opacity = StrataGetOpacityFromSubSurface(StrataLoadSubsurfaceHeader(Strata.SSSTexture, PixelPos));
Opacity = StrataGetOpacityFromSubSurface(StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, PixelPos));
#else // STRATA_ENABLED
FGBufferData GBufferData = GetGBufferDataUint(PixelPos);

View File

@@ -41,6 +41,8 @@
#define STRATA_BASE_PASS_MRT_OUTPUT_COUNT 2
#define STRATA_SSS_DATA_UINT_COUNT 2
#define STRATA_OPERATOR_WEIGHT 0
#define STRATA_OPERATOR_VERTICAL 1
#define STRATA_OPERATOR_HORIZONTAL 2

View File

@@ -321,15 +321,6 @@ void InitialiseStrataFrameSceneData(FRDGBuilder& GraphBuilder, FSceneRenderer& S
Out.TopLayerTexture = GraphBuilder.CreateTexture(FRDGTextureDesc::Create2D(SceneTextureExtent, PF_R32_UINT, FClearValueBinding::Black, TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_FastVRAM), TEXT("Strata.TopLayerTexture"));
}
// SSS texture
{
const uint32 SSSDataUintCount = 2;
const FRDGTextureDesc SSSTextureDesc = FRDGTextureDesc::Create2DArray(SceneTextureExtent, PF_R32_UINT, FClearValueBinding::Black,
TexCreate_TargetArraySlicesIndependently | TexCreate_DisableDCC | TexCreate_NoFastClear | TexCreate_ShaderResource | TexCreate_UAV, SSSDataUintCount, 1, 1);
Out.SSSTexture = GraphBuilder.CreateTexture(SSSTextureDesc, TEXT("Strata.SSSTexture"));
Out.SSSTextureUAV = GraphBuilder.CreateUAV(Out.SSSTexture);
}
// Separated subsurface and rough refraction textures
{
const bool bIsStrataOpaqueMaterialRoughRefractionEnabled = IsStrataOpaqueMaterialRoughRefractionEnabled();
@@ -368,7 +359,8 @@ void InitialiseStrataFrameSceneData(FRDGBuilder& GraphBuilder, FSceneRenderer& S
// Create the material data container
FIntPoint SceneTextureExtent = IsStrataEnabled() ? SceneRenderer.GetActiveSceneTexturesConfig().Extent : FIntPoint(2, 2);
const uint32 SliceCount = FMath::DivideAndRoundUp(Out.MaxBytesPerPixel, 4u);
const uint32 SliceCountSSS = STRATA_SSS_DATA_UINT_COUNT;
const uint32 SliceCount = FMath::DivideAndRoundUp(Out.MaxBytesPerPixel, 4u) + SliceCountSSS;
const FRDGTextureDesc MaterialTextureDesc = FRDGTextureDesc::Create2DArray(SceneTextureExtent, PF_R32_UINT, FClearValueBinding::Transparent,
TexCreate_TargetArraySlicesIndependently | TexCreate_DisableDCC | TexCreate_NoFastClear | TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_UAV, SliceCount, 1, 1);
Out.MaterialTextureArray = GraphBuilder.CreateTexture(MaterialTextureDesc, TEXT("Strata.Material"));
@@ -376,14 +368,19 @@ void InitialiseStrataFrameSceneData(FRDGBuilder& GraphBuilder, FSceneRenderer& S
Out.MaterialTextureArrayUAV = GraphBuilder.CreateUAV(FRDGTextureUAVDesc(Out.MaterialTextureArray, 0));
// See AppendStrataMRTs
check(STRATA_BASE_PASS_MRT_OUTPUT_COUNT <= SliceCount);
check(STRATA_BASE_PASS_MRT_OUTPUT_COUNT <= (SliceCount - SliceCountSSS)); // We want enough slice for MRTs but also do not want the SSSData to be a MRT.
Out.MaterialTextureArrayUAVWithoutRTs = GraphBuilder.CreateUAV(FRDGTextureUAVDesc(Out.MaterialTextureArray, 0, PF_Unknown, STRATA_BASE_PASS_MRT_OUTPUT_COUNT, SliceCount - STRATA_BASE_PASS_MRT_OUTPUT_COUNT));
// Rough diffuse model
Out.bRoughDiffuse = CVarStrataRoughDiffuse.GetValueOnRenderThread() > 0 ? 1u : 0u;
Out.PeelLayersAboveDepth = FMath::Max(CVarStrataDebugPeelLayersAboveDepth.GetValueOnRenderThread(), 0);
Out.SliceStoringDebugStrataTree = SliceCount - 1 - STRATA_BASE_PASS_MRT_OUTPUT_COUNT; // The UAV skips the first slices set as render target
// STRATA_TODO allocate a slice for StoringDebugStrata only if STRATA_ADVANCED_DEBUG_ENABLED is enabled
Out.SliceStoringDebugStrataTree = SliceCount - 1 - STRATA_BASE_PASS_MRT_OUTPUT_COUNT - SliceCountSSS; // The UAV skips the first slices set as render target and other utility re
Out.FirstSliceStoringStrataSSSData = SliceCount - SliceCountSSS; // When we read, there is no slices excluded
Out.FirstSliceStoringStrataSSSDataWithoutMRT = SliceCount - SliceCountSSS - STRATA_BASE_PASS_MRT_OUTPUT_COUNT; // The UAV skips the first slices set as render target
// Initialized view data
for (int32 ViewIndex = 0; ViewIndex < SceneRenderer.Views.Num(); ViewIndex++)
@@ -401,15 +398,12 @@ void BindStrataBasePassUniformParameters(FRDGBuilder& GraphBuilder, const FViewI
OutStrataUniformParameters.MaxBytesPerPixel = StrataSceneData->MaxBytesPerPixel;
OutStrataUniformParameters.PeelLayersAboveDepth = StrataSceneData->PeelLayersAboveDepth;
OutStrataUniformParameters.SliceStoringDebugStrataTree = StrataSceneData->SliceStoringDebugStrataTree;
OutStrataUniformParameters.FirstSliceStoringStrataSSSDataWithoutMRT = StrataSceneData->FirstSliceStoringStrataSSSDataWithoutMRT;
OutStrataUniformParameters.MaterialTextureArrayUAVWithoutRTs = StrataSceneData->MaterialTextureArrayUAVWithoutRTs;
OutStrataUniformParameters.SSSTextureUAV = StrataSceneData->SSSTextureUAV;
OutStrataUniformParameters.OpaqueRoughRefractionTextureUAV = StrataSceneData->OpaqueRoughRefractionTextureUAV;
}
else
{
FRDGTextureRef DummyWritableSSSTexture = GraphBuilder.CreateTexture(FRDGTextureDesc::Create2D(FIntPoint(1, 1), PF_R32_UINT, FClearValueBinding::None, TexCreate_ShaderResource | TexCreate_UAV), TEXT("Strata.DummyWritableTexture"));
FRDGTextureUAVRef DummyWritableSSSTextureUAV = GraphBuilder.CreateUAV(FRDGTextureUAVDesc(DummyWritableSSSTexture));
FRDGTextureRef DummyWritableRefracTexture = GraphBuilder.CreateTexture(FRDGTextureDesc::Create2D(FIntPoint(1, 1), PF_R8, FClearValueBinding::None, TexCreate_ShaderResource | TexCreate_UAV), TEXT("Strata.DummyWritableTexture"));
FRDGTextureUAVRef DummyWritableRefracTextureUAV = GraphBuilder.CreateUAV(FRDGTextureUAVDesc(DummyWritableRefracTexture));
@@ -421,8 +415,8 @@ void BindStrataBasePassUniformParameters(FRDGBuilder& GraphBuilder, const FViewI
OutStrataUniformParameters.MaxBytesPerPixel = 0;
OutStrataUniformParameters.PeelLayersAboveDepth = 0;
OutStrataUniformParameters.SliceStoringDebugStrataTree = -1;
OutStrataUniformParameters.FirstSliceStoringStrataSSSDataWithoutMRT = -1;
OutStrataUniformParameters.MaterialTextureArrayUAVWithoutRTs = DummyWritableTextureArrayUAV;
OutStrataUniformParameters.SSSTextureUAV = DummyWritableSSSTextureUAV;
OutStrataUniformParameters.OpaqueRoughRefractionTextureUAV = DummyWritableRefracTextureUAV;
}
}
@@ -436,6 +430,7 @@ static void BindStrataGlobalUniformParameters(FRDGBuilder& GraphBuilder, FStrata
OutStrataUniformParameters.MaxBytesPerPixel = StrataSceneData->MaxBytesPerPixel;
OutStrataUniformParameters.PeelLayersAboveDepth = StrataSceneData->PeelLayersAboveDepth;
OutStrataUniformParameters.SliceStoringDebugStrataTree = StrataSceneData->SliceStoringDebugStrataTree;
OutStrataUniformParameters.FirstSliceStoringStrataSSSData = StrataSceneData->FirstSliceStoringStrataSSSData;
OutStrataUniformParameters.TileSize = STRATA_TILE_SIZE;
OutStrataUniformParameters.TileSizeLog2 = STRATA_TILE_SIZE_DIV_AS_SHIFT;
OutStrataUniformParameters.TileCount = StrataViewData->TileCount;
@@ -444,7 +439,6 @@ static void BindStrataGlobalUniformParameters(FRDGBuilder& GraphBuilder, FStrata
OutStrataUniformParameters.OverflowTileOffset = StrataViewData->OverflowTileOffset;
OutStrataUniformParameters.MaterialTextureArray = StrataSceneData->MaterialTextureArray;
OutStrataUniformParameters.TopLayerTexture = StrataSceneData->TopLayerTexture;
OutStrataUniformParameters.SSSTexture = StrataSceneData->SSSTexture;
OutStrataUniformParameters.OpaqueRoughRefractionTexture = StrataSceneData->OpaqueRoughRefractionTexture;
OutStrataUniformParameters.BSDFTileTexture = StrataViewData->BSDFTileTexture;
OutStrataUniformParameters.BSDFOffsetTexture = StrataSceneData->BSDFOffsetTexture;
@@ -468,6 +462,7 @@ static void BindStrataGlobalUniformParameters(FRDGBuilder& GraphBuilder, FStrata
OutStrataUniformParameters.MaxBytesPerPixel = 0;
OutStrataUniformParameters.PeelLayersAboveDepth = 0;
OutStrataUniformParameters.SliceStoringDebugStrataTree = -1;
OutStrataUniformParameters.FirstSliceStoringStrataSSSData = -1;
OutStrataUniformParameters.TileSize = 0;
OutStrataUniformParameters.TileSizeLog2 = 0;
OutStrataUniformParameters.TileCount = 0;
@@ -476,7 +471,6 @@ static void BindStrataGlobalUniformParameters(FRDGBuilder& GraphBuilder, FStrata
OutStrataUniformParameters.OverflowTileOffset = 0;
OutStrataUniformParameters.MaterialTextureArray = DefaultTextureArray;
OutStrataUniformParameters.TopLayerTexture = SystemTextures.DefaultNormal8Bit;
OutStrataUniformParameters.SSSTexture = SystemTextures.Black;
OutStrataUniformParameters.OpaqueRoughRefractionTexture = SystemTextures.Black;
OutStrataUniformParameters.BSDFTileTexture = SystemTextures.Black;
OutStrataUniformParameters.BSDFOffsetTexture = SystemTextures.Black;
@@ -582,20 +576,19 @@ class FStrataMaterialTileClassificationPassCS : public FGlobalShader
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, ViewUniformBuffer)
SHADER_PARAMETER(int32, FirstSliceStoringStrataSSSData)
SHADER_PARAMETER(int32, bRectPrimitive)
SHADER_PARAMETER(FIntPoint, ViewResolution)
SHADER_PARAMETER(uint32, MaxBytesPerPixel)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, TopLayerTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, TopLayerCmaskTexture)
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2DArray<uint>, MaterialTextureArray)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, TileDrawIndirectDataBuffer)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, SimpleTileListDataBuffer)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, SingleTileListDataBuffer)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, ComplexTileListDataBuffer)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, OpaqueRoughRefractionTileListDataBuffer)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, SSSWithoutOpaqueRoughRefractionTileListDataBuffer)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<uint>, MaterialHeaderTextureUAV)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2DArray<uint>, SSSTextureUAV)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2DArray<uint>, MaterialTextureArrayUAV)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D<float3>, OpaqueRoughRefractionTexture)
END_SHADER_PARAMETER_STRUCT()
@@ -1035,11 +1028,10 @@ void AddStrataMaterialClassificationPass(FRDGBuilder& GraphBuilder, const FMinim
PassParameters->bRectPrimitive = GRHISupportsRectTopology ? 1 : 0;
PassParameters->ViewResolution = View.ViewRect.Size();
PassParameters->MaxBytesPerPixel = StrataSceneData->MaxBytesPerPixel;
PassParameters->FirstSliceStoringStrataSSSData = StrataSceneData->FirstSliceStoringStrataSSSData;
PassParameters->TopLayerTexture = StrataSceneData->TopLayerTexture;
PassParameters->TopLayerCmaskTexture = TopLayerCmaskTexture;
PassParameters->MaterialTextureArray = StrataSceneData->MaterialTextureArraySRV;
PassParameters->MaterialHeaderTextureUAV = GraphBuilder.CreateUAV(FRDGTextureUAVDesc(StrataSceneData->MaterialTextureArray, 0, PF_R32_UINT, 0, 1));
PassParameters->SSSTextureUAV = StrataSceneData->SSSTextureUAV;
PassParameters->MaterialTextureArrayUAV = StrataSceneData->MaterialTextureArrayUAV;
PassParameters->OpaqueRoughRefractionTexture = StrataSceneData->OpaqueRoughRefractionTexture;
PassParameters->TileDrawIndirectDataBuffer = StrataViewData->ClassificationTileDrawIndirectBufferUAV;
PassParameters->SimpleTileListDataBuffer = StrataViewData->ClassificationTileListBufferUAV[EStrataTileType::ESimple];

View File

@@ -22,8 +22,8 @@ BEGIN_SHADER_PARAMETER_STRUCT(FStrataBasePassUniformParameters, )
SHADER_PARAMETER(uint32, bRoughDiffuse)
SHADER_PARAMETER(uint32, PeelLayersAboveDepth)
SHADER_PARAMETER(int32, SliceStoringDebugStrataTree)
SHADER_PARAMETER(int32, FirstSliceStoringStrataSSSDataWithoutMRT)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2DArray<uint>, MaterialTextureArrayUAVWithoutRTs)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2DArray<uint>, SSSTextureUAV)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float3>, OpaqueRoughRefractionTextureUAV)
END_SHADER_PARAMETER_STRUCT()
@@ -47,6 +47,7 @@ BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FStrataGlobalUniformParameters, RENDERER_AP
SHADER_PARAMETER(uint32, bRoughDiffuse)
SHADER_PARAMETER(uint32, PeelLayersAboveDepth)
SHADER_PARAMETER(int32, SliceStoringDebugStrataTree)
SHADER_PARAMETER(int32, FirstSliceStoringStrataSSSData)
SHADER_PARAMETER(uint32, TileSize)
SHADER_PARAMETER(uint32, TileSizeLog2)
SHADER_PARAMETER(FIntPoint, TileCount)
@@ -55,7 +56,6 @@ BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FStrataGlobalUniformParameters, RENDERER_AP
SHADER_PARAMETER(FIntPoint, OverflowTileOffset)
SHADER_PARAMETER_RDG_TEXTURE(Texture2DArray<uint>, MaterialTextureArray)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D<uint>, TopLayerTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2DArray<uint>, SSSTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D<float3>, OpaqueRoughRefractionTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D<uint>, BSDFOffsetTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D<uint>, BSDFTileTexture)
@@ -80,7 +80,10 @@ struct FStrataSceneData
uint32 MaxBytesPerPixel;
bool bRoughDiffuse;
int32 PeelLayersAboveDepth;
int32 SliceStoringDebugStrataTree;
int32 FirstSliceStoringStrataSSSDataWithoutMRT;
int32 FirstSliceStoringStrataSSSData;
// Resources allocated and updated each frame
@@ -90,11 +93,9 @@ struct FStrataSceneData
FRDGTextureSRVRef MaterialTextureArraySRV = nullptr;
FRDGTextureRef TopLayerTexture = nullptr;
FRDGTextureRef SSSTexture = nullptr;
FRDGTextureRef OpaqueRoughRefractionTexture = nullptr;
FRDGTextureUAVRef TopLayerTextureUAV = nullptr;
FRDGTextureUAVRef SSSTextureUAV = nullptr;
FRDGTextureUAVRef OpaqueRoughRefractionTextureUAV = nullptr;
FRDGTextureRef BSDFOffsetTexture = nullptr;