diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java index d52804652..83b1a253d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java @@ -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) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferImpl.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferImpl.java new file mode 100644 index 000000000..7002e5505 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferImpl.java @@ -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; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentGlBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentGlBuffer.java new file mode 100644 index 000000000..49c0876b4 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentGlBuffer.java @@ -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; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentMappedBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentMappedBuffer.java new file mode 100644 index 000000000..03516f0c8 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentMappedBuffer.java @@ -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() { + + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/Instancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/Instancer.java index c2b3dd720..87069f7db 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/Instancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/Instancer.java @@ -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 { model = new IndexedModel(iModel); vao = new GlVertexArray(); - instanceVBO = new GlBuffer(GlBufferType.ARRAY_BUFFER); + instanceVBO = new PersistentGlBuffer(GlBufferType.ARRAY_BUFFER); vao.bind(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/BufferedModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/BufferedModel.java index 5808c177e..d2774b107 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/BufferedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/BufferedModel.java @@ -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 diff --git a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java index e19140a12..3f0c7c624 100644 --- a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java +++ b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java @@ -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) diff --git a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java index 287cf37d5..36357b675 100644 --- a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java +++ b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java @@ -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)); } /**