You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
The top layer texture had a unecessary UAV flag preventing to create cmask metadata. #rb none #jira none [FYI] sebastien.hillaire #ROBOMERGE-AUTHOR: charles.derousiers #ROBOMERGE-SOURCE: CL 18396739 in //UE5/Release-5.0/... via CL 18396754 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469) [CL 18396760 by charles derousiers in ue5-release-engine-test branch]
268 lines
9.2 KiB
Plaintext
268 lines
9.2 KiB
Plaintext
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "/Engine/Private/Common.ush"
|
|
|
|
#define STRATA_INLINE_SHADING 0
|
|
#define STRATA_SSS_MATERIAL_OVERRIDE 0
|
|
#include "/Engine/Private/Strata/Strata.ush"
|
|
|
|
#define TILE_SIZE 8
|
|
#define GROUP_THREAD_COUNT (TILE_SIZE*TILE_SIZE)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
uint EncodeTile(uint2 TileCoord)
|
|
{
|
|
return TileCoord.x | (TileCoord.y << 16); // assumes 16bit is enough to represent a tiled resolution up to 65,535 :)
|
|
}
|
|
|
|
uint2 DecodeTile(uint In)
|
|
{
|
|
return uint2(In & 0xFFFF, In >> 16);
|
|
}
|
|
|
|
#if SHADER_TILE_CATEGORIZATION
|
|
int TileSize;
|
|
int bRectPrimitive;
|
|
int2 ViewResolution;
|
|
uint MaxBytesPerPixel;
|
|
Texture2D<uint> TopLayerTexture;
|
|
Texture2DArray<uint> MaterialTextureArray;
|
|
RWBuffer<uint> SimpleTileIndirectDataBuffer;
|
|
RWBuffer<uint> SimpleTileListDataBuffer;
|
|
RWBuffer<uint> ComplexTileIndirectDataBuffer;
|
|
RWBuffer<uint> ComplexTileListDataBuffer;
|
|
|
|
#if !PERMUTATION_WAVE_OPS
|
|
groupshared uint s_IsComplexIsMaterialTile[GROUP_THREAD_COUNT];
|
|
#endif
|
|
|
|
#if PERMUTATION_STRATA_CLEAR_DURING_CATEGORIZATION
|
|
RWTexture2D<uint2> SSSTextureUAV;
|
|
#endif
|
|
|
|
[numthreads(TILE_SIZE, TILE_SIZE, 1)]
|
|
void TileMainCS(uint2 DispatchThreadId : SV_DispatchThreadID, uint LinearIndex : SV_GroupIndex, uint3 GroupId : SV_GroupID)
|
|
{
|
|
if (all(DispatchThreadId == 0))
|
|
{
|
|
SimpleTileIndirectDataBuffer[0] = bRectPrimitive > 0 ? 4 : 6;
|
|
ComplexTileIndirectDataBuffer[0] = bRectPrimitive > 0 ? 4 : 6;
|
|
}
|
|
|
|
// TODO: add a SM6 permutation with ballot?
|
|
const uint2 PixelCoord = DispatchThreadId;
|
|
|
|
// Pixels outside of the view area are considered simple to enable screen borders to receive the simple permutation when not aligned to shader group size.
|
|
bool bContainsComplexMaterial = false;
|
|
bool bContainsStrataMaterial = false;
|
|
bool bHasScreenSpaceSubsurfaceScattering = false;
|
|
if (all(PixelCoord < uint2(ViewResolution)))
|
|
{
|
|
FStrataAddressing StrataAddressing = GetStrataPixelDataByteOffset(PixelCoord, uint2(View.BufferSizeAndInvSize.xy), MaxBytesPerPixel);
|
|
FStrataPixelHeader StrataPixelHeader = UnpackStrataHeaderIn(MaterialTextureArray, 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
|
|
bContainsStrataMaterial = StrataPixelHeader.BSDFCount > 0;
|
|
bContainsComplexMaterial = !bIsSimple;
|
|
bHasScreenSpaceSubsurfaceScattering = HasSubsurface(StrataPixelHeader);
|
|
}
|
|
|
|
#if PERMUTATION_STRATA_CLEAR_DURING_CATEGORIZATION
|
|
BRANCH
|
|
if (!bHasScreenSpaceSubsurfaceScattering)
|
|
{
|
|
// We must fill all the pixel which doe not hav subsurface scattering with default so that the SSS code is not executed where it should not.
|
|
FStrataSubsurfaceData StrataSubsurfaceData = (FStrataSubsurfaceData)0;
|
|
SSSTextureUAV[DispatchThreadId.xy] = StrataPackSSSData(StrataSubsurfaceData);
|
|
}
|
|
#endif
|
|
|
|
#if PERMUTATION_WAVE_OPS
|
|
|
|
const bool bHasAnyStrata = WaveActiveAnyTrue(bContainsStrataMaterial);
|
|
const bool bHasAnyComplex = WaveActiveAnyTrue(bContainsComplexMaterial);
|
|
|
|
if (LinearIndex < 1 && bHasAnyStrata)
|
|
{
|
|
if (bHasAnyComplex)
|
|
{
|
|
uint WriteToIndex;
|
|
InterlockedAdd(ComplexTileIndirectDataBuffer[1], 1, WriteToIndex);
|
|
ComplexTileListDataBuffer[WriteToIndex] = EncodeTile(GroupId.xy);
|
|
}
|
|
else
|
|
{
|
|
uint WriteToIndex;
|
|
InterlockedAdd(SimpleTileIndirectDataBuffer[1], 1, WriteToIndex);
|
|
SimpleTileListDataBuffer[WriteToIndex] = EncodeTile(GroupId.xy);
|
|
}
|
|
}
|
|
|
|
#else // PERMUTATION_WAVE_OPS
|
|
|
|
s_IsComplexIsMaterialTile[LinearIndex] = (bContainsComplexMaterial ? 1 : 0) | (bContainsStrataMaterial ? 2 : 0);
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
if (LinearIndex < 32)
|
|
{
|
|
s_IsComplexIsMaterialTile[LinearIndex] = s_IsComplexIsMaterialTile[LinearIndex] | s_IsComplexIsMaterialTile[LinearIndex + 32];
|
|
}
|
|
GroupMemoryBarrierWithGroupSync();
|
|
if (LinearIndex < 16)
|
|
{
|
|
s_IsComplexIsMaterialTile[LinearIndex] = s_IsComplexIsMaterialTile[LinearIndex] | s_IsComplexIsMaterialTile[LinearIndex + 16];
|
|
}
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
if (LinearIndex < 8)
|
|
{
|
|
s_IsComplexIsMaterialTile[LinearIndex] = s_IsComplexIsMaterialTile[LinearIndex] | s_IsComplexIsMaterialTile[LinearIndex + 8];
|
|
}
|
|
GroupMemoryBarrierWithGroupSync();
|
|
if (LinearIndex < 4)
|
|
{
|
|
s_IsComplexIsMaterialTile[LinearIndex] = s_IsComplexIsMaterialTile[LinearIndex] | s_IsComplexIsMaterialTile[LinearIndex + 4];
|
|
}
|
|
GroupMemoryBarrierWithGroupSync();
|
|
if (LinearIndex < 2)
|
|
{
|
|
s_IsComplexIsMaterialTile[LinearIndex] = s_IsComplexIsMaterialTile[LinearIndex] | s_IsComplexIsMaterialTile[LinearIndex + 2];
|
|
}
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
const uint FinalIsSimpleIsMaterialTile = s_IsComplexIsMaterialTile[LinearIndex] | s_IsComplexIsMaterialTile[LinearIndex + 1];
|
|
bContainsComplexMaterial = (FinalIsSimpleIsMaterialTile & 1) > 0;
|
|
bContainsStrataMaterial = (FinalIsSimpleIsMaterialTile & 2) > 0;
|
|
|
|
if (LinearIndex < 1 && bContainsStrataMaterial)
|
|
{
|
|
if (bContainsComplexMaterial)
|
|
{
|
|
uint WriteToIndex;
|
|
InterlockedAdd(ComplexTileIndirectDataBuffer[1], 1, WriteToIndex);
|
|
ComplexTileListDataBuffer[WriteToIndex] = EncodeTile(GroupId.xy);
|
|
}
|
|
else
|
|
{
|
|
uint WriteToIndex;
|
|
InterlockedAdd(SimpleTileIndirectDataBuffer[1], 1, WriteToIndex);
|
|
SimpleTileListDataBuffer[WriteToIndex] = EncodeTile(GroupId.xy);
|
|
}
|
|
}
|
|
#endif // PERMUTATION_WAVE_OPS
|
|
}
|
|
#endif // SHADER_TILE_CATEGORIZATION
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if SHADER_STENCIL_CATEGORIZATION
|
|
|
|
float4 OutputViewSizeAndInvSize;
|
|
float4 OutputBufferSizeAndInvSize;
|
|
float4x4 ViewScreenToTranslatedWorld;
|
|
Buffer<uint> TileListBuffer;
|
|
float4 DebugTileColor;
|
|
|
|
void StrataTilePassVS(
|
|
in uint InVertexId : SV_VertexID,
|
|
in uint InInstanceId : SV_InstanceID,
|
|
#if PERMUTATION_ENABLE_TEXCOORD_SCREENVECTOR
|
|
out float2 OutTexCoord : TEXCOORD0, // Used by DeferredLightPixelMain directional light
|
|
out float3 OutScreenVector : TEXCOORD1, // Used by DeferredLightPixelMain directional light
|
|
#endif
|
|
#if PERMUTATION_ENABLE_DEBUG
|
|
out uint2 OutTileCoord : TILE_COORD, // Used by StencilMainPS below
|
|
#endif
|
|
out float4 OutPosition : SV_POSITION) // Use by StencilMainPS
|
|
{
|
|
const uint2 TileCoord = DecodeTile(TileListBuffer[InInstanceId]);
|
|
|
|
uint2 TileVertex = TileCoord * TILE_SIZE;
|
|
TileVertex.x += InVertexId == 1 || InVertexId == 2 || InVertexId == 4 ? TILE_SIZE : 0;
|
|
TileVertex.y += InVertexId == 2 || InVertexId == 4 || InVertexId == 5 ? TILE_SIZE : 0;
|
|
|
|
OutPosition = float4(float2(TileVertex) * OutputViewSizeAndInvSize.zw * float2(2.0f, -2.0f) + float2(-1.0, 1.0f), 0.5f, 1.0f);
|
|
|
|
#if PERMUTATION_ENABLE_TEXCOORD_SCREENVECTOR
|
|
OutTexCoord = float2(TileVertex) * OutputBufferSizeAndInvSize.zw;
|
|
OutScreenVector = mul(float4(OutPosition.xy, 1, 0), ViewScreenToTranslatedWorld).xyz;
|
|
#endif
|
|
|
|
#if PERMUTATION_ENABLE_DEBUG
|
|
OutTileCoord = TileCoord;
|
|
#endif
|
|
}
|
|
|
|
void StencilMainPS(
|
|
in uint2 InTileCoord : TILE_COORD,
|
|
in float4 SVPos : SV_POSITION,
|
|
out float4 OutColor0 : SV_Target0)
|
|
{
|
|
const bool bTileX = (InTileCoord.x & 1) == 0;
|
|
const bool bTileY = (InTileCoord.y & 1) == 0;
|
|
const bool bChecker = (bTileX && bTileY) || (!bTileX && !bTileY);
|
|
OutColor0 = DebugTileColor * float4(1.0f, 1.0f, 1.0f, bChecker ? 0.33f : 0.66f);
|
|
OutColor0.rgb *= OutColor0.a; // premultiplied alpha blending assuming alpha is opacity==coverage
|
|
}
|
|
|
|
#endif //SHADER_STENCIL_CATEGORIZATION
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if SHADER_CLEAR_MATERIAL_BUFFER
|
|
|
|
RWTexture2DArray<uint> MaterialTextureArrayUAV;
|
|
RWTexture2D<uint2> SSSTextureUAV;
|
|
uint MaxBytesPerPixel;
|
|
int2 TiledViewBufferResolution;
|
|
|
|
[numthreads(8, 8, 1)]
|
|
void ClearMaterialBufferMainCS(uint2 DispatchThreadId : SV_DispatchThreadID)
|
|
{
|
|
if (any(int2(DispatchThreadId.xy) >= TiledViewBufferResolution))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Custom clear of the Strata material buffer.
|
|
// The first layer of tiled uints contains the header that we need to clear so we only write a single uint per pixel instead of clearing the entire buffer which would be too slow.
|
|
|
|
FStrataPixelHeader StrataHeader = InitialiseStrataPixelHeader();
|
|
uint BSDFCount = 0;
|
|
uint PackedStrataHeader = PackStrataHeader(BSDFCount, StrataHeader);
|
|
|
|
const uint FirstSlice = 0;
|
|
MaterialTextureArrayUAV[uint3(DispatchThreadId.xy, FirstSlice)] = PackedStrataHeader;
|
|
|
|
FStrataSubsurfaceData StrataSubsurfaceData = (FStrataSubsurfaceData)0;
|
|
SSSTextureUAV[DispatchThreadId.xy] = StrataPackSSSData(StrataSubsurfaceData);
|
|
}
|
|
|
|
#endif // SHADER_CLEAR_MATERIAL_BUFFER
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if SHADER_POST_BASEPASS
|
|
|
|
Texture2DArray<uint> MaterialTextureArrayMRTs;
|
|
RWTexture2DArray<uint> MaterialTextureArrayUAV;
|
|
|
|
[numthreads(8, 8, 1)]
|
|
void PostBasePassCS(uint2 DispatchThreadId : SV_DispatchThreadID)
|
|
{
|
|
if (any(int2(DispatchThreadId.xy) >= View.ViewSizeAndInvSize.xy))
|
|
{
|
|
return;
|
|
}
|
|
|
|
int3 CoordData0 = int3(View.ViewRectMin.xy + DispatchThreadId.xy, 0);
|
|
int3 CoordData1 = int3(View.ViewRectMin.xy + DispatchThreadId.xy, 1);
|
|
|
|
MaterialTextureArrayUAV[CoordData0] = MaterialTextureArrayMRTs[CoordData0];
|
|
MaterialTextureArrayUAV[CoordData1] = MaterialTextureArrayMRTs[CoordData1];
|
|
}
|
|
|
|
#endif // SHADER_POST_BASEPASS
|
|
|