diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backends.java b/src/main/java/com/jozufozu/flywheel/backend/Backends.java index 41bbcd21d..f19af77c0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backends.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backends.java @@ -7,7 +7,7 @@ import com.jozufozu.flywheel.backend.compile.InstancingPrograms; import com.jozufozu.flywheel.backend.engine.batching.BatchingEngine; import com.jozufozu.flywheel.backend.engine.indirect.IndirectEngine; import com.jozufozu.flywheel.backend.engine.instancing.InstancingEngine; -import com.jozufozu.flywheel.gl.versioned.GlCompat; +import com.jozufozu.flywheel.gl.GlCompat; import com.jozufozu.flywheel.lib.backend.SimpleBackend; import com.jozufozu.flywheel.lib.context.Contexts; import com.jozufozu.flywheel.lib.util.ShadersModHandler; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compilation.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compilation.java index dc252043c..a898f274e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compilation.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compilation.java @@ -10,9 +10,9 @@ import org.jetbrains.annotations.NotNull; import org.lwjgl.opengl.GL20; import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.gl.GlCompat; import com.jozufozu.flywheel.gl.shader.GlShader; import com.jozufozu.flywheel.gl.shader.ShaderType; -import com.jozufozu.flywheel.gl.versioned.GlCompat; import com.jozufozu.flywheel.glsl.GLSLVersion; import com.jozufozu.flywheel.glsl.SourceComponent; import com.jozufozu.flywheel.glsl.SourceFile; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java index 985d11a54..2164ea4fa 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java @@ -41,7 +41,7 @@ public class GPUInstancer extends AbstractInstancer { } vbo = new GlBuffer(GlBufferUsage.DYNAMIC_DRAW); - vbo.setGrowthMargin(instanceStride * 16); + vbo.growthMargin(instanceStride * 16); } public void update() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedMeshPool.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedMeshPool.java index f52d87fe2..25ed034f1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedMeshPool.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedMeshPool.java @@ -39,7 +39,7 @@ public class InstancedMeshPool { this.vertexType = vertexType; int stride = vertexType.getLayout().getStride(); vbo = new GlBuffer(); - vbo.setGrowthMargin(stride * 32); + vbo.growthMargin(stride * 32); } public VertexType getVertexType() { diff --git a/src/main/java/com/jozufozu/flywheel/gl/versioned/GlCompat.java b/src/main/java/com/jozufozu/flywheel/gl/GlCompat.java similarity index 75% rename from src/main/java/com/jozufozu/flywheel/gl/versioned/GlCompat.java rename to src/main/java/com/jozufozu/flywheel/gl/GlCompat.java index 78919a027..6f318ad4c 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/versioned/GlCompat.java +++ b/src/main/java/com/jozufozu/flywheel/gl/GlCompat.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.gl.versioned; +package com.jozufozu.flywheel.gl; import java.nio.ByteBuffer; @@ -8,6 +8,8 @@ import org.lwjgl.opengl.GL20C; import org.lwjgl.opengl.GLCapabilities; import org.lwjgl.system.MemoryStack; +import com.jozufozu.flywheel.gl.array.GlVertexArray; + import net.minecraft.Util; /** @@ -17,17 +19,9 @@ import net.minecraft.Util; * system. */ public class GlCompat { - private static final GLCapabilities caps; - public static final VertexArray vertexArray; - public static final boolean amd; - public static final boolean supportsIndirect; - - static { - caps = GL.createCapabilities(); - vertexArray = VertexArray.DSA.INSTANCE.fallback(caps); - supportsIndirect = _decideIfWeSupportIndirect(); - amd = _decideIfWeAreAMDWindows(); - } + public static final GLCapabilities CAPABILITIES = GL.createCapabilities(); + private static final boolean amd = _decideIfWeAreAMDWindows(); + private static final boolean supportsIndirect = _decideIfWeSupportIndirect(); private GlCompat() { } @@ -37,7 +31,7 @@ public class GlCompat { } public static boolean supportsInstancing() { - return caps.OpenGL33 || caps.GL_ARB_instanced_arrays; + return GlVertexArray.IMPL != null; } public static boolean supportsIndirect() { @@ -45,12 +39,7 @@ public class GlCompat { } private static boolean _decideIfWeSupportIndirect() { - return caps.OpenGL46 || ( - caps.GL_ARB_compute_shader && - caps.GL_ARB_shader_draw_parameters && - caps.GL_ARB_base_instance && - caps.GL_ARB_multi_draw_indirect && - caps.GL_ARB_direct_state_access); + return CAPABILITIES.OpenGL46 || (CAPABILITIES.GL_ARB_compute_shader && CAPABILITIES.GL_ARB_shader_draw_parameters && CAPABILITIES.GL_ARB_base_instance && CAPABILITIES.GL_ARB_multi_draw_indirect && CAPABILITIES.GL_ARB_direct_state_access); } /** diff --git a/src/main/java/com/jozufozu/flywheel/gl/GlStateTracker.java b/src/main/java/com/jozufozu/flywheel/gl/GlStateTracker.java index bf9d45e65..05197cb78 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/GlStateTracker.java +++ b/src/main/java/com/jozufozu/flywheel/gl/GlStateTracker.java @@ -39,6 +39,12 @@ public class GlStateTracker { return new State(BUFFERS.clone(), vao, program); } + public static void bindVao(int vao) { + if (vao != GlStateTracker.vao) { + GlStateManager._glBindVertexArray(vao); + } + } + public record State(int[] buffers, int vao, int program) implements AutoCloseable { public void restore() { if (vao != GlStateTracker.vao) { diff --git a/src/main/java/com/jozufozu/flywheel/gl/array/GlVertexArray.java b/src/main/java/com/jozufozu/flywheel/gl/array/GlVertexArray.java index 45f5afe50..cc5d61bb7 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/array/GlVertexArray.java +++ b/src/main/java/com/jozufozu/flywheel/gl/array/GlVertexArray.java @@ -1,18 +1,14 @@ package com.jozufozu.flywheel.gl.array; -import java.util.List; - import org.lwjgl.opengl.GL32; import com.jozufozu.flywheel.api.layout.BufferLayout; import com.jozufozu.flywheel.gl.GlObject; import com.jozufozu.flywheel.gl.GlStateTracker; -import com.jozufozu.flywheel.gl.versioned.GlCompat; import com.mojang.blaze3d.platform.GlStateManager; -@SuppressWarnings("MismatchedReadAndWriteOfArray") public class GlVertexArray extends GlObject { - + public static final VertexArray IMPL = new VertexArray.DSA().fallback(); private static final int MAX_ATTRIBS = GL32.glGetInteger(GL32.GL_MAX_VERTEX_ATTRIBS); /** @@ -42,57 +38,61 @@ public class GlVertexArray extends GlObject { private int elementBufferBinding = 0; - public GlVertexArray() { - setHandle(GlCompat.vertexArray.create()); + setHandle(IMPL.create()); } public void bindForDraw() { - if (!isBound()) { - GlStateManager._glBindVertexArray(handle()); - } - } - - private boolean isBound() { - return handle() == GlStateTracker.getVertexArray(); + GlStateTracker.bindVao(handle()); } public static void unbind() { GlStateManager._glBindVertexArray(0); } - public void bindAttributes(BufferLayout type, int vbo, int startAttrib, long startOffset) { + public void bindAttributes(BufferLayout type, final int vbo, final int startAttrib, final long startOffset) { + final int vao = handle(); final int stride = type.getStride(); - List vertexAttributes = type.attributes(); - for (int i = 0; i < vertexAttributes.size(); i++) { - var attribute = vertexAttributes.get(i); - int index = i + startAttrib; - targets[index] = vbo; - attributes[index] = attribute; - offsets[index] = startOffset; - strides[index] = stride; + int index = startAttrib; + long offset = startOffset; + for (var attribute : type.attributes()) { + if (!enabled[index]) { + IMPL.enableAttrib(vao, index); + enabled[index] = true; + } - GlCompat.vertexArray.setupAttrib(handle(), index, vbo, stride, startOffset, attribute); + if (shouldSetupAttrib(index, vbo, stride, offset, attribute)) { + IMPL.setupAttrib(vao, index, vbo, stride, offset, attribute); + targets[index] = vbo; + attributes[index] = attribute; + offsets[index] = offset; + strides[index] = stride; + } - startOffset += attribute.getByteWidth(); + index++; + offset += attribute.getByteWidth(); } } + private boolean shouldSetupAttrib(int index, int vbo, int stride, long offset, VertexAttribute attribute) { + return targets[index] != vbo || offsets[index] != offset || strides[index] != stride || !attribute.equals(attributes[index]); + } + protected void deleteInternal(int handle) { GlStateManager._glDeleteVertexArrays(handle); } public void setAttributeDivisor(int index, int divisor) { if (divisors[index] != divisor) { - GlCompat.vertexArray.setAttribDivisor(handle(), index, divisor); + IMPL.setAttribDivisor(handle(), index, divisor); divisors[index] = divisor; } } public void setElementBuffer(int ebo) { if (elementBufferBinding != ebo) { - GlCompat.vertexArray.setElementBuffer(handle(), ebo); + IMPL.setElementBuffer(handle(), ebo); elementBufferBinding = ebo; } } diff --git a/src/main/java/com/jozufozu/flywheel/gl/versioned/VertexArray.java b/src/main/java/com/jozufozu/flywheel/gl/array/VertexArray.java similarity index 57% rename from src/main/java/com/jozufozu/flywheel/gl/versioned/VertexArray.java rename to src/main/java/com/jozufozu/flywheel/gl/array/VertexArray.java index 5abc51031..cc7aee929 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/versioned/VertexArray.java +++ b/src/main/java/com/jozufozu/flywheel/gl/array/VertexArray.java @@ -1,23 +1,23 @@ -package com.jozufozu.flywheel.gl.versioned; +package com.jozufozu.flywheel.gl.array; import org.lwjgl.opengl.ARBInstancedArrays; import org.lwjgl.opengl.GL20C; import org.lwjgl.opengl.GL30C; import org.lwjgl.opengl.GL33C; import org.lwjgl.opengl.GL45C; -import org.lwjgl.opengl.GLCapabilities; import org.lwjgl.system.Checks; +import com.jozufozu.flywheel.gl.GlCompat; import com.jozufozu.flywheel.gl.GlStateTracker; -import com.jozufozu.flywheel.gl.array.VertexAttribute; import com.jozufozu.flywheel.gl.buffer.GlBufferType; -import com.mojang.blaze3d.platform.GlStateManager; public interface VertexArray { int create(); void setElementBuffer(int vao, int elementBuffer); + void enableAttrib(int vao, int index); + void setupAttrib(int vao, int index, int vbo, int stride, long offset, VertexAttribute attribute); void setAttribDivisor(int vao, int attrib, int divisor); @@ -30,69 +30,58 @@ public interface VertexArray { @Override public void setElementBuffer(int vao, int elementBuffer) { - if (vao != GlStateTracker.getVertexArray()) { - GlStateManager._glBindVertexArray(vao); - } + GlStateTracker.bindVao(vao); GlBufferType.ELEMENT_ARRAY_BUFFER.bind(elementBuffer); } @Override - public void setupAttrib(int vao, int index, int vbo, int stride, long offset, VertexAttribute attribute) { - if (vao != GlStateTracker.getVertexArray()) { - GlStateManager._glBindVertexArray(vao); - } - GlBufferType.ARRAY_BUFFER.bind(vbo); - + public void enableAttrib(int vao, int index) { + GlStateTracker.bindVao(vao); GL20C.glEnableVertexAttribArray(index); - attribute.setup(offset, index, stride); } + @Override + public void setupAttrib(int vao, int index, int vbo, int stride, long offset, VertexAttribute attribute) { + GlStateTracker.bindVao(vao); + GlBufferType.ARRAY_BUFFER.bind(vbo); + attribute.setup(offset, index, stride); + } } class InstancedArraysARB extends GL3 { - public static InstancedArraysARB INSTANCE = new InstancedArraysARB(); - @Override public void setAttribDivisor(int vao, int attrib, int divisor) { - if (vao != GlStateTracker.getVertexArray()) { - GlStateManager._glBindVertexArray(vao); - } + GlStateTracker.bindVao(vao); ARBInstancedArrays.glVertexAttribDivisorARB(attrib, divisor); } - public VertexArray fallback(GLCapabilities caps) { - return isSupported(caps) ? this : null; - } - - private boolean isSupported(GLCapabilities caps) { - return Checks.checkFunctions(caps.glVertexAttribDivisorARB); + public VertexArray fallback() { + if (Checks.checkFunctions(GlCompat.CAPABILITIES.glVertexAttribDivisorARB)) { + return this; + } + // null signals that we don't support instancing. + return null; } } class InstancedArraysCore extends GL3 { - public static InstancedArraysCore INSTANCE = new InstancedArraysCore(); - @Override public void setAttribDivisor(int vao, int attrib, int divisor) { - if (vao != GlStateTracker.getVertexArray()) { - GlStateManager._glBindVertexArray(vao); - } + GlStateTracker.bindVao(vao); GL33C.glVertexAttribDivisor(attrib, divisor); } - public VertexArray fallback(GLCapabilities caps) { - return isSupported(caps) ? this : InstancedArraysARB.INSTANCE.fallback(caps); + public VertexArray fallback() { + // We know vertex arrays are supported because minecraft required GL32. + if (Checks.checkFunctions(GlCompat.CAPABILITIES.glVertexAttribDivisor)) { + return this; + } + return new InstancedArraysARB().fallback(); } - private static boolean isSupported(GLCapabilities caps) { - // We know vertex arrays are supported because minecraft required GL32. - return Checks.checkFunctions(caps.glVertexAttribDivisor); - } } class DSA implements VertexArray { - public static final DSA INSTANCE = new DSA(); - @Override public int create() { return GL45C.glCreateVertexArrays(); @@ -104,8 +93,12 @@ public interface VertexArray { } @Override - public void setupAttrib(int vao, int index, int vbo, int stride, long offset, VertexAttribute attribute) { + public void enableAttrib(int vao, int index) { GL45C.glEnableVertexArrayAttrib(vao, index); + } + + @Override + public void setupAttrib(int vao, int index, int vbo, int stride, long offset, VertexAttribute attribute) { GL45C.glVertexArrayVertexBuffer(vao, index, vbo, offset, stride); attribute.setupDSA(vao, index); } @@ -115,12 +108,26 @@ public interface VertexArray { GL45C.glVertexArrayBindingDivisor(vao, attrib, divisor); } - public VertexArray fallback(GLCapabilities caps) { - return isSupported(caps) ? this : InstancedArraysCore.INSTANCE.fallback(caps); - } + public VertexArray fallback() { + var c = GlCompat.CAPABILITIES; + if (Checks.checkFunctions(c.glCreateVertexArrays, c.glVertexArrayElementBuffer, c.glEnableVertexArrayAttrib, c.glVertexArrayVertexBuffer, c.glVertexArrayAttribFormat, c.glVertexArrayAttribIFormat)) { - private static boolean isSupported(GLCapabilities caps) { - return Checks.checkFunctions(caps.glCreateVertexArrays, caps.glVertexArrayElementBuffer, caps.glEnableVertexArrayAttrib, caps.glVertexArrayVertexBuffer, caps.glVertexArrayBindingDivisor, caps.glVertexArrayAttribFormat, caps.glVertexArrayAttribIFormat); + if (Checks.checkFunctions(c.glVertexArrayBindingDivisor)) { + return this; + } else if (Checks.checkFunctions(c.glVertexArrayVertexAttribDivisorEXT)) { + // Seems like this may happen when a driver supports + // ARB_direct_state_access but not core instanced arrays? + return new InstancedArraysEXTDSA(); + } + } + return new InstancedArraysCore().fallback(); + } + } + + class InstancedArraysEXTDSA extends DSA { + @Override + public void setAttribDivisor(int vao, int attrib, int divisor) { + ARBInstancedArrays.glVertexArrayVertexAttribDivisorEXT(vao, attrib, divisor); } } } diff --git a/src/main/java/com/jozufozu/flywheel/gl/array/VertexAttributeF.java b/src/main/java/com/jozufozu/flywheel/gl/array/VertexAttributeF.java index 0c9db89ae..664949890 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/array/VertexAttributeF.java +++ b/src/main/java/com/jozufozu/flywheel/gl/array/VertexAttributeF.java @@ -13,7 +13,6 @@ import com.jozufozu.flywheel.gl.GlNumericType; * @param normalized Whether the data is normalized. */ public record VertexAttributeF(GlNumericType type, int size, boolean normalized) implements VertexAttribute { - @Override public int getByteWidth() { return size * type.getByteWidth(); diff --git a/src/main/java/com/jozufozu/flywheel/gl/array/VertexAttributeI.java b/src/main/java/com/jozufozu/flywheel/gl/array/VertexAttributeI.java index 5e5928f15..f99633f8c 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/array/VertexAttributeI.java +++ b/src/main/java/com/jozufozu/flywheel/gl/array/VertexAttributeI.java @@ -12,7 +12,6 @@ import com.jozufozu.flywheel.gl.GlNumericType; * @param size The number of components in the attribute, e.g. 3 for a vec3. */ public record VertexAttributeI(GlNumericType type, int size) implements VertexAttribute { - @Override public int getByteWidth() { return size * type.getByteWidth(); diff --git a/src/main/java/com/jozufozu/flywheel/gl/buffer/Buffer.java b/src/main/java/com/jozufozu/flywheel/gl/buffer/Buffer.java new file mode 100644 index 000000000..c5d1b03f6 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/gl/buffer/Buffer.java @@ -0,0 +1,89 @@ +package com.jozufozu.flywheel.gl.buffer; + +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL31; +import org.lwjgl.opengl.GL45C; +import org.lwjgl.system.Checks; + +import com.jozufozu.flywheel.gl.GlCompat; + +public interface Buffer { + int create(); + + void data(int vbo, long size, long ptr, int glEnum); + + void copyData(int src, int dst, long srcOffset, long dstOffset, long size); + + long mapRange(int handle, int offset, long size, int access); + + void unmap(int handle); + + class DSA implements Buffer { + @Override + public int create() { + return GL45C.glCreateBuffers(); + } + + @Override + public void data(int vbo, long size, long ptr, int glEnum) { + GL45C.nglNamedBufferData(vbo, size, ptr, glEnum); + } + + @Override + public void copyData(int src, int dst, long srcOffset, long dstOffset, long size) { + GL45C.glCopyNamedBufferSubData(src, dst, srcOffset, dstOffset, size); + } + + @Override + public long mapRange(int handle, int offset, long size, int access) { + return GL45C.nglMapNamedBufferRange(handle, offset, size, access); + } + + @Override + public void unmap(int handle) { + GL45C.glUnmapNamedBuffer(handle); + } + + public Buffer fallback() { + var c = GlCompat.CAPABILITIES; + if (Checks.checkFunctions(c.glCreateBuffers, c.glNamedBufferData, c.glCopyNamedBufferSubData, c.glMapNamedBufferRange, c.glUnmapNamedBuffer)) { + return this; + } + return new Core(); + } + } + + class Core implements Buffer { + @Override + public int create() { + return GL15.glGenBuffers(); + } + + @Override + public void data(int vbo, long size, long ptr, int glEnum) { + GlBufferType.COPY_WRITE_BUFFER.bind(vbo); + GL15.nglBufferData(GlBufferType.COPY_WRITE_BUFFER.glEnum, size, ptr, glEnum); + } + + @Override + public void copyData(int src, int dst, long size, long srcOffset, long dstOffset) { + GlBufferType.COPY_READ_BUFFER.bind(src); + GlBufferType.COPY_WRITE_BUFFER.bind(dst); + + GL31.glCopyBufferSubData(GlBufferType.COPY_READ_BUFFER.glEnum, GlBufferType.COPY_WRITE_BUFFER.glEnum, srcOffset, dstOffset, size); + } + + @Override + public long mapRange(int handle, int offset, long size, int access) { + GlBufferType.COPY_READ_BUFFER.bind(handle); + return GL30.nglMapBufferRange(GlBufferType.COPY_READ_BUFFER.glEnum, 0, size, access); + } + + @Override + public void unmap(int handle) { + GlBufferType.COPY_READ_BUFFER.bind(handle); + GL15.glUnmapBuffer(GlBufferType.COPY_READ_BUFFER.glEnum); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/gl/buffer/GlBuffer.java b/src/main/java/com/jozufozu/flywheel/gl/buffer/GlBuffer.java index 4724e961d..e9c4ba90e 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/buffer/GlBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/gl/buffer/GlBuffer.java @@ -1,16 +1,16 @@ package com.jozufozu.flywheel.gl.buffer; -import static org.lwjgl.opengl.GL15.glBufferData; import static org.lwjgl.opengl.GL15.glDeleteBuffers; -import static org.lwjgl.opengl.GL15.glGenBuffers; -import static org.lwjgl.opengl.GL15.nglBufferData; -import static org.lwjgl.opengl.GL31.glCopyBufferSubData; + +import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.gl.GlObject; import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker; import com.jozufozu.flywheel.lib.memory.MemoryBlock; +import com.mojang.blaze3d.platform.GlStateManager; public class GlBuffer extends GlObject { + public static final Buffer IMPL = new Buffer.DSA().fallback(); protected final GlBufferUsage usage; /** * The size (in bytes) of the buffer on the GPU. @@ -26,64 +26,67 @@ public class GlBuffer extends GlObject { } public GlBuffer(GlBufferUsage usage) { - setHandle(glGenBuffers()); + setHandle(IMPL.create()); this.usage = usage; } /** * @return true if the buffer was recreated. */ - public boolean ensureCapacity(long size) { - if (size < 0) { - throw new IllegalArgumentException("Size " + size + " < 0"); + public boolean ensureCapacity(long capacity) { + if (capacity < 0) { + throw new IllegalArgumentException("Size " + capacity + " < 0"); } - if (size == 0) { + if (capacity == 0) { return false; } - if (this.size == 0) { - this.size = size; - GlBufferType.COPY_WRITE_BUFFER.bind(handle()); - glBufferData(GlBufferType.COPY_WRITE_BUFFER.glEnum, size, usage.glEnum); - FlwMemoryTracker._allocGPUMemory(size); - + if (size == 0) { + alloc(capacity); return true; } - if (size > this.size) { - var oldSize = this.size; - this.size = size + growthMargin; - - realloc(oldSize, this.size); - + if (capacity > size) { + realloc(capacity); return true; } return false; } - private void realloc(long oldSize, long newSize) { - FlwMemoryTracker._freeGPUMemory(oldSize); - FlwMemoryTracker._allocGPUMemory(newSize); - var oldHandle = handle(); - var newHandle = glGenBuffers(); + private void alloc(long capacity) { + increaseSize(capacity); + IMPL.data(handle(), size, MemoryUtil.NULL, usage.glEnum); + FlwMemoryTracker._allocGPUMemory(size); + } - GlBufferType.COPY_READ_BUFFER.bind(oldHandle); - GlBufferType.COPY_WRITE_BUFFER.bind(newHandle); - - glBufferData(GlBufferType.COPY_WRITE_BUFFER.glEnum, newSize, usage.glEnum); - glCopyBufferSubData(GlBufferType.COPY_READ_BUFFER.glEnum, GlBufferType.COPY_WRITE_BUFFER.glEnum, 0, 0, oldSize); + private void realloc(long capacity) { + FlwMemoryTracker._freeGPUMemory(size); + var oldSize = size; + increaseSize(capacity); + int oldHandle = handle(); + int newHandle = IMPL.create(); + IMPL.data(newHandle, size, MemoryUtil.NULL, usage.glEnum); + IMPL.copyData(oldHandle, newHandle, 0, 0, oldSize); glDeleteBuffers(oldHandle); setHandle(newHandle); + + FlwMemoryTracker._allocGPUMemory(size); + } + + /** + * Increase the size of the buffer to at least the given capacity. + */ + private void increaseSize(long capacity) { + size = capacity + growthMargin; } public void upload(MemoryBlock directBuffer) { FlwMemoryTracker._freeGPUMemory(size); - GlBufferType.COPY_WRITE_BUFFER.bind(handle()); - nglBufferData(GlBufferType.COPY_WRITE_BUFFER.glEnum, directBuffer.size(), directBuffer.ptr(), usage.glEnum); - this.size = directBuffer.size(); + IMPL.data(handle(), directBuffer.size(), directBuffer.ptr(), usage.glEnum); + size = directBuffer.size(); FlwMemoryTracker._allocGPUMemory(size); } @@ -91,16 +94,16 @@ public class GlBuffer extends GlObject { return new MappedBuffer(handle(), size); } - public void setGrowthMargin(int growthMargin) { + public void growthMargin(int growthMargin) { this.growthMargin = growthMargin; } - public long getSize() { + public long size() { return size; } protected void deleteInternal(int handle) { - glDeleteBuffers(handle); + GlStateManager._glDeleteBuffers(handle); FlwMemoryTracker._freeGPUMemory(size); } } diff --git a/src/main/java/com/jozufozu/flywheel/gl/buffer/MappedBuffer.java b/src/main/java/com/jozufozu/flywheel/gl/buffer/MappedBuffer.java index 4803d0fc8..7d54eda3b 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/buffer/MappedBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/gl/buffer/MappedBuffer.java @@ -1,10 +1,8 @@ package com.jozufozu.flywheel.gl.buffer; import static org.lwjgl.opengl.GL30.GL_MAP_WRITE_BIT; -import static org.lwjgl.opengl.GL30.nglMapBufferRange; import static org.lwjgl.system.MemoryUtil.NULL; -import org.lwjgl.opengl.GL15; import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.gl.error.GlError; @@ -17,8 +15,7 @@ public class MappedBuffer implements AutoCloseable { public MappedBuffer(int glBuffer, long size) { this.glBuffer = glBuffer; - GlBufferType.COPY_READ_BUFFER.bind(glBuffer); - ptr = nglMapBufferRange(GlBufferType.COPY_READ_BUFFER.glEnum, 0, size, GL_MAP_WRITE_BIT); + ptr = GlBuffer.IMPL.mapRange(glBuffer, 0, size, GL_MAP_WRITE_BIT); if (ptr == MemoryUtil.NULL) { throw new GlException(GlError.poll(), "Could not map buffer"); @@ -35,8 +32,7 @@ public class MappedBuffer implements AutoCloseable { return; } - GlBufferType.COPY_READ_BUFFER.bind(glBuffer); - GL15.glUnmapBuffer(GlBufferType.COPY_READ_BUFFER.glEnum); + GlBuffer.IMPL.unmap(glBuffer); ptr = NULL; } }