Hey,
So recently we enabled FastGeoStreaming and I’ve observed a crash when changing `r.MaterialQualityLevel` during the depth pre-pass, in a cooked build.
It occurs in ValidateUniformBuffer (does not occur when the plugin is disabled).
inline void ValidateBoundUniformBuffer(FD3D12UniformBuffer* InUniformBuffer, FRHIShader* InShaderRHI, uint32 InBufferIndex)
{
#if DO_CHECK
auto const& LayoutHashes = InShaderRHI->GetShaderResourceTable().ResourceTableLayoutHashes;
if (InBufferIndex < (uint32)LayoutHashes.Num())
{
uint32 UniformBufferHash = InUniformBuffer->GetLayout().GetHash(); <-------------- here
uint32 ShaderTableHash = LayoutHashes[InBufferIndex];
ensureMsgf(ShaderTableHash == 0 || UniformBufferHash == ShaderTableHash,
TEXT("Invalid uniform buffer %s bound on %sShader at index %d."),
*(InUniformBuffer->GetLayout().GetDebugName()),
GetShaderFrequencyString(InShaderRHI->GetFrequency(), false),
InBufferIndex);
}
#endif
}
The UB in question is the materials `Material` uniform buffer and is effectively pointing at the UB from before the quality level changed, which was since freed during:
FMaterialRenderProxy::InvalidateUniformExpressionCache(bool bRecreateUniformBuffer)
But re-allocated in:
FMaterialRenderProxy::EvaluateUniformExpressions(FRHICommandListBase& RHICmdList, FUniformExpressionCache& OutUniformExpressionCache, const FMaterialRenderContext& Context, FUniformExpressionCacheAsyncUpdater* Updater) const
I added some sketchy logging around `FMaterialShader::GetShaderBindings` to keep track of what pointer was currently stashed in `UniformExpressionCache.UniformBuffer`, using the callstack up until `FScene::Update()` as a way to book keep it and each pass appeared to have the most up to date uniform buffer pointer.
I was wondering if you had ever encountered something like this before / had tips on debugging it further?
Many thanks,
Alister