IrisShaders / Iris

A modern shaders mod for Minecraft compatible with existing OptiFine shader packs
https://irisshaders.dev
GNU Lesser General Public License v3.0
3.31k stars 625 forks source link

JVM crashes when BlockEntityRenderer tries to render a model with >50000 vertices #2435

Closed vlad250906 closed 1 week ago

vlad250906 commented 1 month ago

Minecraft Version

1.21

Iris Version

iris-1.7.3+mc1.21

Sodium Version

sodium-fabric-0.5.11+mc1.21

Operating System

Windows 10

What is your GPU?

NVIDIA GeForce GTX 1070

Java Version

Java 21

Reproduction Steps

1) Install/write a mod that has BlockEntityRenderer rendering a model with a bunch of vertices. Example:

public class CustomBlockEntityRenderer implements BlockEntityRenderer<CustomBlockEntity>{

    public CustomBlockEntityRenderer(BlockEntityRendererFactory.Context con) {

    }

    @Override
    public void render(CustomBlockEntity entity, float tickDelta, MatrixStack matrices,
            VertexConsumerProvider vertexConsumers, int light, int overlay) {

        VertexConsumer cons = vertexConsumers.getBuffer(RenderLayer.getBlockLayers().get(0));
        Matrix4f matrix4f = matrices.peek().getPositionMatrix();// 20

        for(int i=0;i<50000;i++) {
            cons.vertex(matrix4f, 0.0f + i * 0.1f, 0.0f + i * 0.1f, 0.0f + i * 0.1f).color(1, 0, 0, 0).texture(0, 0).overlay(0).light(0).normal(0, 1, 0);
            cons.vertex(matrix4f, 1.0f + i * 0.1f, 0.0f + i * 0.1f, 0.0f + i * 0.1f).color(0, 1, 0, 0).texture(1, 0).overlay(1).light(0).normal(0, 1, 0);
            cons.vertex(matrix4f, 0.0f + i * 0.1f, 1.0f + i * 0.1f, 1.0f + i * 0.1f).color(0, 0, 1, 0).texture(0, 1).overlay(0).light(1).normal(0, 1, 0);
            cons.vertex(matrix4f, 1.0f + i * 0.1f, 1.0f + i * 0.1f, 1.0f + i * 0.1f).color(1, 0, 1, 0).texture(1, 1).overlay(1).light(1).normal(0, 1, 0);
        }

    }

}

2) Launch the game and enter any world (I will use super-flat void world). 3) Use any shaderpack (any will work; I used Iris-Example-Shaderpack-master). 4) Spam-place custom block created 5) JVM crashes

Without Iris (or if shaders are disabled) all is OK.

https://github.com/user-attachments/assets/63078db7-6a99-4012-9ac4-67c93e86e436

Crash Report file and latest.log

(the file is too huge: 141 kb)
https://github.com/user-attachments/files/16482973/hs_err_pid23976.log

Additional context

hs_err_pid23976.log latest.log

The problem is probably caused by MixinBufferBuilder::fillExtendedData not handling ByteBufferBuilder growth (ByteBufferBuilder::resize) correctly. iris$beforeNext saves direct memory pointers in vertexPointers and calls fillExtendedData to change quad data. But if too many vertices are being added to BufferBuilder, ByteBufferBuilder will have to expand and double its size, reallocating itself to a new address. And now there are some addresses in vertexPointers pointing to the old freed buffer and some pointing to the new one. MemoryUtil.memPutFloat call will crash the JVM.

I wrote custom mixins for ByteBufferBuilder and BufferBuilder to catch EXCEPTION_ACCESS_VIOLATION before the JVM crashes (it checks that all addresses used in MemoryUtil.memPutFloat and MemoryUtil.memPutInt are pointing to buffer)

//                                        testmod$beforeNext is HEAD inject to BufferBuilder::endVertex
[02:13:55][Render thread/INFO](Minecraft) testmod$beforeNext: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; vertexCount = 39852; begincurrentAddressess = 22d6fdf0bc0; currentAddress = 22d6ffeaa7c; endAddress = 22d6ffeabc0; capacity = 2072576
[02:13:55][Render thread/INFO](Minecraft) testmod$beforeNext: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; vertexCount = 39853; begincurrentAddressess = 22d6fdf0bc0; currentAddress = 22d6ffeaab0; endAddress = 22d6ffeabc0; capacity = 2072576
[02:13:55][Render thread/INFO](Minecraft) testmod$beforeNext: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; vertexCount = 39854; begincurrentAddressess = 22d6fdf0bc0; currentAddress = 22d6ffeaae4; endAddress = 22d6ffeabc0; capacity = 2072576
[02:13:55][Render thread/INFO](Minecraft) testmod$beforeNext: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; vertexCount = 39855; begincurrentAddressess = 22d6fdf0bc0; currentAddress = 22d6ffeab18; endAddress = 22d6ffeabc0; capacity = 2072576

//                                        testmod$fillExtendedData is INVOKE inject to iris/.../MixinBufferBuilder::fillExtendedData; target = "Lnet/irisshaders/iris/vertices/BufferBuilderPolygonView;setup([JII)V"
[02:13:55][Render thread/INFO](Minecraft) testmod$fillExtendedData: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; begincurrentAddressess = 22d6fdf0bc0

[02:13:55][Render thread/INFO](Minecraft) testmod$beforeNext: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; vertexCount = 39856; begincurrentAddressess = 22d6fdf0bc0; currentAddress = 22d6ffeab4c; endAddress = 22d6ffeabc0; capacity = 2072576
[02:13:55][Render thread/INFO](Minecraft) testmod$beforeNext: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; vertexCount = 39857; begincurrentAddressess = 22d6fdf0bc0; currentAddress = 22d6ffeab80; endAddress = 22d6ffeabc0; capacity = 2072576

//                                        testmod$grow is TAIL inject to ByteBufferBuilder::resize
[02:13:55][Render thread/INFO](Minecraft) testmod$grow: this = net.minecraft.client.util.BufferAllocator@4c553ae3; newPointer = 22d087e0300

[02:13:55][Render thread/INFO](Minecraft) testmod$beforeNext: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; vertexCount = 39858; begincurrentAddressess = 22d087e0300; currentAddress = 22d089da2f4; endAddress = 22d08bd4300; capacity = 4145152
[02:13:55][Render thread/INFO](Minecraft) testmod$beforeNext: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; vertexCount = 39859; begincurrentAddressess = 22d087e0300; currentAddress = 22d089da328; endAddress = 22d08bd4300; capacity = 4145152
[02:13:55][Render thread/INFO](Minecraft) testmod$fillExtendedData: this = net.minecraft.client.render.BufferBuilder@74e015b7; allocator = net.minecraft.client.util.BufferAllocator@4c553ae3; begincurrentAddressess = 22d087e0300
[02:13:55][Render thread/WARN](WmiQueryHandler) COM exception: Invalid Query: SELECT PERCENTUSAGE FROM Win32_PerfRawData_PerfOS_PagingFile
[02:13:55][Render thread/ERROR](Minecraft) Reported exception thrown!
    net.minecraft.util.crash.CrashException: Rendering Block Entity
    at net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher.runReported(BlockEntityRenderDispatcher.java:111) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher.render(BlockEntityRenderDispatcher.java:79) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer.renderBlockEntity(SodiumWorldRenderer.java:368) ~[sodium-mc1.21-0.5.11.jar:?]
    at me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer.redirect$zja000$iris$addToList(SodiumWorldRenderer.java:584) ~[sodium-mc1.21-0.5.11.jar:?]
    at me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer.renderBlockEntities(SodiumWorldRenderer.java:307) ~[sodium-mc1.21-0.5.11.jar:?]
    at me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer.renderBlockEntities(SodiumWorldRenderer.java:270) ~[sodium-mc1.21-0.5.11.jar:?]
    at net.minecraft.client.render.WorldRenderer.handler$znd000$sodium$onRenderBlockEntities(WorldRenderer.java:8827) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.WorldRenderer.render(WorldRenderer.java:1119) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.GameRenderer.renderWorld(GameRenderer.java:1087) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.GameRenderer.render(GameRenderer.java:850) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.MinecraftClient.render(MinecraftClient.java:1285) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.MinecraftClient.run(MinecraftClient.java:882) [minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.main.Main.main(Main.java:256) [minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:480) [fabric-loader-0.16.0.jar:?]
    at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74) [fabric-loader-0.16.0.jar:?]
    at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23) [fabric-loader-0.16.0.jar:?]
    at net.fabricmc.devlaunchinjector.Main.main(Main.java:86) [dev-launch-injector-0.2.1+build.8.jar:?]

Caused by: java.lang.IllegalStateException: EXCEPTION_ACCESS_VIOLATION: beginAddress = 22d087e0300; currentAddress = 22d6ffeaba4; endAddress = 22d08bd4300; capacity = 4145152; message = <type = Polygon 1; vertexAmount = 4; realVerticesAmount = 39860; vertexPointers = [22d6ffeab80; 22d089da2f4; 22d089da328; 22d089da35c; ]; midTexOffset = 36; tangentOffset = 44; normalOffset = 28>

    at net.minecraft.client.render.BufferBuilder.assertcurrentAddressess(BufferBuilder.java:3101) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.BufferBuilder.redirect$bdc000$modid$testmod$fillExtendedData(BufferBuilder.java:3086) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.BufferBuilder.fillExtendedData(BufferBuilder.java:1205) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.BufferBuilder.handler$zhd000$iris$beforeNext(BufferBuilder.java:1177) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.BufferBuilder.endVertex(BufferBuilder.java) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.BufferBuilder.begincurrentAddressessVertex(BufferBuilder.java:96) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.BufferBuilder.vertex(BufferBuilder.java:156) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.VertexConsumer.vertex(VertexConsumer.java:532) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at com.example.CustomBlockEntityRenderer.render(CustomBlockEntityRenderer.java:29) ~[client/:?]
    at com.example.CustomBlockEntityRenderer.render(CustomBlockEntityRenderer.java:1) ~[client/:?]
    at net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher.render(BlockEntityRenderDispatcher.java:90) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher.method_23081(BlockEntityRenderDispatcher.java:79) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    at net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher.runReported(BlockEntityRenderDispatcher.java:104) ~[minecraft-clientOnly-47f089f66a-1.21-net.fabricmc.yarn.1_21.1.21+build.2-v2.jar:?]
    ... 16 more
[02:13:56][Server thread/INFO](Minecraft) Stopping server

vertexPointers = [22d6ffeab80; 22d089da2f4; 22d089da328; 22d089da35c;] Vertex 0 is pointing to an old freed buffer with capacity 2072576 Vertex 1,2 and 3 are pointing to a new buffer with capacity 4145152

Mod used to crash Iris + Mixins: https://github.com/vlad250906/iris-crash-test Shaderpack used: https://github.com/IrisShaders/Iris-Example-Shaderpack

IMS212 commented 1 month ago

I cannot reproduce this crash on my machine; I'll look into it more. Your assumption seems right at first glance...

FruitClown commented 1 month ago

I get the same, I think it's because of the Better Dogs resource pack in my case (I don't get the crashes after disabling the pack, and it adds a whole lot of vertices) hs_err_pid26640.log

IMS212 commented 1 week ago

Has this been fixed with Iris 1.8 beta 3?

vlad250906 commented 1 week ago

Yes, in 1.8.0-beta.3+mc1.21.1 the bug is gone. Thanks!