1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-01-20 06:02:54 +00:00

Reset the BufferUploader state on Linux

GlStateManager.glDeleteBuffers clears a buffer before deleting it on
Linux - I assume otherwise there's memory leaks on some drivers? - which
clobbers BufferUploader's cache. Roll our own version which resets the
cache when needed.

Also always reset the cache when deleting/creating a DirectVertexBuffer.
This commit is contained in:
Jonathan Coates 2022-04-26 22:39:34 +01:00
parent 59e3608d2a
commit 42b98bce28
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
4 changed files with 35 additions and 8 deletions

View File

@ -163,7 +163,6 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
MonitorTextureBufferShader shader = RenderTypes.getMonitorTextureBufferShader(); MonitorTextureBufferShader shader = RenderTypes.getMonitorTextureBufferShader();
shader.setupUniform( monitor.tboUniform ); shader.setupUniform( monitor.tboUniform );
// TODO: Switch to using a VBO here? Something to avoid having to do the
VertexConsumer buffer = bufferSource.getBuffer( RenderTypes.MONITOR_TBO ); VertexConsumer buffer = bufferSource.getBuffer( RenderTypes.MONITOR_TBO );
tboVertex( buffer, matrix, -xMargin, -yMargin ); tboVertex( buffer, matrix, -xMargin, -yMargin );
tboVertex( buffer, matrix, -xMargin, pixelHeight + yMargin ); tboVertex( buffer, matrix, -xMargin, pixelHeight + yMargin );

View File

@ -6,7 +6,9 @@
package dan200.computercraft.client.util; package dan200.computercraft.client.util;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferUploader; import com.mojang.blaze3d.vertex.BufferUploader;
import net.minecraft.Util;
import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL15C; import org.lwjgl.opengl.GL15C;
import org.lwjgl.opengl.GL45C; import org.lwjgl.opengl.GL45C;
@ -20,6 +22,7 @@ import java.nio.ByteBuffer;
public class DirectBuffers public class DirectBuffers
{ {
public static final boolean HAS_DSA; public static final boolean HAS_DSA;
static final boolean ON_LINUX = Util.getPlatform() == Util.OS.LINUX;
static static
{ {
@ -32,6 +35,23 @@ public class DirectBuffers
return HAS_DSA ? GL45C.glCreateBuffers() : GL15C.glGenBuffers(); return HAS_DSA ? GL45C.glCreateBuffers() : GL15C.glGenBuffers();
} }
/**
* Delete a previously created buffer.
*
* On Linux, {@link GlStateManager#_glDeleteBuffers(int)} clears a buffer before deleting it. However, this involves
* binding and unbinding the buffer, conflicting with {@link BufferUploader}'s cache. This deletion method uses
* our existing {@link #setEmptyBufferData(int, int, int)}, which correctly handles clearing the buffer.
*
* @param type The buffer's type.
* @param id The buffer's ID.
*/
public static void deleteBuffer( int type, int id )
{
RenderSystem.assertOnRenderThread();
if( ON_LINUX ) DirectBuffers.setEmptyBufferData( type, id, GL15C.GL_DYNAMIC_DRAW );
GL15C.glDeleteBuffers( id );
}
public static void setBufferData( int type, int id, ByteBuffer buffer, int flags ) public static void setBufferData( int type, int id, ByteBuffer buffer, int flags )
{ {
if( HAS_DSA ) if( HAS_DSA )
@ -40,9 +60,9 @@ public class DirectBuffers
} }
else else
{ {
if( type == GL45C.GL_ARRAY_BUFFER ) BufferUploader.reset(); if( type == GL15C.GL_ARRAY_BUFFER ) BufferUploader.reset();
GlStateManager._glBindBuffer( type, id ); GlStateManager._glBindBuffer( type, id );
GlStateManager._glBufferData( type, buffer, GL15C.GL_STATIC_DRAW ); GlStateManager._glBufferData( type, buffer, flags );
GlStateManager._glBindBuffer( type, 0 ); GlStateManager._glBindBuffer( type, 0 );
} }
} }
@ -55,9 +75,9 @@ public class DirectBuffers
} }
else else
{ {
if( type == GL45C.GL_ARRAY_BUFFER ) BufferUploader.reset(); if( type == GL15C.GL_ARRAY_BUFFER ) BufferUploader.reset();
GlStateManager._glBindBuffer( type, id ); GlStateManager._glBindBuffer( type, id );
GlStateManager._glBufferData( type, 0, GL15C.GL_STATIC_DRAW ); GlStateManager._glBufferData( type, 0, flags );
GlStateManager._glBindBuffer( type, 0 ); GlStateManager._glBindBuffer( type, 0 );
} }
} }

View File

@ -6,6 +6,7 @@
package dan200.computercraft.client.util; package dan200.computercraft.client.util;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferUploader;
import com.mojang.blaze3d.vertex.VertexBuffer; import com.mojang.blaze3d.vertex.VertexBuffer;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.math.Matrix4f; import com.mojang.math.Matrix4f;
@ -29,6 +30,7 @@ public class DirectVertexBuffer extends VertexBuffer
if( DirectBuffers.HAS_DSA ) if( DirectBuffers.HAS_DSA )
{ {
RenderSystem.glDeleteBuffers( vertextBufferId ); RenderSystem.glDeleteBuffers( vertextBufferId );
if( DirectBuffers.ON_LINUX ) BufferUploader.reset(); // See comment on DirectBuffers.deleteBuffer.
vertextBufferId = GL45C.glCreateBuffers(); vertextBufferId = GL45C.glCreateBuffers();
} }
} }
@ -57,4 +59,11 @@ public class DirectVertexBuffer extends VertexBuffer
{ {
return actualIndexCount; return actualIndexCount;
} }
@Override
public void close()
{
super.close();
if( DirectBuffers.ON_LINUX ) BufferUploader.reset(); // See comment on DirectBuffers.deleteBuffer.
}
} }

View File

@ -6,7 +6,6 @@
package dan200.computercraft.shared.peripheral.monitor; package dan200.computercraft.shared.peripheral.monitor;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import dan200.computercraft.client.util.DirectBuffers; import dan200.computercraft.client.util.DirectBuffers;
import dan200.computercraft.client.util.DirectVertexBuffer; import dan200.computercraft.client.util.DirectVertexBuffer;
import dan200.computercraft.shared.common.ClientTerminal; import dan200.computercraft.shared.common.ClientTerminal;
@ -105,7 +104,7 @@ public final class ClientMonitor extends ClientTerminal
if( tboBuffer != 0 ) if( tboBuffer != 0 )
{ {
RenderSystem.glDeleteBuffers( tboBuffer ); DirectBuffers.deleteBuffer( GL31.GL_TEXTURE_BUFFER, tboBuffer );
tboBuffer = 0; tboBuffer = 0;
} }
@ -117,7 +116,7 @@ public final class ClientMonitor extends ClientTerminal
if( tboUniform != 0 ) if( tboUniform != 0 )
{ {
RenderSystem.glDeleteBuffers( tboUniform ); DirectBuffers.deleteBuffer( GL31.GL_UNIFORM_BUFFER, tboUniform );
tboUniform = 0; tboUniform = 0;
} }