Files
UnrealEngineUWP/Engine/Shaders/Private/ComputeGenerateMips.usf
eric mcdaniel 502749c59a Fix for async compute on platforms with memory boundary restrictions on async compute dispatch indirect arguments
*** This change will incur a full shader invalidation across all platforms ***

Issues:
  - Some platforms require async compute dispatch indirect arguments to not cross specific memory boundaries
    - This places restrictions on the valid sizes for a dispatch indirect argument set.  We were not conforming to these restrictions which could result in GPU crashes on these async passes

Fixes:
  - FRHIDispatchIndirectParameters is padded out to meet per-platform memory boundary restrictions
    - This is driven via new per-platform preprocessor define PLATFORM_DISPATCH_INDIRECT_ARGUMENT_BOUNDARY_SIZE
    - Some platforms require FRHIDispatchIndirectParameters to align with their internal structure hence we cannot universally size to meet all platform's requirements

  - Introduce new FRHIDispatchIndirectParametersNoPadding for uses when we explicitly do not want the padding and otherwise avoid the memory boundary restrictions

  - Revise and expand indirect argument validation code to catch further such issues in the future

  - Update shaders which write to dispatch indirect argument buffers to account for optional per-platform padding
    - New utility function WriteDispatchIndirectArgs introduced to faciliate this
    - platforms which require other than the default nonpadded dispatch indirect arguments must define DISPATCH_INDIRECT_UINT_COUNT and their own WriteDispatchIndirectArgs in their CommonPlatform.ush

  - move creation of DispatchIndirectGraphicsCommandSignature command signature to be per-platform
    - DispatchIndirectGraphicsCommandSignature and DispatchIndirectComputeCommandSignature stride changed to account for additional padding on impacted platforms

Testing:
  - ran Lyra with and without async compute Lumen on impacted platforms as well as Win64
  - ran FN replay on impacted platforms

#rb Krzysztof.Narkowicz, Ben.Woodhouse, Benjamin.Rouveyrol
#jira UE-167950
#preflight 6359563b2e6690262a11bc06

[CL 22862498 by eric mcdaniel in ue5-main branch]
2022-10-31 10:15:11 -04:00

93 lines
2.4 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
/*==================================================================================================
GenericGenerateMips.usf: Standard code for generating mips via the compute shader in realtime
===================================================================================================*/
#pragma once
#include "Common.ush"
#include "GammaCorrectionCommon.ush"
Texture2D MipInSRV;
SamplerState MipSampler;
#if GENMIPS_COMPUTE
float2 TexelSize;
#if GENMIPS_SRGB
RWTexture2D<half4> MipOutUAV;
#else
RWTexture2D<float4> MipOutUAV;
#endif
[numthreads(8, 8, 1)]
void MainCS(uint3 DT_ID : SV_DispatchThreadID)
{
float2 UV = TexelSize * (DT_ID.xy + 0.5f);
#if GENMIPS_SRGB
half4 outColor = MipInSRV.SampleLevel(MipSampler, UV, 0);
outColor = half4(LinearToSrgb(outColor.xyz), outColor.w);
#else
float4 outColor = MipInSRV.SampleLevel(MipSampler, UV, 0);
#endif
#if GENMIPS_SWIZZLE
MipOutUAV[DT_ID.xy] = outColor.zyxw;
#else
MipOutUAV[DT_ID.xy] = outColor;
#endif
}
uint2 TextureSize;
uint Offset;
uint NumMips;
Buffer<uint> ConditionBuffer;
RWBuffer<uint> RWIndirectDispatchArgsBuffer;
[numthreads(8,1,1)]
void BuildIndirectDispatchArgsCS(uint DT_ID : SV_DispatchThreadID)
{
if (DT_ID < NumMips)
{
uint Condition = ConditionBuffer[Offset];
// Generate mipmaps only when Condition > 0
const bool bShouldDispatchGenerateMips = (Condition > 0);
if (bShouldDispatchGenerateMips)
{
uint2 DestTextureSize = uint2(
max(TextureSize.x >> (DT_ID + 1u), 1u),
max(TextureSize.y >> (DT_ID + 1u), 1u));
DestTextureSize = (DestTextureSize + 8 - 1) / 8;
WriteDispatchIndirectArgs(RWIndirectDispatchArgsBuffer, DT_ID, DestTextureSize.x, DestTextureSize.y, 1);
}
else
{
WriteDispatchIndirectArgs(RWIndirectDispatchArgsBuffer, DT_ID, 0, 0, 0);
}
}
}
#else // !GENMIPS_COMPUTE
float2 HalfTexelSize;
float Level;
void MainVS(in float4 InPosition : ATTRIBUTE0, in float2 InUV : ATTRIBUTE1, out float4 OutPosition : SV_POSITION, out float2 OutUV : TEXCOORD0)
{
OutPosition = InPosition;
OutPosition.xy = -1.0f + 2.0f * InPosition.xy;
OutPosition.xy *= float2( 1, -1 );
OutUV = InUV;
}
void MainPS(float4 InPosition : SV_POSITION, float2 InUV : TEXCOORD0, out float4 OutColor : SV_Target0)
{
OutColor = MipInSRV.SampleLevel(MipSampler, InUV + HalfTexelSize, Level);
}
#endif // GENMIPS_COMPUTE