We recently observed an issue where a Modified & Dependencies cook process would crash in DumpShaderTypeStats because “const FShaderType* ShaderType = FindShaderTypeByName(HashedName);” would occasionally be nullptr which would crash the KeySort a few lines down.
I’m not 100% sure of the root cause of the null shadertype, but I’m highly suspicious of the fact that we recently upgraded FSR to the latest 5.6-compatible version (v4.0.3a) which modified a bunch of plugin shaders. Fortunately/unfortunately, the error went away by doing a full cook instead and is no longer reproducible, so we don’t currently need a workaround (if we ever see it again, we can just modify DumpShaderTypeStats to add null check before adding the null shader to the array). I just wanted to bring this to Epic’s attention in case this was something that had been observed before internally, since I didn’t see any other occurrences of it posted in EPS. Perhaps this is an oversight in how Modified & Dependencies tracks shader changes (in plugins)?
[Attachment Removed]
Hi,
Thanks for reporting. I took a look at the code in 5.8 and the issue probably got raised because the code was modified to handle the null pointer. At null check was added along with some diagnostics logs. You could pick up the new code if you want.
//UE5/Release-5.8/Engine/Source/Runtime/RenderCore/Private/ShaderLibrary/ShaderCodeLibrary.cpp:1984
if (const FShaderType* ShaderType = FindShaderTypeByName(FHashedName(Pair.Key)))
{
CountersByTypeName.Add(ShaderType, Pair.Value);
}
else
{
// This error needs to be suppressed for data used by ShaderMaps or Shaders
// that are not referenced by any assets that have bReferencedByStaging.
TArray<FName> AssetNames;
bool bReferencedbyStaging = IsShaderTypeReferencedByStaging(PlatformId, Pair.Key,
&AssetNames, 1 /* MaxNumAssetNames */);
if (bReferencedbyStaging)
{
FString CookStatus = TEXT("It is unknown whether this asset was incrementally skipped in the current cook.");
if (!AssetNames.IsEmpty())
{
bool bImplemented = false;
bool bReferenced = false;
bool bRecooked = false;
GetCookStatus(AssetNames[0], bImplemented, bReferenced, bRecooked);
if (bImplemented)
{
if (!bReferenced)
{
CookStatus = TEXT("This asset was not referenced in the current cook; ")
TEXT("there is a Cooker bug that reported it to the ShaderCodeLibrary as referenced by staging.");
}
else if (bRecooked)
{
CookStatus = TEXT("This asset was referenced and recooked in the current cook; ")
TEXT("there is a Cooker or ShaderCodeLibrary bug that failed to remove its now-stale previously cooked shader that uses the removed or renamed ShaderType.");
}
else
{
CookStatus = TEXT("This asset was referenced but was incrementally skipped in the current cook; ")
TEXT("the change that removed or renamed the ShaderType is missing a version bump that triggers the recook of the asset.");
}
}
}
checkf(false,
TEXT("Shader library contains a reference to an FShaderType with hash %" UINT64_FMT " which does not exist.\n")
TEXT("Removed or renamed ShaderTypes are supposed to be impossible to stage; recooks should not be able ")
TEXT("to reference them and incremental cooks are supposed to recook assets that use them.\n")
TEXT("This shadertype however is referenced by an asset which is being staged: \"%s\". %s"),
Pair.Key, AssetNames.IsEmpty() ? TEXT("<Unknown>") : *AssetNames[0].ToString(), *CookStatus);
}
}
Regards,
Patrick
[Attachment Removed]
Excellent, we may backport that change just in case we ever encounter it again. Thanks.
[Attachment Removed]