From e27b68cc9b765d2bfa71dfd1e6cbc1fa4166789c Mon Sep 17 00:00:00 2001 From: Sebastien Hillaire Date: Mon, 29 Aug 2022 02:55:17 -0400 Subject: [PATCH] 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] --- .../Shaders/Private/BasePassPixelShader.usf | 4 +- .../Private/DistanceFieldShadowing.usf | 2 +- .../Shaders/Private/Lumen/LumenMaterial.ush | 4 +- .../Shaders/Private/PostProcessSubsurface.usf | 4 +- .../RayTracing/RayTracingOcclusionRGS.usf | 2 +- .../Private/ShadowProjectionPixelShader.usf | 4 +- Engine/Shaders/Private/Strata/Strata.ush | 41 ++++++++++++------ .../Strata/StrataMaterialClassification.usf | 29 +++++-------- .../Private/Strata/StrataVisualize.usf | 8 ++-- .../VirtualShadowMapProjection.usf | 2 +- .../VirtualShadowMapTransmissionCommon.ush | 2 +- Engine/Shaders/Shared/StrataDefinitions.h | 2 + .../Renderer/Private/Strata/Strata.cpp | 42 ++++++++----------- .../Runtime/Renderer/Private/Strata/Strata.h | 9 ++-- 14 files changed, 80 insertions(+), 75 deletions(-) diff --git a/Engine/Shaders/Private/BasePassPixelShader.usf b/Engine/Shaders/Private/BasePassPixelShader.usf index b937cbc6f5f0..1176893dec4c 100644 --- a/Engine/Shaders/Private/BasePassPixelShader.usf +++ b/Engine/Shaders/Private/BasePassPixelShader.usf @@ -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); } } diff --git a/Engine/Shaders/Private/DistanceFieldShadowing.usf b/Engine/Shaders/Private/DistanceFieldShadowing.usf index 3896814fa2ff..af48834337f5 100644 --- a/Engine/Shaders/Private/DistanceFieldShadowing.usf +++ b/Engine/Shaders/Private/DistanceFieldShadowing.usf @@ -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)) { diff --git a/Engine/Shaders/Private/Lumen/LumenMaterial.ush b/Engine/Shaders/Private/Lumen/LumenMaterial.ush index 9efab30936c0..2d8150cb1140 100644 --- a/Engine/Shaders/Private/Lumen/LumenMaterial.ush +++ b/Engine/Shaders/Private/Lumen/LumenMaterial.ush @@ -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); diff --git a/Engine/Shaders/Private/PostProcessSubsurface.usf b/Engine/Shaders/Private/PostProcessSubsurface.usf index 731ba47790cf..df3b917ffbf7 100644 --- a/Engine/Shaders/Private/PostProcessSubsurface.usf +++ b/Engine/Shaders/Private/PostProcessSubsurface.usf @@ -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 diff --git a/Engine/Shaders/Private/RayTracing/RayTracingOcclusionRGS.usf b/Engine/Shaders/Private/RayTracing/RayTracingOcclusionRGS.usf index 1231a92db501..a35b0ea3ac72 100644 --- a/Engine/Shaders/Private/RayTracing/RayTracingOcclusionRGS.usf +++ b/Engine/Shaders/Private/RayTracing/RayTracingOcclusionRGS.usf @@ -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); diff --git a/Engine/Shaders/Private/ShadowProjectionPixelShader.usf b/Engine/Shaders/Private/ShadowProjectionPixelShader.usf index e2fc8b1e73b0..48fd6c5c092d 100644 --- a/Engine/Shaders/Private/ShadowProjectionPixelShader.usf +++ b/Engine/Shaders/Private/ShadowProjectionPixelShader.usf @@ -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; diff --git a/Engine/Shaders/Private/Strata/Strata.ush b/Engine/Shaders/Private/Strata/Strata.ush index 90639e62e702..d6b4eaa3e570 100644 --- a/Engine/Shaders/Private/Strata/Strata.ush +++ b/Engine/Shaders/Private/Strata/Strata.ush @@ -874,26 +874,35 @@ struct FStrataSubsurfaceData FStrataSubsurfaceHeader Header; FStrataSubsurfaceExtras Extras; }; -FStrataSubsurfaceHeader StrataLoadSubsurfaceHeader(Texture2DArray SSSTexture, uint2 PixelPos) +FStrataSubsurfaceHeader StrataLoadSubsurfaceHeader(Texture2DArray 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 SSSTexture, uint2 PixelPos) +FStrataSubsurfaceExtras StrataLoadSubsurfaceExtras(Texture2DArray 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 SSSTexture, uint2 PixelPos) +FStrataSubsurfaceData StrataLoadSubsurfaceData(Texture2DArray 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 StrataBuffer, uint FirstSliceStoringStrataSSSData, uint2 PixelPos, uint HeaderBytes) +{ + StrataBuffer[uint3(PixelPos, FirstSliceStoringStrataSSSData + 0)] = HeaderBytes; +} +void StrataStoreSubsurfaceExtras(RWTexture2DArray 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; diff --git a/Engine/Shaders/Private/Strata/StrataMaterialClassification.usf b/Engine/Shaders/Private/Strata/StrataMaterialClassification.usf index 3ea616c0c832..3a3d6e291dd7 100644 --- a/Engine/Shaders/Private/Strata/StrataMaterialClassification.usf +++ b/Engine/Shaders/Private/Strata/StrataMaterialClassification.usf @@ -15,13 +15,12 @@ int bRectPrimitive; int2 ViewResolution; uint MaxBytesPerPixel; +int FirstSliceStoringStrataSSSData; Texture2D TopLayerTexture; #if PERMUTATION_CMASK Texture2D TopLayerCmaskTexture; -RWTexture2D MaterialHeaderTextureUAV; -#else -Texture2DArray MaterialTextureArray; #endif +RWTexture2DArray MaterialTextureArrayUAV; // Indirect draw data buffer for all tile types RWBuffer TileDrawIndirectDataBuffer; @@ -40,8 +39,6 @@ Texture2D OpaqueRoughRefractionTexture; groupshared uint s_TileFlags[GROUP_THREAD_COUNT]; #endif -RWTexture2DArray 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 diff --git a/Engine/Shaders/Private/Strata/StrataVisualize.usf b/Engine/Shaders/Private/Strata/StrataVisualize.usf index b479fa1c5524..ac25e58a8be1 100644 --- a/Engine/Shaders/Private/Strata/StrataVisualize.usf +++ b/Engine/Shaders/Private/Strata/StrataVisualize.usf @@ -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 diff --git a/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapProjection.usf b/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapProjection.usf index f1a80be8ff5d..31dd3a3b72e4 100644 --- a/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapProjection.usf +++ b/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapProjection.usf @@ -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; diff --git a/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapTransmissionCommon.ush b/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapTransmissionCommon.ush index f0e94396f7e4..26ad178e95c0 100644 --- a/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapTransmissionCommon.ush +++ b/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapTransmissionCommon.ush @@ -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); diff --git a/Engine/Shaders/Shared/StrataDefinitions.h b/Engine/Shaders/Shared/StrataDefinitions.h index adbb23f82d3e..38f41d25aa7f 100644 --- a/Engine/Shaders/Shared/StrataDefinitions.h +++ b/Engine/Shaders/Shared/StrataDefinitions.h @@ -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 diff --git a/Engine/Source/Runtime/Renderer/Private/Strata/Strata.cpp b/Engine/Source/Runtime/Renderer/Private/Strata/Strata.cpp index f44e3d51befa..0f762a0c7505 100644 --- a/Engine/Source/Runtime/Renderer/Private/Strata/Strata.cpp +++ b/Engine/Source/Runtime/Renderer/Private/Strata/Strata.cpp @@ -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, 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, MaterialHeaderTextureUAV) - SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2DArray, SSSTextureUAV) + SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2DArray, MaterialTextureArrayUAV) SHADER_PARAMETER_RDG_TEXTURE(Texture2D, 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]; diff --git a/Engine/Source/Runtime/Renderer/Private/Strata/Strata.h b/Engine/Source/Runtime/Renderer/Private/Strata/Strata.h index 93f4ac488843..869a66f94930 100644 --- a/Engine/Source/Runtime/Renderer/Private/Strata/Strata.h +++ b/Engine/Source/Runtime/Renderer/Private/Strata/Strata.h @@ -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, MaterialTextureArrayUAVWithoutRTs) - SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2DArray, SSSTextureUAV) SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, 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, MaterialTextureArray) SHADER_PARAMETER_RDG_TEXTURE(Texture2D, TopLayerTexture) - SHADER_PARAMETER_RDG_TEXTURE(Texture2DArray, SSSTexture) SHADER_PARAMETER_RDG_TEXTURE(Texture2D, OpaqueRoughRefractionTexture) SHADER_PARAMETER_RDG_TEXTURE(Texture2D, BSDFOffsetTexture) SHADER_PARAMETER_RDG_TEXTURE(Texture2D, 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;