Persistent buffers v1

This commit is contained in:
Jozufozu 2021-08-13 16:15:20 -07:00
parent 11f55d1d56
commit f0fc3fffb9
8 changed files with 155 additions and 38 deletions

View file

@ -2,27 +2,17 @@ package com.jozufozu.flywheel.backend.gl.buffer;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlObject;
import com.jozufozu.flywheel.backend.gl.versioned.MapBufferRange;
public class GlBuffer extends GlObject {
public abstract class GlBuffer extends GlObject {
protected final GlBufferType type;
protected final GlBufferUsage usage;
public GlBuffer(GlBufferType type) {
this(type, GlBufferUsage.STATIC_DRAW);
}
public GlBuffer(GlBufferType type, GlBufferUsage usage) {
setHandle(GL20.glGenBuffers());
_create();
this.type = type;
this.usage = usage;
}
public GlBufferType getBufferTarget() {
@ -30,37 +20,21 @@ public class GlBuffer extends GlObject {
}
public void bind() {
bind(type);
}
public void bind(GlBufferType type) {
GL20.glBindBuffer(type.glEnum, handle());
}
public void unbind() {
unbind(type);
GL20.glBindBuffer(type.glEnum, 0);
}
public void unbind(GlBufferType bufferType) {
GL20.glBindBuffer(bufferType.glEnum, 0);
}
public abstract void alloc(long size);
public void alloc(int size) {
GL15.glBufferData(type.glEnum, size, usage.glEnum);
}
public abstract void upload(ByteBuffer directBuffer);
public void upload(ByteBuffer directBuffer) {
GL15.glBufferData(type.glEnum, directBuffer, usage.glEnum);
}
public abstract MappedBuffer getBuffer(int offset, int length);
public MappedBuffer getBuffer(int offset, int length) {
if (Backend.getInstance().compat.mapBufferRange != MapBufferRange.UNSUPPORTED) {
return new MappedBufferRange(this, offset, length, GL30.GL_MAP_WRITE_BIT);
} else {
MappedFullBuffer fullBuffer = new MappedFullBuffer(this, MappedBufferUsage.WRITE_ONLY);
fullBuffer.position(offset);
return fullBuffer;
}
protected void _create() {
setHandle(GL20.glGenBuffers());
}
protected void deleteInternal(int handle) {

View file

@ -0,0 +1,41 @@
package com.jozufozu.flywheel.backend.gl.buffer;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.versioned.MapBufferRange;
public class GlBufferImpl extends GlBuffer {
protected final GlBufferUsage usage;
public GlBufferImpl(GlBufferType type) {
this(type, GlBufferUsage.STATIC_DRAW);
}
public GlBufferImpl(GlBufferType type, GlBufferUsage usage) {
super(type);
this.usage = usage;
}
public void alloc(long size) {
GL15.glBufferData(type.glEnum, size, usage.glEnum);
}
public void upload(ByteBuffer directBuffer) {
GL15.glBufferData(type.glEnum, directBuffer, usage.glEnum);
}
public MappedBuffer getBuffer(int offset, int length) {
if (Backend.getInstance().compat.mapBufferRange != MapBufferRange.UNSUPPORTED) {
return new MappedBufferRange(this, offset, length, GL30.GL_MAP_WRITE_BIT);
} else {
MappedFullBuffer fullBuffer = new MappedFullBuffer(this, MappedBufferUsage.WRITE_ONLY);
fullBuffer.position(offset);
return fullBuffer;
}
}
}

View file

@ -0,0 +1,66 @@
package com.jozufozu.flywheel.backend.gl.buffer;
import static org.lwjgl.opengl.GL44.*;
import java.nio.ByteBuffer;
public class PersistentGlBuffer extends GlBuffer {
private PersistentMappedBuffer buffer;
int flags;
long size;
private long fence = -1;
public PersistentGlBuffer(GlBufferType type) {
super(type);
flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
}
@Override
public void unbind() {
super.unbind();
fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
@Override
public void alloc(long size) {
this.size = size;
if (buffer != null) {
deleteInternal(handle());
_create();
}
glBufferStorage(type.glEnum, size, flags);
buffer = new PersistentMappedBuffer(this);
}
@Override
public void upload(ByteBuffer directBuffer) {
}
@Override
public MappedBuffer getBuffer(int offset, int length) {
if (fence != -1) {
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);
return buffer;
}
}

View file

@ -0,0 +1,31 @@
package com.jozufozu.flywheel.backend.gl.buffer;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL44;
import org.lwjgl.opengl.GL46;
public class PersistentMappedBuffer extends MappedBuffer {
PersistentGlBuffer owner;
public PersistentMappedBuffer(PersistentGlBuffer buffer) {
super(buffer);
owner = buffer;
ByteBuffer byteBuffer = GL44.glMapBufferRange(owner.type.glEnum, 0, owner.size, owner.flags);
setInternal(byteBuffer);
}
@Override
public void flush() {
}
@Override
protected void checkAndMap() {
}
}

View file

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

View file

@ -8,6 +8,7 @@ import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
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.MappedBuffer;
import com.jozufozu.flywheel.core.model.IModel;
@ -24,7 +25,7 @@ public class BufferedModel implements IBufferedModel {
this.model = model;
this.primitiveMode = primitiveMode;
vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
vbo = new GlBufferImpl(GlBufferType.ARRAY_BUFFER);
vbo.bind();
// allocate the buffer on the gpu

View file

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

View file

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