Skip to content

[1.21] Using custom render layers in BLOCK_OUTLINE event causes crash #3939

Description

@SuperMartijn642

When a render type other than RenderLayer#LINES (and that does not have a fixed buffer) is used to render something in the WorldRenderEvents#BLOCK_OUTLINE event, this causes a crash.
To replicate the crash, simply add the following subsciber to the event:

WorldRenderEvents.BLOCK_OUTLINE.register((worldRenderContext, blockOutlineContext) -> {
    worldRenderContext.consumers().getBuffer(RenderLayer.getEndPortal());
    return true;
});

Here is a log of such a crash (although with mojmaps): https://gist.github.com/SuperMartijn642/2a6ba4977d6c172b01f2137d4f8dec30


The current flow for the WorldRenderEvents#BLOCK_OUTLINE is as follows:

  1. WorldRenderer#render requests a buffer for RenderLayer#LINES.
  2. WorldRenderer#render calls WorldRenderer#drawBlockOutline with the requested buffer.
  3. Fabric's WorldRendererMixin#onDrawBlockOutline mixin fires the WorldRenderEvents#BLOCK_OUTLINE.
  4. Fabric's WorldRendererMixin#onDrawBlockOutline mixin requests a buffer for RenderLayer#LINES.
  5. WorldRenderer#drawBlockOutline renders the block's outline with the buffer passed to it.

If a mod requests a buffer for a render type other than RenderLayer#LINES during the WorldRenderEvents#BLOCK_OUTLINE event, that causes the original buffer for RenderLayer#LINES to be ended. If simply left as is, this would cause a crash in step 5 when vertices are submitted to the original buffer.
To combat this, step 4 requests a buffer for RenderLayer#LINES again.

In 1.20.6, VertexConsumerProvider#Immediate simply held one buffer object which gets reset whenever the requested render type is different from the last. Hence, the buffer requested in step 1 would be reset by step 4.
In 1.21, VertexConsumerProvider#Immediate now creates a new BufferBuilder instance every time the requested render type is different from the last. Hence, the buffer requested in step 1 is never reset, rather step 4 causes a new BufferBuilder to be created. As step 5 still uses the buffer object requested in step 1, this leads to a crash.

The WorldRendererMixin#onDrawBlockOutline mixin for context:
https://github.com/FabricMC/fabric/blob/e43d74f64b242dfb86920343808cc6616bfb1441/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/WorldRendererMixin.java#L114-L131

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions