Storage clean-up

- Wrapper for sync objects
 - Compat layer for buffer storage
 - Don't get persistent buffers if they're not supported
This commit is contained in:
Jozufozu 2021-08-14 15:57:52 -07:00
parent f82b9d2d23
commit d41acf2bcf
11 changed files with 134 additions and 28 deletions

View file

@ -0,0 +1,41 @@
package com.jozufozu.flywheel.backend.gl;
import static org.lwjgl.opengl.GL32.GL_ALREADY_SIGNALED;
import static org.lwjgl.opengl.GL32.GL_CONDITION_SATISFIED;
import static org.lwjgl.opengl.GL32.GL_SYNC_FLUSH_COMMANDS_BIT;
import static org.lwjgl.opengl.GL32.GL_SYNC_GPU_COMMANDS_COMPLETE;
import static org.lwjgl.opengl.GL32.GL_UNSIGNALED;
import static org.lwjgl.opengl.GL32.glClientWaitSync;
import static org.lwjgl.opengl.GL32.glDeleteSync;
import static org.lwjgl.opengl.GL32.glFenceSync;
public class GlFence {
private long fence;
public void post() {
clear();
fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
public void clear() {
if (fence != 0) {
glDeleteSync(fence);
fence = 0;
}
}
public void waitSync() {
if (fence != 0) {
int waitReturn = GL_UNSIGNALED;
while (waitReturn != GL_ALREADY_SIGNALED && waitReturn != GL_CONDITION_SATISFIED) {
waitReturn = glClientWaitSync(fence, GL_SYNC_FLUSH_COMMANDS_BIT, 1);
}
glDeleteSync(fence);
}
fence = 0;
}
}

View file

@ -4,6 +4,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlObject; import com.jozufozu.flywheel.backend.gl.GlObject;
public abstract class GlBuffer extends GlObject { public abstract class GlBuffer extends GlObject {
@ -15,6 +16,25 @@ public abstract class GlBuffer extends GlObject {
this.type = type; this.type = type;
} }
/**
* Request a Persistent mapped buffer.
*
* <p>
* If Persistent buffers are supported, this will provide one. Otherwise it will fall back to a classic mapped
* buffer.
* </p>
*
* @param type The type of buffer you want.
* @return A buffer that will be persistent if the driver supports it.
*/
public static GlBuffer requestPersistent(GlBufferType type) {
if (Backend.getInstance().compat.bufferStorageSupported()) {
return new PersistentGlBuffer(type);
} else {
return new MappedGlBuffer(type);
}
}
public GlBufferType getBufferTarget() { public GlBufferType getBufferTarget() {
return type; return type;
} }

View file

@ -8,15 +8,15 @@ import org.lwjgl.opengl.GL30;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.versioned.MapBufferRange; import com.jozufozu.flywheel.backend.gl.versioned.MapBufferRange;
public class GlBufferImpl extends GlBuffer { public class MappedGlBuffer extends GlBuffer {
protected final GlBufferUsage usage; protected final GlBufferUsage usage;
public GlBufferImpl(GlBufferType type) { public MappedGlBuffer(GlBufferType type) {
this(type, GlBufferUsage.STATIC_DRAW); this(type, GlBufferUsage.STATIC_DRAW);
} }
public GlBufferImpl(GlBufferType type, GlBufferUsage usage) { public MappedGlBuffer(GlBufferType type, GlBufferUsage usage) {
super(type); super(type);
this.usage = usage; this.usage = usage;
} }

View file

@ -4,6 +4,9 @@ import static org.lwjgl.opengl.GL44.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlFence;
public class PersistentGlBuffer extends GlBuffer { public class PersistentGlBuffer extends GlBuffer {
@ -11,17 +14,18 @@ public class PersistentGlBuffer extends GlBuffer {
int flags; int flags;
long size; long size;
private long fence = -1; GlFence fence;
public PersistentGlBuffer(GlBufferType type) { public PersistentGlBuffer(GlBufferType type) {
super(type); super(type);
flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
fence = new GlFence();
} }
@Override @Override
public void doneForThisFrame() { public void doneForThisFrame() {
fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); fence.post();
} }
@Override @Override
@ -33,7 +37,9 @@ public class PersistentGlBuffer extends GlBuffer {
_create(); _create();
} }
glBufferStorage(type.glEnum, size, flags); fence.clear();
Backend.getInstance().compat.bufferStorage.bufferStorage(type.glEnum, size, flags);
buffer = new PersistentMappedBuffer(this); buffer = new PersistentMappedBuffer(this);
} }
@ -46,16 +52,7 @@ public class PersistentGlBuffer extends GlBuffer {
@Override @Override
public MappedBuffer getBuffer(int offset, int length) { public MappedBuffer getBuffer(int offset, int length) {
if (fence != -1) { fence.waitSync();
int waitReturn = GL_UNSIGNALED;
while (waitReturn != GL_ALREADY_SIGNALED && waitReturn != GL_CONDITION_SATISFIED) {
waitReturn = glClientWaitSync(fence, GL_SYNC_FLUSH_COMMANDS_BIT, 1);
}
glDeleteSync(fence);
}
fence = -1;
buffer.position(offset); buffer.position(offset);

View file

@ -6,6 +6,8 @@ import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL44; import org.lwjgl.opengl.GL44;
import org.lwjgl.opengl.GL46; import org.lwjgl.opengl.GL46;
import com.jozufozu.flywheel.backend.Backend;
public class PersistentMappedBuffer extends MappedBuffer { public class PersistentMappedBuffer extends MappedBuffer {
PersistentGlBuffer owner; PersistentGlBuffer owner;
@ -14,7 +16,7 @@ public class PersistentMappedBuffer extends MappedBuffer {
super(buffer); super(buffer);
owner = buffer; owner = buffer;
ByteBuffer byteBuffer = GL44.glMapBufferRange(owner.type.glEnum, 0, owner.size, owner.flags); ByteBuffer byteBuffer = Backend.getInstance().compat.mapBufferRange.mapBuffer(owner.type, 0, owner.size, owner.flags);
setInternal(byteBuffer); setInternal(byteBuffer);
} }

View file

@ -0,0 +1,44 @@
package com.jozufozu.flywheel.backend.gl.versioned;
import org.lwjgl.opengl.ARBBufferStorage;
import org.lwjgl.opengl.GL44;
import org.lwjgl.opengl.GLCapabilities;
public enum BufferStorage implements GlVersioned {
GL44CORE {
@Override
public boolean supported(GLCapabilities caps) {
return caps.OpenGL44;
}
@Override
public void bufferStorage(int target, long size, int flags) {
GL44.glBufferStorage(target, size, flags);
}
},
ARB {
@Override
public boolean supported(GLCapabilities caps) {
return caps.GL_ARB_buffer_storage;
}
@Override
public void bufferStorage(int target, long size, int flags) {
ARBBufferStorage.glBufferStorage(target, size, flags);
}
},
UNSUPPORTED {
@Override
public boolean supported(GLCapabilities caps) {
return true;
}
@Override
public void bufferStorage(int target, long size, int flags) {
throw new UnsupportedOperationException();
}
};
public abstract void bufferStorage(int target, long size, int flags);
}

View file

@ -29,6 +29,7 @@ public class GlCompat {
public final DrawInstanced drawInstanced; public final DrawInstanced drawInstanced;
public final Blit blit; public final Blit blit;
public final Framebuffer fbo; public final Framebuffer fbo;
public final BufferStorage bufferStorage;
public final RGPixelFormat pixelFormat; public final RGPixelFormat pixelFormat;
@ -40,6 +41,7 @@ public class GlCompat {
drawInstanced = getLatest(DrawInstanced.class, caps); drawInstanced = getLatest(DrawInstanced.class, caps);
blit = getLatest(Blit.class, caps); blit = getLatest(Blit.class, caps);
fbo = getLatest(Framebuffer.class, caps); fbo = getLatest(Framebuffer.class, caps);
bufferStorage = getLatest(BufferStorage.class, caps);
pixelFormat = getLatest(RGPixelFormat.class, caps); pixelFormat = getLatest(RGPixelFormat.class, caps);
} }
@ -64,6 +66,10 @@ public class GlCompat {
return blit != Blit.UNSUPPORTED; return blit != Blit.UNSUPPORTED;
} }
public boolean bufferStorageSupported() {
return bufferStorage != BufferStorage.UNSUPPORTED;
}
/** /**
* Get the most compatible version of a specific OpenGL feature by iterating over enum constants in order. * Get the most compatible version of a specific OpenGL feature by iterating over enum constants in order.
* *

View file

@ -8,10 +8,8 @@ import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferImpl;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.PersistentGlBuffer;
import com.jozufozu.flywheel.backend.material.MaterialSpec; import com.jozufozu.flywheel.backend.material.MaterialSpec;
import com.jozufozu.flywheel.backend.model.IBufferedModel; import com.jozufozu.flywheel.backend.model.IBufferedModel;
import com.jozufozu.flywheel.backend.model.IndexedModel; import com.jozufozu.flywheel.backend.model.IndexedModel;
@ -110,7 +108,7 @@ public class Instancer<D extends InstanceData> {
model = new IndexedModel(iModel); model = new IndexedModel(iModel);
vao = new GlVertexArray(); vao = new GlVertexArray();
instanceVBO = new PersistentGlBuffer(GlBufferType.ARRAY_BUFFER); instanceVBO = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER);
vao.bind(); vao.bind();

View file

@ -2,13 +2,11 @@ package com.jozufozu.flywheel.backend.model;
import static org.lwjgl.opengl.GL20.glDrawArrays; import static org.lwjgl.opengl.GL20.glDrawArrays;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlPrimitive; import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferImpl; import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.core.model.IModel; import com.jozufozu.flywheel.core.model.IModel;
@ -25,7 +23,7 @@ public class BufferedModel implements IBufferedModel {
this.model = model; this.model = model;
this.primitiveMode = primitiveMode; this.primitiveMode = primitiveMode;
vbo = new GlBufferImpl(GlBufferType.ARRAY_BUFFER); vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
vbo.bind(); vbo.bind();
// allocate the buffer on the gpu // allocate the buffer on the gpu

View file

@ -5,7 +5,7 @@ import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.gl.GlNumericType; import com.jozufozu.flywheel.backend.gl.GlNumericType;
import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferImpl; import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import net.minecraftforge.common.util.Lazy; import net.minecraftforge.common.util.Lazy;
@ -26,7 +26,7 @@ public class FullscreenQuad {
private final GlBuffer vbo; private final GlBuffer vbo;
private FullscreenQuad() { private FullscreenQuad() {
vbo = new GlBufferImpl(GlBufferType.ARRAY_BUFFER); vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
vbo.bind(); vbo.bind();
vbo.alloc(bufferSize); vbo.alloc(bufferSize);
vbo.getBuffer(0, bufferSize) vbo.getBuffer(0, bufferSize)

View file

@ -14,7 +14,7 @@ import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.backend.gl.GlNumericType; import com.jozufozu.flywheel.backend.gl.GlNumericType;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferImpl; import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.model.ElementBuffer; import com.jozufozu.flywheel.backend.model.ElementBuffer;
import com.jozufozu.flywheel.event.ReloadRenderersEvent; import com.jozufozu.flywheel.event.ReloadRenderersEvent;
@ -142,7 +142,7 @@ public class QuadConverter {
} }
private GlBuffer getBuffer(GlNumericType type) { private GlBuffer getBuffer(GlNumericType type) {
return ebos.computeIfAbsent(type, $ -> new GlBufferImpl(GlBufferType.ELEMENT_ARRAY_BUFFER)); return ebos.computeIfAbsent(type, $ -> new MappedGlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER));
} }
/** /**