RHIinit() calls GRHICommandList.GetImmediateCommandList().GetContext() to make sure that GDynamicRHI->Init() initialized the immediate command list (by calling FRHICommandListImmediate::InitializeImmediateContexts()). This works in Debug and Development because the lambda enqueued by SwitchPipeline runs immediately, as Bypass() returns true before the RHI thread is started. However, in Test and Shipping Bypass() always returns false, so the switch pipelines command is enqueued rather than executed, and nothing sets up the contexts on the immediate command list.
However, checks are normally disabled in Test and Shipping, so the checkf() inside GetContext() doesn't fire. Two wrongs make a right in this case. :> When USE_CHECKS_IN_SHIPPING is 1, the check fires, and the engine crashes on startup.
Note that this doesn't happen in server builds because RHIInit takes a different path (it uses the null RHI and doesn't perform this check).
We either need to flush commands before calling GetContext(), or we need to find another way of ensuring that the dynamic RHI has called InitializeImmediateContexts().
Download the licensee repro from here:
Compile a Win64 test package of the project (either via the editor or buildcookrun etc)
Launch the test package. If using Visual Studio, launch Test/Win64/TestProjectUDN. Crash occurs on startup.
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-171275 in the post.