Fix nvidia driver crash

This commit is contained in:
James Seibel
2026-04-22 17:14:50 -05:00
parent 1777acd1d4
commit b0e924c7fe
2 changed files with 46 additions and 67 deletions
@@ -62,14 +62,13 @@ public class GLBuffer implements AutoCloseable
private static final ThreadPoolExecutor CLEANUP_THREAD = ThreadUtil.makeSingleDaemonThreadPool("GLBuffer Cleanup");
protected int id;
protected int id = 0;
public final int getId() { return this.id; }
protected int size = 0;
public int getSize() { return this.size; }
protected boolean bufferStorage;
protected boolean isMapped = false;
public final StampedLock writeLock = new StampedLock();
//==============//
@@ -112,27 +111,26 @@ public class GLBuffer implements AutoCloseable
LodUtil.assertNotReach("Thread ["+Thread.currentThread()+"] tried to create a GLBuffer outside the MC render thread.");
}
// destroy the old buffer if one is present
if (this.id != 0)
int oldId = this.id;
this.id = GLMC.glGenBuffers();
// destroy the old buffer
// after the new one has been created
// to hopefully prevent a rare race conditions where the old ID
// is still used somewhere
if (oldId != 0)
{
destroyBufferIdNow(this.id);
destroyBufferIdNow(oldId);
}
long writeLock = this.writeLock.writeLock();
try
{
this.id = GLMC.glGenBuffers();
this.bufferStorage = asBufferStorage;
bufferCount.getAndIncrement();
PhantomReference<GLBuffer> phantom = new PhantomReference<>(this, PHANTOM_REFERENCE_QUEUE);
PHANTOM_TO_BUFFER_ID.put(phantom, this.id);
BUFFER_ID_TO_PHANTOM.put(this.id, phantom);
}
finally
{
this.writeLock.unlock(writeLock);
}
this.bufferStorage = asBufferStorage;
bufferCount.getAndIncrement();
PhantomReference<GLBuffer> phantom = new PhantomReference<>(this, PHANTOM_REFERENCE_QUEUE);
PHANTOM_TO_BUFFER_ID.put(phantom, this.id);
BUFFER_ID_TO_PHANTOM.put(this.id, phantom);
}
@@ -144,20 +142,14 @@ public class GLBuffer implements AutoCloseable
return;
}
long writeLock = this.writeLock.writeLock();
try
{
final int idToDelete = this.id; // saving the ID to a separate variable is necessary so it can be captured by the lambda
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer destroyAsync", () -> { destroyBufferIdNow(idToDelete); });
this.id = 0;
this.size = 0;
}
finally
{
this.writeLock.unlock(writeLock);
}
final int idToDelete = this.id; // saving the ID to a separate variable is necessary so it can be captured by the lambda
// mark the old data is invalid before deleting to prevent a rare race condition
// where the queued on render thread task runs before the ID is cleared
this.id = 0;
this.size = 0;
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer destroyAsync", () -> { destroyBufferIdNow(idToDelete); });
}
private static void destroyBufferIdNow(int id)
{
@@ -341,46 +341,33 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
continue;
}
long vboReadLock = vbo.writeLock.tryReadLock();
if (vboReadLock == 0)
// don't render empty sections
if (vbo.getVertexCount() == 0)
{
// VBO is being deleted
continue;
}
try
// don't render deleted VBOs (this will crash the driver/game)
if (vbo.getId() == 0
|| vbo.getQuadIBO().getId() == 0)
{
if (vbo.getVertexCount() == 0)
{
continue;
}
if (vbo.getId() == 0
|| vbo.getQuadIBO().getId() == 0)
{
continue;
}
// 4 vertices per face, but 6 indices (IE 2 triangles) per face, aka need to multiply by 1.5
int indexCount = (int)(vbo.getVertexCount() * 1.5);
vbo.bind();
vbo.getQuadIBO().bind();
GlDhMetaRenderer.INSTANCE.shaderProgramForThisFrame.bindVertexBuffer(vbo.getId());
GL32.glDrawElements(
GL32.GL_TRIANGLES,
indexCount,
vbo.getQuadIBO().getGlType(), 0);
vbo.unbind();
vbo.getQuadIBO().unbind();
}
finally
{
vbo.writeLock.unlock(vboReadLock);
continue;
}
// 4 vertices per face, but 6 indices (IE 2 triangles) per face, aka need to multiply by 1.5
int indexCount = (int)(vbo.getVertexCount() * 1.5);
vbo.bind();
vbo.getQuadIBO().bind();
GlDhMetaRenderer.INSTANCE.shaderProgramForThisFrame.bindVertexBuffer(vbo.getId());
GL32.glDrawElements(
GL32.GL_TRIANGLES,
indexCount,
vbo.getQuadIBO().getGlType(), 0);
vbo.unbind();
vbo.getQuadIBO().unbind();
}
}
}