PCGWorldPartitionBuilder crash trying to load big landscape chunk

Hello,

we want to run PCGWorldPartitionBuilder commandlet nightly to update all the proceduraly placed content in the world. But when we’re running said commandlet we keep running into the memory crash. We have very big world and trying to load whole map at once always results in OOM. To fight this, we’re running commandlet in an IterativeCell mode. However at some point we keep crashing because of giant texture it tries to load when loading landscape:

LogD3D12RHI: Error: Driver crashed while creating texture: 16384x16384x32 DXGI_FORMAT_R8_UNORM(0x0000003d) with 1 mips

Callstack is in attachment.

Is there a way to bypass this issue? And could it be a case that when we’re loading next cell, GC doesn’t clean up memory from previous one? Because when we look at memory stats in logs, we’re using a lot.

Here’s the command we’re running currently:

.\Engine\Binaries\Win64\UnrealEditor-Cmd.exe Project “/Game/MAP/L_MainMap” -Unattended -AllowCommandletRendering -run=WorldPartitionBuilderCommandlet -Builder=PCGWorldPartitionBuilder -IgnoreGenerationErrors=true -GenerateComponentEditingModeNormal=true -AssetGatherAll -IncludeGraphNames=PCG_Biome; -IterativeCellLoading -IterativeCellSize=500000

[Attachment Removed]

Steps to Reproduce[Attachment Removed]

Hi Yegor!

I’ve reassigned your question to Patrick in the team that’s most knowledgeable about our commandlet, but some early questions that arise:

  • Do you have something that is using the landscape textures?
  • Do you need to run with AllowCommandletRendering?

Cheers,

Julien

[Attachment Removed]

Hi Yegor,

The iterative cell mode is what you would want to use indeed in a large world.

A couple of things to note about the iterative cell mode:

  • The cell will be adjusted to fit the loading bounds of the intersecting PCG Partition Actors so you can expect more data to be loaded than the actual cell size
  • GC happens after Cell has been processed in UWorldPartitionBuilder::Run when FWorldPartitionHelpers::ShouldCollectGarbage(), you might want to take a look see if you are hitting this consistently.

Could you give me the details on your Landscape setup? (Nb of proxies, size of components, streamable or not, etc etc)

I might add someone from the Landscape team to look into it as it seems like the issue might not lie with PCG directly here.

Cheers,

Patrick

[Attachment Removed]

Hello, sorry for taking long to answer, been crazy past couple of weeks. I’ve managed to get the commandlet barely working by putting it very small cell size, but then it might take 24h to run across the map. I’ve even split the job into 2 separate ones to at least generate some of pcg faster, but even small deviation starts to go OOM.

Regarding “AllowCommandletRendering” flag we have to run with it, since WorldPartitionBuilder can’t run without it.

“Do you have something that is using the landscape textures?” - nothing that I know of. Landscape itself. We do have a 4 landscape edit layers though.

As for Landscape setup - we have 334 Proxies which are 511x511 cell size. They’re are all streamable, we have 4 landscape edit layers. Non-nanite yet

[Attachment Removed]

Hi Yegor,

The crash occurs because in the editor, landscape edit layers are active and they will merge when requested. In UE5.5, the merge process requires a bunch of temporary render targets that are sized to the size of the landscape that is currently loaded (“global merge”). If you have a resolution of 16k x 16k, that’s likely because the loaded landscape proxies cover an area of 16k x 16k. Please check the loaded proxies while executing the commandlet and verify what resolution is needed. It is generally advised to aim for a maximum area of 4k x 4k (you can check the computed resolution in ALandscape::CreateLayersRenderingResource when the merge algorithm runs).

In UE5.6, a new merge algorithm has been officially introduced : batched merge (you can also activate it in UE5.5 with the CVar landscape.EditLayersLocalMerge.Enable 2, but it only became the default in UE5.6 so it’s possible you will encounter some bugs unless you switch to UE5.6 or, even better, UE5.7, where the old code path has been removed entirely). Batched merge tries to circumvent these OOM issues by splitting the renderable area of the merge into smaller batches, and merging the landscape batch by batch. This way, you can load a much larger region of landscape and not go OOM while using edit layers.

That being said, there are some factors that can influence the landscape proxies that need to be loaded. On a standard landscape, only the loaded region’s size will matter, which means that using iterative cell mode, only the landscape proxies intersected by the cell should be loaded. However, if you are using BP brushes (such as the Water Brush) on one of the edit layers, we then force-load all proxies of the landscape, meaning that even if your cell intersects only a couple of proxies, all proxies will still end up being loaded (but in the editor only). That is because we don’t have control over what BP brushes are doing so we don’t know what region of landscape they require in order to be applied in a deterministic way. The water brush, for example, requires to be applied on the entire landscape because of the way it is computed internally. As a result, whenever a BP brush is used, we force-load all proxies, meaning that if the overall landscape is very large, then no matter the region size you’re trying to load, it will end up updating the entire landscape and is likely to go OOM. Are you guys using BP brushes?

Please note that this remains true even with batched merge. We’re slowly moving away from BP brushes for this reason (although they will remain usable, but with the same loading constraints) and the water brush will be converted to a dedicated water edit layer to circumvent that problem.

If you want to disable the edit layer merge altogether, there’s also a hidden boolean you can set on the main ALandscape actor : bEnableEditorLayersTick. It will bypass the merge entirely. It comes with no strings attached, though : it’s not exposed to BP or even C++ because of it. It’s not well-tested, so it’s possible it will create bugs later down the line. But if nothing in your commandlet requires the edit layers algorithm to run (this could happen if ForceLayersFullUpdate was called, for example), then it might be a way to avoid going OOM by bypassing the landscape edit layer system altogether (please note that if the landscape proxies are not up-to-date, then you might end up with PCG instances being spawned at the wrong location, for example).

Can you have a look at these and let us know if you have more questions? If so, please provide the full log.

Cheers,

Jonathan

[Attachment Removed]