Enuf enums

- Remove GlVersioned abstraction in favor of explicit fallback
- Remove versioned.BufferStorage
This commit is contained in:
Jozufozu 2023-05-01 21:57:12 -07:00
parent f1f289124d
commit b1a1120764
5 changed files with 91 additions and 202 deletions

View file

@ -73,7 +73,7 @@ public class GlVertexArray extends GlObject {
offsets[index] = startOffset;
strides[index] = stride;
GlCompat.vertexArray.setupAttrib(handle(), stride, vbo, startOffset, attribute, index);
GlCompat.vertexArray.setupAttrib(handle(), index, vbo, stride, startOffset, attribute);
startOffset += attribute.getByteWidth();
}

View file

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

View file

@ -1,7 +1,6 @@
package com.jozufozu.flywheel.gl.versioned;
import java.nio.ByteBuffer;
import java.util.Optional;
import org.lwjgl.PointerBuffer;
import org.lwjgl.opengl.GL;
@ -20,14 +19,12 @@ import net.minecraft.Util;
public class GlCompat {
private static final GLCapabilities caps;
public static final VertexArray vertexArray;
public static final BufferStorage bufferStorage;
public static final boolean amd;
public static final boolean supportsIndirect;
static {
caps = GL.createCapabilities();
bufferStorage = getLatest(BufferStorage.class);
vertexArray = getLatest(VertexArray.class);
vertexArray = VertexArray.DSA.INSTANCE.fallback(caps);
supportsIndirect = _decideIfWeSupportIndirect();
amd = _decideIfWeAreAMDWindows();
}
@ -40,7 +37,7 @@ public class GlCompat {
}
public static boolean supportsInstancing() {
return vertexArray != VertexArray.UNSUPPORTED;
return caps.OpenGL33 || caps.GL_ARB_instanced_arrays;
}
public static boolean supportsIndirect() {
@ -56,23 +53,6 @@ public class GlCompat {
caps.GL_ARB_direct_state_access);
}
/**
* Get the most compatible version of a specific OpenGL feature by iterating over enum constants in order.
*
* @param <V> The type of the versioning enum.
* @param clazz The class of the versioning enum.
* @return The first defined enum variant to return true.
*/
private static <V extends Enum<V> & GlVersioned> V getLatest(Class<V> clazz) {
for (V it : clazz.getEnumConstants()) {
if (it.supported(GlCompat.caps)) {
return Optional.of(it)
.get();
}
}
throw new IllegalStateException("Invalid versioned enum, must provide at least one supported constant");
}
/**
* Modified from:
* <br> <a href="https://github.com/grondag/canvas/commit/820bf754092ccaf8d0c169620c2ff575722d7d96">canvas</a>

View file

@ -1,17 +0,0 @@
package com.jozufozu.flywheel.gl.versioned;
import org.lwjgl.opengl.GLCapabilities;
/**
* This interface should be implemented by enums such that the
* last defined variant <em>always</em> returns {@code true}
*/
public interface GlVersioned {
/**
* Queries whether this variant is supported by the current system.
*
* @param caps The {@link GLCapabilities} reported by the current system.
* @return <code>true</code> if this variant is supported, or if this is the last defined variant.
*/
boolean supported(GLCapabilities caps);
}

View file

@ -1,24 +1,98 @@
package com.jozufozu.flywheel.gl.versioned;
import org.lwjgl.opengl.ARBInstancedArrays;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL33;
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.GlStateTracker;
import com.jozufozu.flywheel.gl.array.VertexAttribute;
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
import com.mojang.blaze3d.platform.GlStateManager;
public enum VertexArray implements GlVersioned {
DSA {
public interface VertexArray {
int create();
void setElementBuffer(int vao, int elementBuffer);
void setupAttrib(int vao, int index, int vbo, int stride, long offset, VertexAttribute attribute);
void setAttribDivisor(int vao, int attrib, int divisor);
abstract class GL3 implements VertexArray {
@Override
public boolean supported(GLCapabilities caps) {
// The static methods from GL45 and ARBDirectStateAccess all point to GL45C.
return caps.OpenGL45 || caps.GL_ARB_direct_state_access;
public int create() {
return GL30C.glGenVertexArrays();
}
@Override
public void setElementBuffer(int vao, int elementBuffer) {
if (vao != GlStateTracker.getVertexArray()) {
GlStateManager._glBindVertexArray(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);
GL20C.glEnableVertexAttribArray(index);
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);
}
ARBInstancedArrays.glVertexAttribDivisorARB(attrib, divisor);
}
public VertexArray fallback(GLCapabilities caps) {
return isSupported(caps) ? this : null;
}
private boolean isSupported(GLCapabilities caps) {
return Checks.checkFunctions(caps.glVertexAttribDivisorARB);
}
}
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);
}
GL33C.glVertexAttribDivisor(attrib, divisor);
}
public VertexArray fallback(GLCapabilities caps) {
return isSupported(caps) ? this : InstancedArraysARB.INSTANCE.fallback(caps);
}
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();
@ -30,7 +104,7 @@ public enum VertexArray implements GlVersioned {
}
@Override
public void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index) {
public void setupAttrib(int vao, int index, int vbo, int stride, long offset, VertexAttribute attribute) {
GL45C.glEnableVertexArrayAttrib(vao, index);
GL45C.glVertexArrayVertexBuffer(vao, index, vbo, offset, stride);
attribute.setupDSA(vao, index);
@ -40,115 +114,13 @@ public enum VertexArray implements GlVersioned {
public void setAttribDivisor(int vao, int attrib, int divisor) {
GL45C.glVertexArrayBindingDivisor(vao, attrib, divisor);
}
},
GL_33 {
@Override
public boolean supported(GLCapabilities caps) {
return caps.OpenGL33;
public VertexArray fallback(GLCapabilities caps) {
return isSupported(caps) ? this : InstancedArraysCore.INSTANCE.fallback(caps);
}
@Override
public int create() {
return GL33.glGenVertexArrays();
private static boolean isSupported(GLCapabilities caps) {
return Checks.checkFunctions(caps.glCreateVertexArrays, caps.glVertexArrayElementBuffer, caps.glEnableVertexArrayAttrib, caps.glVertexArrayVertexBuffer, caps.glVertexArrayBindingDivisor, caps.glVertexArrayAttribFormat, caps.glVertexArrayAttribIFormat);
}
@Override
public void setElementBuffer(int vao, int elementBuffer) {
if (vao != GlStateTracker.getVertexArray()) {
GlStateManager._glBindVertexArray(vao);
}
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(elementBuffer);
}
@Override
public void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index) {
if (vao != GlStateTracker.getVertexArray()) {
GlStateManager._glBindVertexArray(vao);
}
GlBufferType.ARRAY_BUFFER.bind(vbo);
GL33.glEnableVertexAttribArray(index);
attribute.setup(offset, index, stride);
}
@Override
public void setAttribDivisor(int vao, int attrib, int divisor) {
if (vao != GlStateTracker.getVertexArray()) {
GlStateManager._glBindVertexArray(vao);
}
GL33.glVertexAttribDivisor(attrib, divisor);
}
},
ARB_INSTANCED_ARRAYS {
@Override
public boolean supported(GLCapabilities caps) {
return caps.GL_ARB_instanced_arrays;
}
@Override
public int create() {
return GL30.glGenVertexArrays();
}
@Override
public void setElementBuffer(int vao, int elementBuffer) {
if (vao != GlStateTracker.getVertexArray()) {
GlStateManager._glBindVertexArray(vao);
}
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(elementBuffer);
}
@Override
public void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index) {
if (vao != GlStateTracker.getVertexArray()) {
GlStateManager._glBindVertexArray(vao);
}
GlBufferType.ARRAY_BUFFER.bind(vbo);
GL30.glEnableVertexAttribArray(index);
attribute.setup(offset, index, stride);
}
@Override
public void setAttribDivisor(int vao, int attrib, int divisor) {
if (vao != GlStateTracker.getVertexArray()) {
GlStateManager._glBindVertexArray(vao);
}
ARBInstancedArrays.glVertexAttribDivisorARB(attrib, divisor);
}
},
UNSUPPORTED {
@Override
public boolean supported(GLCapabilities caps) {
return true;
}
@Override
public int create() {
throw new UnsupportedOperationException("Cannot use vertex arrays");
}
@Override
public void setElementBuffer(int vao, int elementBuffer) {
throw new UnsupportedOperationException("Cannot use vertex arrays");
}
@Override
public void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index) {
throw new UnsupportedOperationException("Cannot use vertex arrays");
}
@Override
public void setAttribDivisor(int vao, int attrib, int divisor) {
throw new UnsupportedOperationException("Cannot use vertex arrays");
}
};
public abstract int create();
public abstract void setElementBuffer(int vao, int elementBuffer);
public abstract void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index);
public abstract void setAttribDivisor(int vao, int attrib, int divisor);
}
}