Mutable crashes when building textures

As far as I can tell the crash is caused by UpdateLayoutBlockDesc latching a 2x2 block with a 4k texture and calculating a BlockPixelX and BlockPixelY to be 2048 and then a second block comes through the loop at 11x4 (or something like that) and the expected texture size grows too big.

From the output log:

Fatal error: [File:E:\p4\dante\Engine\Source\Runtime\Core\Private\Containers\ContainerHelpers.cpp] [Line: 8]

Trying to resize TArray to an invalid size of 3623878656

A breakpoint instruction (__debugbreak() statement or a similar call) was executed in UnrealEditor.exe.

This is from CodeGenerator.cpp line 3091

					// Block in layout grid units
					box< FIntVector2 > RectInCells;
					RectInCells.min = ExtendLayout->Blocks[BlockIndex].Min;
					RectInCells.size = ExtendLayout->Blocks[BlockIndex].Size;

					FImageDesc ExtendDesc = FragmentOp->GetImageDesc();

					// If we don't know the size of a layout block in pixels, calculate it
					UpdateLayoutBlockDesc(InOutLayoutBlockDesc, ExtendDesc, RectInCells.size);

					// Adjust the format and size of the block to be added
					// Actually don't do it, it will be propagated from the top format operation.
					//FragmentOp = GenerateImageFormat(FragmentOp, FinalImageFormat);

					UE::Math::TIntVector2<int32> ExpectedSize;
					ExpectedSize[0] = InOutLayoutBlockDesc.BlockPixelsX * RectInCells.size[0];
					ExpectedSize[1] = InOutLayoutBlockDesc.BlockPixelsY * RectInCells.size[1];
					FragmentOp = GenerateImageSize(FragmentOp, ExpectedSize);


Fatal error: [File:E:\p4\dante\Engine\Source\Runtime\Core\Private\Containers\ContainerHelpers.cpp] [Line: 8] 
Trying to resize TArray to an invalid size of 3623878656
A breakpoint instruction (__debugbreak() statement or a similar call) was executed in UnrealEditor.exe.

A breakpoint instruction (__debugbreak() statement or a similar call) was executed in UnrealEditor.exe.



[Attachment Removed]

Steps to Reproduce
Have a look at the plugin I sent. It’s all assets at this point. So you could either import the assets themselves into Unreal or change the paths in the plugin so it can be built and added to the project.

Then open CO_Party_Body that is in the Plugin’s content folder under the folder DevMutable. Just let it compile and it crashes.

I’ve also included a diff showing that we changed the default texture group to a project based one with a 4k texture size.

[Attachment Removed]

Hi David Lee,

Thanks for reaching out. I tried to import the example content, but the COs appear to be serialized with an unknown custom version. Meshes and others import just fine.

Could it be that you cherry-picked a fix or added a custom version that modified the CO serialization? If so, could you tell which ones?

Regards,

Pere

[Attachment Removed]

Hi,

I made two changes to Mutable. I sent you the first and I thought I integrated the 2nd after I packed the assets. We also have changes to the engine. I tried migrating the assets to a vanilla version of 5.7.1 but the migration failed. I could undo all changes to Mutable and then resave the assets if you think that would solve the problem. However if having a modified engine causes the problem, I’m not sure how to best get you a working example.

[Attachment Removed]

This is the 2nd change. It’s a band-aid fix and generally leads to smaller output textures.

	void CodeGenerator::UpdateLayoutBlockDesc(CodeGenerator::FLayoutBlockDesc& Out, FImageDesc BlockDesc, FIntVector2 LayoutCellSize)
	{
#if 1 // SK_MOD leed6 adjust block size before generating images
		if (LayoutCellSize.X > 0 && LayoutCellSize.Y > 0)
		{
			Out.BlockPixelsX = Out.BlockPixelsX ? FMath::Min(Out.BlockPixelsX, BlockDesc.m_size[0] / LayoutCellSize[0]) : FMath::Max(1, BlockDesc.m_size[0] / LayoutCellSize[0]);
			Out.BlockPixelsY = Out.BlockPixelsY ? FMath::Min(Out.BlockPixelsY, BlockDesc.m_size[1] / LayoutCellSize[1]) : FMath::Max(1, BlockDesc.m_size[1] / LayoutCellSize[1]);
#else // SK_MOD
		if (Out.BlockPixelsX == 0 && LayoutCellSize.X > 0 && LayoutCellSize.Y > 0)
		{
			Out.BlockPixelsX = FMath::Max(1, BlockDesc.m_size[0] / LayoutCellSize[0]);
			Out.BlockPixelsY = FMath::Max(1, BlockDesc.m_size[1] / LayoutCellSize[1]);
#endif // SK_MOD
			Out.bBlocksHaveMips = BlockDesc.m_lods > 1;
 
			if (Out.FinalFormat==EImageFormat::None)
			{
				Out.FinalFormat = BlockDesc.m_format;
			}
		}
	};

[Attachment Removed]

I would appreciate it if you could remake the graph using the vanilla version of 5.7.1. Alternatively, you could simplify the graph as much as possible and send screenshots so I can copy the setup.

Note: It’s highly unlikely that undoing the code changes and resaving will work.

[Attachment Removed]

A quick update. I’ve recreated the graph in vanilla 5.7.1. However I’m having trouble getting it to replace textures now. I even recreated the node manually. It just ignores the color map parameter and no texture is allocated and set on the MID. I’ll keep poking at it and see if I can get it to work.

[Image Removed]

[Attachment Removed]

I’m sorry for not getting back to you sooner. I haven’t been able to reproduce it, but we know the cause to some extent and are preparing a fix, likely for 5.8.

[Attachment Removed]