mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-15 00:36:08 +01:00
GlStateTracker for better state restore
- Replaces both ShaderInstanceAccessor and BufferUploaderAccessor
This commit is contained in:
parent
b6a00b54dd
commit
3391e3e168
11 changed files with 117 additions and 96 deletions
|
@ -0,0 +1,55 @@
|
||||||
|
package com.jozufozu.flywheel.backend.gl;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks bound buffers/vbos because GlStateManager doesn't do that for us.
|
||||||
|
*/
|
||||||
|
public class GlStateTracker {
|
||||||
|
|
||||||
|
private static final int[] buffers = new int[GlBufferType.values().length];
|
||||||
|
private static int vao;
|
||||||
|
private static int program;
|
||||||
|
|
||||||
|
public static int getBuffer(GlBufferType type) {
|
||||||
|
return buffers[type.ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getVertexArray() {
|
||||||
|
return vao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getProgram() {
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void _setBuffer(GlBufferType type, int buffer) {
|
||||||
|
buffers[type.ordinal()] = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void _setProgram(int id) {
|
||||||
|
program = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void _setVertexArray(int id) {
|
||||||
|
vao = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static State getRestoreState() {
|
||||||
|
return new State(buffers.clone(), vao, program);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static record State(int[] buffers, int vao, int program) {
|
||||||
|
public void restore() {
|
||||||
|
GlBufferType[] values = GlBufferType.values();
|
||||||
|
|
||||||
|
for (int i = 0; i < values.length; i++) {
|
||||||
|
GlStateManager._glBindBuffer(values[i].glEnum, buffers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlStateManager._glBindVertexArray(vao);
|
||||||
|
GlStateManager._glUseProgram(program);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import org.lwjgl.opengl.GL20;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.core.layout.LayoutItem;
|
import com.jozufozu.flywheel.core.layout.LayoutItem;
|
||||||
import com.jozufozu.flywheel.mixin.BufferUploaderAccessor;
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
public class GlVertexArray extends GlObject {
|
public class GlVertexArray extends GlObject {
|
||||||
|
@ -14,20 +13,14 @@ public class GlVertexArray extends GlObject {
|
||||||
|
|
||||||
public static void bind(int vao) {
|
public static void bind(int vao) {
|
||||||
GlStateManager._glBindVertexArray(vao);
|
GlStateManager._glBindVertexArray(vao);
|
||||||
BufferUploaderAccessor.flywheel$setLastVAO(vao);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind() {
|
public void bind() {
|
||||||
bind(handle());
|
bind(handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getBoundVertexArray() {
|
|
||||||
return BufferUploaderAccessor.flywheel$getLastVAO();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void unbind() {
|
public static void unbind() {
|
||||||
GlStateManager._glBindVertexArray(0);
|
GlStateManager._glBindVertexArray(0);
|
||||||
BufferUploaderAccessor.flywheel$setLastVAO(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableArrays(int count) {
|
public void enableArrays(int count) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.lwjgl.opengl.GL40;
|
||||||
import org.lwjgl.opengl.GL42;
|
import org.lwjgl.opengl.GL42;
|
||||||
import org.lwjgl.opengl.GL43;
|
import org.lwjgl.opengl.GL43;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.mixin.BufferUploaderAccessor;
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
public enum GlBufferType {
|
public enum GlBufferType {
|
||||||
|
@ -33,29 +33,34 @@ public enum GlBufferType {
|
||||||
this.glEnum = glEnum;
|
this.glEnum = glEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(int buffer) {
|
public static GlBufferType fromTarget(int pTarget) {
|
||||||
GlStateManager._glBindBuffer(glEnum, buffer);
|
return switch (pTarget) {
|
||||||
|
case GL15C.GL_ARRAY_BUFFER -> ARRAY_BUFFER;
|
||||||
|
case GL15C.GL_ELEMENT_ARRAY_BUFFER -> ELEMENT_ARRAY_BUFFER;
|
||||||
|
case GL21.GL_PIXEL_PACK_BUFFER -> PIXEL_PACK_BUFFER;
|
||||||
|
case GL21.GL_PIXEL_UNPACK_BUFFER -> PIXEL_UNPACK_BUFFER;
|
||||||
|
case GL30.GL_TRANSFORM_FEEDBACK_BUFFER -> TRANSFORM_FEEDBACK_BUFFER;
|
||||||
|
case GL31.GL_UNIFORM_BUFFER -> UNIFORM_BUFFER;
|
||||||
|
case GL31.GL_TEXTURE_BUFFER -> TEXTURE_BUFFER;
|
||||||
|
case GL31.GL_COPY_READ_BUFFER -> COPY_READ_BUFFER;
|
||||||
|
case GL31.GL_COPY_WRITE_BUFFER -> COPY_WRITE_BUFFER;
|
||||||
|
case GL40.GL_DRAW_INDIRECT_BUFFER -> DRAW_INDIRECT_BUFFER;
|
||||||
|
case GL42.GL_ATOMIC_COUNTER_BUFFER -> ATOMIC_COUNTER_BUFFER;
|
||||||
|
case GL43.GL_DISPATCH_INDIRECT_BUFFER -> DISPATCH_INDIRECT_BUFFER;
|
||||||
|
case GL43.GL_SHADER_STORAGE_BUFFER -> SHADER_STORAGE_BUFFER;
|
||||||
|
default -> throw new IllegalArgumentException("Unknown target: " + pTarget);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
switch (this.glEnum) {
|
public void bind(int buffer) {
|
||||||
case GL15C.GL_ELEMENT_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$setLastEBO(buffer);
|
GlStateManager._glBindBuffer(glEnum, buffer);
|
||||||
case GL15C.GL_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$setLastVBO(buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unbind() {
|
public void unbind() {
|
||||||
GlStateManager._glBindBuffer(glEnum, 0);
|
GlStateManager._glBindBuffer(glEnum, 0);
|
||||||
|
|
||||||
switch (this.glEnum) {
|
|
||||||
case GL15C.GL_ELEMENT_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$setLastEBO(0);
|
|
||||||
case GL15C.GL_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$setLastVBO(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBoundBuffer() {
|
public int getBoundBuffer() {
|
||||||
return switch (this.glEnum) {
|
return GlStateTracker.getBuffer(this);
|
||||||
case GL15C.GL_ELEMENT_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$getLastEBO();
|
|
||||||
case GL15C.GL_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$getLastVBO();
|
|
||||||
default -> -1;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import org.lwjgl.system.MemoryStack;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlObject;
|
import com.jozufozu.flywheel.backend.gl.GlObject;
|
||||||
import com.jozufozu.flywheel.mixin.ShaderInstanceAccessor;
|
|
||||||
import com.mojang.blaze3d.shaders.ProgramManager;
|
import com.mojang.blaze3d.shaders.ProgramManager;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
|
|
||||||
|
@ -29,14 +28,11 @@ public abstract class GlProgram extends GlObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind() {
|
public void bind() {
|
||||||
int handle = handle();
|
ProgramManager.glUseProgram(handle());
|
||||||
ProgramManager.glUseProgram(handle);
|
|
||||||
ShaderInstanceAccessor.flywheel$setLastProgramId(handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unbind() {
|
public static void unbind() {
|
||||||
ProgramManager.glUseProgram(0);
|
ProgramManager.glUseProgram(0);
|
||||||
ShaderInstanceAccessor.flywheel$setLastProgramId(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,8 +10,6 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialGroup;
|
import com.jozufozu.flywheel.api.MaterialGroup;
|
||||||
import com.jozufozu.flywheel.backend.RenderLayer;
|
import com.jozufozu.flywheel.backend.RenderLayer;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||||
import com.jozufozu.flywheel.core.WorldContext;
|
import com.jozufozu.flywheel.core.WorldContext;
|
||||||
|
@ -79,10 +77,6 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void render(TaskEngine taskEngine, RenderLayerEvent event) {
|
public void render(TaskEngine taskEngine, RenderLayerEvent event) {
|
||||||
int ebo = GlBufferType.ELEMENT_ARRAY_BUFFER.getBoundBuffer();
|
|
||||||
int vbo = GlBufferType.ARRAY_BUFFER.getBoundBuffer();
|
|
||||||
int vao = GlVertexArray.getBoundVertexArray();
|
|
||||||
|
|
||||||
double camX;
|
double camX;
|
||||||
double camY;
|
double camY;
|
||||||
double camZ;
|
double camZ;
|
||||||
|
@ -102,10 +96,6 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
getGroupsToRender(event.getLayer()).forEach(group -> group.render(viewProjection, camX, camY, camZ));
|
getGroupsToRender(event.getLayer()).forEach(group -> group.render(viewProjection, camX, camY, camZ));
|
||||||
|
|
||||||
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(ebo);
|
|
||||||
GlBufferType.ARRAY_BUFFER.bind(vbo);
|
|
||||||
GlVertexArray.bind(vao);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<InstancedMaterialGroup<P>> getGroupsToRender(@Nullable RenderLayer layer) {
|
private Stream<InstancedMaterialGroup<P>> getGroupsToRender(@Nullable RenderLayer layer) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class WorldProgram extends ExtensibleGlProgram {
|
||||||
|
|
||||||
super.bind();
|
super.bind();
|
||||||
registerSamplers();
|
registerSamplers();
|
||||||
super.unbind();
|
unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void registerSamplers() {
|
protected void registerSamplers() {
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package com.jozufozu.flywheel.mixin;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.BufferUploader;
|
|
||||||
|
|
||||||
@Mixin(BufferUploader.class)
|
|
||||||
public interface BufferUploaderAccessor {
|
|
||||||
@Accessor("lastVertexArrayObject")
|
|
||||||
static void flywheel$setLastVAO(int id) {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Accessor("lastVertexBufferObject")
|
|
||||||
static void flywheel$setLastVBO(int id) {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Accessor("lastIndexBufferObject")
|
|
||||||
static void flywheel$setLastEBO(int id) {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Accessor("lastIndexBufferObject")
|
|
||||||
static int flywheel$getLastEBO() {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Accessor("lastVertexBufferObject")
|
|
||||||
static int flywheel$getLastVBO() {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Accessor("lastVertexArrayObject")
|
|
||||||
static int flywheel$getLastVAO() {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.jozufozu.flywheel.mixin;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
|
@Mixin(GlStateManager.class)
|
||||||
|
public class GlStateManagerMixin {
|
||||||
|
|
||||||
|
@Inject(method = "_glBindBuffer", at = @At("TAIL"))
|
||||||
|
private static void onBindBuffer(int pTarget, int pBuffer, CallbackInfo ci) {
|
||||||
|
GlStateTracker._setBuffer(GlBufferType.fromTarget(pTarget), pBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "_glBindVertexArray", at = @At("TAIL"))
|
||||||
|
private static void onBindVertexArray(int pArray, CallbackInfo ci) {
|
||||||
|
GlStateTracker._setVertexArray(pArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "_glUseProgram", at = @At("TAIL"))
|
||||||
|
private static void onUseProgram(int pProgram, CallbackInfo ci) {
|
||||||
|
GlStateTracker._setProgram(pProgram);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer;
|
import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer;
|
||||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
|
@ -57,7 +58,11 @@ public class LevelRendererMixin {
|
||||||
|
|
||||||
RenderBuffers renderBuffers = this.renderBuffers;
|
RenderBuffers renderBuffers = this.renderBuffers;
|
||||||
|
|
||||||
|
GlStateTracker.State restoreState = GlStateTracker.getRestoreState();
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(level, type, stack, renderBuffers, camX, camY, camZ));
|
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(level, type, stack, renderBuffers, camX, camY, camZ));
|
||||||
|
|
||||||
|
restoreState.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At("TAIL"), method = "allChanged")
|
@Inject(at = @At("TAIL"), method = "allChanged")
|
||||||
|
@ -76,7 +81,9 @@ public class LevelRendererMixin {
|
||||||
|
|
||||||
Vec3 cameraPos = info.getPosition();
|
Vec3 cameraPos = info.getPosition();
|
||||||
|
|
||||||
|
GlStateTracker.State restoreState = GlStateTracker.getRestoreState();
|
||||||
CrumblingRenderer.renderBreaking(new RenderLayerEvent(level, null, stack, null, cameraPos.x, cameraPos.y, cameraPos.z));
|
CrumblingRenderer.renderBreaking(new RenderLayerEvent(level, null, stack, null, cameraPos.x, cameraPos.y, cameraPos.z));
|
||||||
|
restoreState.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instancing
|
// Instancing
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package com.jozufozu.flywheel.mixin;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.ShaderInstance;
|
|
||||||
|
|
||||||
@Mixin(ShaderInstance.class)
|
|
||||||
public interface ShaderInstanceAccessor {
|
|
||||||
@Accessor("lastProgramId")
|
|
||||||
static void flywheel$setLastProgramId(int id) {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,13 +7,13 @@
|
||||||
"client": [
|
"client": [
|
||||||
"BlockEntityTypeMixin",
|
"BlockEntityTypeMixin",
|
||||||
"BufferBuilderMixin",
|
"BufferBuilderMixin",
|
||||||
"BufferUploaderAccessor",
|
|
||||||
"CameraMixin",
|
"CameraMixin",
|
||||||
"CancelEntityRenderMixin",
|
"CancelEntityRenderMixin",
|
||||||
"ChunkRebuildHooksMixin",
|
"ChunkRebuildHooksMixin",
|
||||||
"EntityTypeMixin",
|
"EntityTypeMixin",
|
||||||
"FixFabulousDepthMixin",
|
"FixFabulousDepthMixin",
|
||||||
"FrustumMixin",
|
"FrustumMixin",
|
||||||
|
"GlStateManagerMixin",
|
||||||
"InstanceAddMixin",
|
"InstanceAddMixin",
|
||||||
"InstanceRemoveMixin",
|
"InstanceRemoveMixin",
|
||||||
"LevelRendererAccessor",
|
"LevelRendererAccessor",
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
"RenderTexturesMixin",
|
"RenderTexturesMixin",
|
||||||
"RenderTypeMixin",
|
"RenderTypeMixin",
|
||||||
"ShaderCloseMixin",
|
"ShaderCloseMixin",
|
||||||
"ShaderInstanceAccessor",
|
|
||||||
"atlas.AtlasDataMixin",
|
"atlas.AtlasDataMixin",
|
||||||
"atlas.SheetDataAccessor",
|
"atlas.SheetDataAccessor",
|
||||||
"light.LightUpdateMixin",
|
"light.LightUpdateMixin",
|
||||||
|
|
Loading…
Reference in a new issue