potential nvidia null VBO pointer crash fix

This commit is contained in:
James Seibel
2026-04-22 22:33:17 -05:00
parent 118ef39c30
commit 33e6ce6376
3 changed files with 67 additions and 31 deletions
@@ -69,6 +69,17 @@ public class GLBuffer implements AutoCloseable
protected boolean bufferStorage;
protected boolean isMapped = false;
/**
* Locking on the render thread isn't great, but is needed due to an inconsistent
* race condition where VBOs can be marked as deleted outside the render thread. <br><br>
*
* But, due to being a read-write lock the chance of freezing
* the render thread is very low
* and since this is a stamped lock, the optimistic read time is basically zero.
* (The optimistic lock time doesn't even appear in the profiler).
*/
public final StampedLock renderStampLock = new StampedLock();
//==============//
@@ -142,6 +153,14 @@ public class GLBuffer implements AutoCloseable
return;
}
long writeStamp = 0;
try
{
// lock to prevent the render thread from accessing the buffer's ID
// while we are removing it
writeStamp = renderStampLock.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
@@ -151,6 +170,11 @@ public class GLBuffer implements AutoCloseable
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer destroyAsync", () -> { destroyBufferIdNow(idToDelete); });
}
finally
{
renderStampLock.unlock(writeStamp);
}
}
private static void destroyBufferIdNow(int id)
{
// only delete valid buffers
@@ -341,6 +341,12 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
continue;
}
// for lock information please view the lock's javadocs
long vboReadStamp = vbo.renderStampLock.readLock();
long iboReadStamp = vbo.getQuadIBO().renderStampLock.readLock();
try
{
// don't render empty sections
if (vbo.getVertexCount() == 0)
{
@@ -355,7 +361,7 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
}
// 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);
int indexCount = (int) (vbo.getVertexCount() * 1.5);
vbo.bind();
vbo.getQuadIBO().bind();
@@ -369,6 +375,12 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
vbo.unbind();
vbo.getQuadIBO().unbind();
}
finally
{
vbo.renderStampLock.unlock(vboReadStamp);
vbo.getQuadIBO().renderStampLock.unlock(iboReadStamp);
}
}
}
}