RaphiMC / ImmediatelyFast

Speed up immediate mode rendering in Minecraft
https://modrinth.com/mod/immediatelyfast
GNU Lesser General Public License v3.0
288 stars 21 forks source link

[1.20.6] MixinVertexBuffer.checkForDrawCallWhileBatching not working as intended? #263

Closed thexaero closed 1 month ago

thexaero commented 1 month ago

I've been trying to make my HUD mods not conflict with this mod's hud batching and I think I've discovered a bug that may be causing the majority of the problems. I am not entirely sure on this, so I apologize if I'm wrong. It seems to me like MixinVertexBuffer.checkForDrawCallWhileBatching is missing a call to reupload the correct buffer data after force-rendering the "batching buffers" (which uploads other buffer data to the same VBO/IBO), causing the buffer that triggered forceDrawBuffers to not render correctly afterwards because the VBO/IBO are now missing the correct data. Or perhaps forceDrawBuffers should be called before the original buffer data upload in the BufferUploader class (or whatever it's called in yarn mappings). Not sure if any modders use the VertexBuffer class directly though.

RaphiMC commented 1 month ago

Thanks for reporting the issue. What are the steps to reproduce that issue?

thexaero commented 1 month ago

Sure. Here's a way to test it I just came up with.

Between a BatchingBuffers.beginHudBatching() and a BatchingBuffers.endHudBatching(), with guiGraphics being the DrawContext instance, run the following code:

RenderSystem.setShader(GameRenderer::getPositionColorShader);
Tesselator tessellator = Tesselator.getInstance();
BufferBuilder vertexBuffer = tessellator.getBuilder();
Matrix4f matrix = guiGraphics.pose().last().pose();

vertexBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
vertexBuffer.vertex(matrix, 0, 100, 0).color(255, 0, 0, 255).endVertex();
vertexBuffer.vertex(matrix, 100, 100, 0).color(255, 0, 0, 255).endVertex();
vertexBuffer.vertex(matrix, 100, 0, 0).color(255, 0, 0, 255).endVertex();
vertexBuffer.vertex(matrix, 0, 0, 0).color(255, 0, 0, 255).endVertex();
tessellator.end();

guiGraphics.fill(110, 0, 210, 100, 0xFF00FF00);

vertexBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
vertexBuffer.vertex(matrix, 220, 100, 0).color(0, 0, 255, 255).endVertex();
vertexBuffer.vertex(matrix, 320, 100, 0).color(0, 0, 255, 255).endVertex();
vertexBuffer.vertex(matrix, 320, 0, 0).color(0, 0, 255, 255).endVertex();
vertexBuffer.vertex(matrix, 220, 0, 0).color(0, 0, 255, 255).endVertex();
tessellator.end();

vertexBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
vertexBuffer.vertex(matrix, 330, 100, 0).color(0, 255, 255, 255).endVertex();
vertexBuffer.vertex(matrix, 430, 100, 0).color(0, 255, 255, 255).endVertex();
vertexBuffer.vertex(matrix, 430, 0, 0).color(0, 255, 255, 255).endVertex();
vertexBuffer.vertex(matrix, 330, 0, 0).color(0, 255, 255, 255).endVertex();
tessellator.end();

I'm using the official mappings, but you should be able to translate it easily. The code should render 4 squares, a red, a green, a blue and a cyan one. The first one is rendered directly and works correctly if BatchingBuffers has no data yet, the second one uses the DrawContext and uses the hud batching, the third one is supposed to trigger forceDrawBuffers and then render normally, but it doesn't render. The last one renders fine again because BatchingBuffers is empty again.

RaphiMC commented 1 month ago

Thanks for reporting the issue and providing example code. This is now fixed in the latest snapshot builds.

thexaero commented 1 month ago

Awesome, thank you!