ValidateUniformBuffer Crash

This Question relates to:

[Content removed]

Was there ever an actionable or CL generated from this? We’re also experiencing this exact issue.

Thanks,

Brenden

Hello,

It doesn’t look like any issue was created. Is this something you can reproduce in a sample project for us to look into? The callstack looks similar to this public issue Unreal Engine Issues and Bug Tracker (UE\-269068)

I was hoping given some information others had revealed on this issue that a change had been generated whether by the user or by epic.

I haven’t found any related fixes for this issue but I’m basing it off the callstack alone:

[Inlined] ValidateBoundUniformBuffer(FD3D12UniformBuffer *, FRHIShader *, unsigned int) D3D12Commands.cpp:59 BindUniformBuffer(FD3D12CommandContext &, FRHIShader *, EShaderFrequency, unsigned int, FD3D12UniformBuffer *) D3D12Commands.cpp:73 SetShaderParametersOnContext(FD3D12CommandContext &, FRHIShader *, EShaderFrequency, TArrayView<…>, TArrayView<…>, TArrayView<…>, TArrayView<…>) D3D12Commands.cpp:1107 FD3D12CommandContext::RHISetShaderParameters(FRHIComputeShader *, TArrayView<…>, TArrayView<…>, TArrayView<…>, TArrayView<…>) D3D12Commands.cpp:1143 FRHICommandSetShaderParameters::Execute(FRHICommandListBase &) RHICommandListCommandExecutes.inl:128 [Inlined] FCpuProfilerTrace::FEventScope::BeginEventCommon(unsigned int &, const wchar_t *, const char *, unsigned int) CpuProfilerTrace.h:193 [Inlined] FCpuProfilerTrace::FEventScope::{ctor}(unsigned int &,const wchar_t *,const UE::Trace::FChannel &,bool,const char *,unsigned int) CpuProfilerTrace.h:153 FRHICommand::ExecuteAndDestruct(FRHICommandListBase &, FRHICommandListDebugContext &) RHICommandList.h:1289 FRHICommandListBase::Execute(TRHIPipelineArray<…> &, FRHICommandListBase::FPersistentState::FGPUStats *) RHICommandList.cpp:465 FRHICommandListImmediate::QueueAsyncCommandListSubmit’::27'::<lambda_2>::operator()() RHICommandList.cpp:611 [Inlined] UE::Core::Private::Function::TFunctionRefBase::operator()() Function.h:555 [Inlined] TFunctionGraphTaskImpl::DoTaskImpl(TUniqueFunction<…> &, Type, const TRefCountPtr<…> &) TaskGraphInterfaces.h:1733 [Inlined] TFunctionGraphTaskImpl::DoTask(Type, const TRefCountPtr<…> &) TaskGraphInterfaces.h:1726 TGraphTask::ExecuteTask(TArray<…> &, Type, bool) TaskGraphInterfaces.h:1235 [Inlined] FBaseGraphTask::Execute(TArray<…> &, Type, bool) TaskGraphInterfaces.h:840 [Inlined] FTaskGraphCompatibilityImplementation::QueueTask::__l5::<lambda_1>::operator()() TaskGraph.cpp:1970 LowLevelTasks::FTask::Init<FTaskGraphCompatibilityImplementation::QueueTask'::5’::<lambda_1> >‘::13'::<lambda_1>::operator()(const bool) Task.h:499 [Inlined] Invoke(LowLevelTasks::FTask::<lambda_1> &, bool &) Invoke.h:47 [Inlined] LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<LowLevelTasks::FTask::Init<FTaskGraphCompatibilityImplementation::QueueTask'::5’::<lambda_1> >‘::13'::<lambda_1>,0>::Call(void *,bool) TaskDelegate.h:162 LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<LowLevelTasks::FTask::Init<FTaskGraphCompatibilityImplementation::QueueTask'::5’::<lambda_1> >‘::13'::<lambda_1>,0>::CallAndMove(LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48> &,void *,unsigned int,bool) TaskDelegate.h:171 [Inlined] LowLevelTasks::TTaskDelegate::CallAndMove(LowLevelTasks::TTaskDelegate<…> &, bool) TaskDelegate.h:308 LowLevelTasks::FTask::ExecuteTask() Task.h:627 [Inlined] FCpuProfilerTrace::FEventScope::BeginEventCommon(unsigned int &, const char *, const char *, unsigned int) CpuProfilerTrace.h:181 [Inlined] FCpuProfilerTrace::FEventScope::{ctor}(unsigned int &,const char *,bool,const char *,unsigned int) CpuProfilerTrace.h:135 LowLevelTasks::FScheduler::ExecuteTask(LowLevelTasks::FTask *) Scheduler.cpp:154 [Inlined] LowLevelTasks::FScheduler::TryExecuteTaskFrom(LowLevelTasks::Private::FWaitEvent *, LowLevelTasks::Private::TLocalQueueRegistry<…>::TLocalQueue *, LowLevelTasks::Private::FOutOfWork &, bool) Scheduler.cpp:362 LowLevelTasks::FScheduler::WorkerMain(LowLevelTasks::Private::FWaitEvent *, LowLevelTasks::Private::TLocalQueueRegistry<…>::TLocalQueue *, unsigned int, bool) Scheduler.cpp:397 [Inlined] LowLevelTasks::FScheduler::CreateWorker::__l2::<lambda_1>::operator()() Scheduler.cpp:70 [Inlined] Invoke(<lambda_1> &) Invoke.h:47 UE::Core::Private::Function::TFunctionRefCaller<LowLevelTasks::FScheduler::CreateWorker’::2'::<lambda_1>,void __cdecl(void)>::Call(void *) Function.h:405 [Inlined] UE::Core::Private::Function::TFunctionRefBase::operator()() Function.h:555 FThreadImpl::Run() Thread.cpp:66 FRunnableThreadWin::Run() WindowsRunnableThread.cpp:146 FRunnableThreadWin::GuardedRun() WindowsRunnableThread.cpp:71If you can repro this on a developer machine you can enable -rhivalidation which may reveal more information. It’s also possible your logs may provide more information about the related Material and shader.

I spent a week tracking this down and have some info that will hopefully help future wanderers

In our case the original post [Content removed] did have the answer but was a bit lost in translation due to the language barrier. They also didn’t provide any real technique for running the problem down.

If two Material Parameter Collection assets share the same StateId GUID the engine can end up GCing one MPC and therefore take with it a Uniform Buffer resource used by draws referencing a different MPC.

To run this down I recommend running with -onethread -forcerhibypass -rdgimmediate and trying to find *which* MPC asset’s uniform buffer is getting GCed. Going up the stack from the crash we found that the Nanite rendering pass was the source of the crash and we were able to find the MaterialRenderProxy of the material instance relevant to the offending draw. Finding the FGuid of the used MPC and then triggering a break in UMaterialParameterCollection::PostLoad with something like:

```

if(StateId == FGuid(“{what-ever-guid-id}”)

{

__debugbreak();

}

```

Helped to pinpoint which MPCs had colliding guids. In our case they were MPCs with the same name but living in different directories; presumably one was a copy of the other and the StateID was never updated. In this case since the MPCs were dupe we removed one and replaced all references with the other.

Does the engine need to generated a different StateID when an MPC asset is duplicated?

Hi there, it sounds like there are two remaining questions here:

  1. Does the engine need to generate a different StateID when an MPC asset is duplicated?
  2. When you have duplicate named MPCs or MPCs with colliding GUIDs, how can you rename or delete them and redirect existing references.

I’m directing this issue to my colleague who is more familiar with this system to provide some guidance here, but if you can provide some more details about what happens when you try to rename the MPCs with redirecting references, that might be some kind of bug we can address.

Hi Brenden,

Apologies for the delay in response on this, this issue just got rerouted to me. I already have a jira for this issue logged from the Fortnite team. I’ve converted it to a UE bug and marked it for a public tracker for you:

Unreal Engine Issues and Bug Tracker (UE\-295255) (may not be immediately visible as it needs the DevRel team to approve it).

I will be addressing it asap in the next few weeks, please bear with me and keep an eye on the tracker in the meantime.

Thanks,

Jon

Hi Brenden,

Oh why thank you for the kind words! I actually moved teams internally from DevRel support over to full time rendering on the materials team, hence I am less frequent in responding to UDNs unless it’s related to something I’ve worked on.

Ok thank you for highlighting the workaround, that genuinely might help me find a solution as perhaps it’s a loading/residency issue with the MPCs not being tied directly as a dependency for the material.

Thanks,

Jon

Unfortunately it reproduces just enough to be a problem for us but without any clear reproduction. I was hoping given some information others had revealed on this issue that a change had been generated whether by the user or by epic.

The callstack does look like the one you pointed out, though the crash for us is always within a packaged build.

We tried doing this but unfortunately have run into a crash: [Content removed]

We do have some duplicate named MPC’s but have unfortunately been unable to rename, or delete them while redirecting references, it may be because they don’t use the new HLSL generator and have to use the Translate_Legacy path.

In our case, I think this issue was caused from importing multiple paragon assets which were each packaged with the same MPC and likely share that StateID. So even generating a different StateID when duplicating might not be enough here since the act of duplication isn’t actually occurring. It’s possible a duplication event already is accurately handling a duplicate StateID and this is just an edgecase that bypasses it.

Yes, question 2 is causing us troubles. We have not been successful in renaming the MPCs because we get another crash when doing so. I made a separate ticket for that issue here:

[Content removed]

Jon Cain, It’s nice to hear from you. You used to answer a lot of UDN tickets about a decade ago and your input has been sorely missed!

I have found a bit of a workaround in the interim, which is noted in this ticket: [Content removed]

Thanks,

Brenden