Hi,
For past couple of weeks I have been trying to solve high VRAM consumption ( 12+ gigabytes ) in Minecraft.
Its pretty obvious that there is a memory leak, as normally I wouldn't expect for the game to use anything more than 300-600 megabytes. I have tried using Radeon Dev Tool Suite, but it doesn't support OpenGL. I also wanted to use CodeXL, but its unable to hook into OpenGL ( Java loads OpenGL from System32, even if you put opengl32.dll next to javaw.exe ).
From doing a bunch of testing it seems that its caused by rapid re-rendering of OpenGL draw lists. For context - Minecraft uses draw lists ( prior to 1.12 ) to draw its game world, and because its a dynamic game it re-renders already-created lists when something is updated on the screen.
It seems highly related to https://gitlab.freedesktop.org/mesa/mesa/-/issues/6140, but that's Mesa driver and shouldn't affect Windows ( ??. This is my guess, I know that mesa has custom implementation of AMD GPU driver ).
I'm kind-of lost now, so developer forum seems to be the only place where I could look for help.
edit:
OS: Windows 10, Windows 11
GPU: RX 6900 XT, RX 580 8GB, RX 4xx series
Driver version: I have tested on 23.4.3 and 23.4.1 ( Adrenaline version, AMD Windows Driver Version 31.0.14051.5006, RX 6900 XT ), 31.0.14037.1007 ( RX 580, driver version )
STR ( in game ) : Startup Minecraft 1.7, Join any world in creative/with admin rights, press T to open chat and type `/tp ~500 200 ~500`. Wait 15-30 seconds for world to load, and type the command again. Repeat this step 10-15 times.
Potential STR ( I haven't tested this, but seeing that chunk updates are causing this issue so I'm including what MC does during that ) :
// Pseudocode
listN = 55000;
lists = glGenLists(55000);
while (true) {
for (i = 0; i < listN; i++) {
glNewList(lists + i);
// Setup matrix, setup render state, render blocks via glDrawArrays and GL_QUADS
glEndList(lists + 1);
}
// All lists are draw each frame, and some of them *might* change, might not change before each frame ( if blocks in that list were changed ). I'm re-creating all of them for simplicity sake
for (i = 0; i < listN; i++) {
glTranslatef(... list offset ...);
glCallList(i);
}
}
In theory I could record apitrace. Never did it on Windows, but should be possible.
Hi @TechoMan ,
Thanks for reporting it. I have whitelisted you and moved the post to the OpenGL forum.
Could you please provide the following information?
1) setup details like OS, GPU, driver version etc., 2) detailed steps to reproduce the issue
Thanks.
Hi @dipak ,
Thanks. I have updated original post with more information.
Thanks for the information. I will forward the issue to the OpenGL team.
A bug ticket has been created to track this issue. I will keep you posted on its progress.
Thanks.
Hi @TechoMan ,
STR ( in game ) : Startup Minecraft 1.7, Join any world in creative/with admin rights, press T to open chat and type `/tp ~500 200 ~500`. Wait 15-30 seconds for world to load, and type the command again. Repeat this step 10-15 times.
To reproduce the issue locally, it would be helpful if you please provide some more details on the above steps like the exact thing that you observed/monitored, the tool(s) used to monitor the VRAM usage etc.. You can also provide some screenshots or a demo video to demonstrate this issue.
Thanks.
Hi @dipak ,
Basically when you see new chunks/new area of a game VRAM usage is increasing, but it never decreases. This happens only on Minecraft 1.7 and older, as new versions of Minecraft don't use GL11 render lists. You can either teleport with a command, or just fly in straight line ( as you can see in the video )
Here is video: https://youtu.be/dI0Ei6heWl0 I have used task manager and AMD Software ( Adrenaline edition ) to monitor VRAM.
I have also tried deleting the render lists via deleteDisplayLists and it seems to free up the VRAM, witch kind-of proofs that memory leak happens because of render lists I guess ?
If you need any other help or have Q about internal of MC - just drop me a message 🙂
Thanks for the above information and providing the demo video. I will share these details with the OpenGL team.
Thanks.
Hey @dipak , are there any updates to this?
Hi @CamJ7103 ,
The OpenGL team was able to reproduce the issue locally. The dev team is now investigating it.
Thanks.
@dipak can you provide an updated status for this issue ?
Hi @TechoMan ,
I will check with the OpenGL team and let you know if I get any update on this.
Thanks.
As I have come to know, the issue is still under investigation. Will notify you once there is any update on this.
Thanks.
For anyone coming here from the web, and willing to code/fix this issue in MC itself.
package su.borealis.clientTweaker.mixin;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.RenderGlobal;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(RenderGlobal.class)
public abstract class MixinRenderGlobal_reCreateDisplayLists {
public abstract void deleteAllDisplayLists();
private int glRenderListBase;
@Inject(method = "loadRenderers", at = @At("HEAD"))
public void loadRenderers_reloadDrawLists(CallbackInfo ci) {
this.deleteAllDisplayLists();
byte b0 = 32 * 2 + 2;
byte b1 = 16;
glRenderListBase = GLAllocation.generateDisplayLists(b0 * b0 * b1 * 3);
}
}
Here is half-bodged mixin/solution that re-creates display lists when you force-reload chunks ( aka press F3 + A ).
Chunks would need to be re-rendered when list is destroyed anyway.
This won't work with OF, but it makes little sense to support 64 chunk rendering as AMD drivers straightforward crash with such high render distances ( most likely there is a limit on how many textures can be had, and most minimap mods create 1-3 textures per rendered chunk => crash would occur ).