From 738514b86bda7148d00c3255a294637afcb55ed3 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Tue, 6 Sep 2022 08:49:48 -0700 Subject: [PATCH 01/11] Fresh loaded entities here! - Remove loaded chunk check from entity instance manager --- .../instancing/entity/EntityInstanceManager.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java index 60ece43f5..024073635 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java @@ -6,9 +6,7 @@ import com.jozufozu.flywheel.backend.instancing.AbstractInstance; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry; -import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; public class EntityInstanceManager extends InstanceManager { @@ -29,18 +27,13 @@ public class EntityInstanceManager extends InstanceManager { @Override protected boolean canCreateInstance(Entity entity) { - if (!entity.isAlive()) return false; + if (!entity.isAlive()) { + return false; + } Level world = entity.level; - if (Backend.isFlywheelWorld(world)) { - BlockPos pos = entity.blockPosition(); + return Backend.isFlywheelWorld(world); - BlockGetter existingChunk = world.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4); - - return existingChunk != null; - } - - return false; } } From 552c132512254047d41aeeb1e6c99ef71f5772d8 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Wed, 21 Sep 2022 15:34:58 -0700 Subject: [PATCH 02/11] Porting from all directions - Diagonal-port restore state changes from 1.18/next - Back-port buffer uploader changes and RenderLayerEvent dispatch point change from 1.19/dev - Make CrumblingRenderer return earlier if there is nothing to render - Bump version --- gradle.properties | 2 +- .../flywheel/backend/gl/GlStateTracker.java | 29 +++++++++---------- .../instancing/InstancingEngine.java | 5 ++++ .../core/crumbling/CrumblingRenderer.java | 18 +++++++++--- .../flywheel/mixin/BufferUploaderMixin.java | 29 ------------------- .../flywheel/mixin/LevelRendererMixin.java | 23 ++------------- src/main/resources/flywheel.mixins.json | 1 - 7 files changed, 37 insertions(+), 70 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderMixin.java diff --git a/gradle.properties b/gradle.properties index e9ca1f061..d01adbfc2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G org.gradle.daemon = false # mod version info -mod_version = 0.6.5 +mod_version = 0.6.6 artifact_minecraft_version = 1.18.2 minecraft_version = 1.18.2 diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java index eec0a4cf8..e63897fc6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java @@ -7,13 +7,12 @@ 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 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()]; + return BUFFERS[type.ordinal()]; } public static int getVertexArray() { @@ -24,36 +23,36 @@ public class GlStateTracker { 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 _setBuffer(GlBufferType type, int id) { + BUFFERS[type.ordinal()] = id; } public static void _setVertexArray(int id) { vao = id; } + public static void _setProgram(int id) { + program = id; + } + public static State getRestoreState() { - return new State(buffers.clone(), vao, program); + return new State(BUFFERS.clone(), vao, program); } public static record State(int[] buffers, int vao, int program) { public void restore() { + if (vao != GlStateTracker.vao) { + GlStateManager._glBindVertexArray(vao); + } + GlBufferType[] values = GlBufferType.values(); for (int i = 0; i < values.length; i++) { - if (buffers[i] != GlStateTracker.buffers[i]) { + if (buffers[i] != GlStateTracker.BUFFERS[i]) { GlStateManager._glBindBuffer(values[i].glEnum, buffers[i]); } } - if (vao != GlStateTracker.vao) { - GlStateManager._glBindVertexArray(vao); - } - if (program != GlStateTracker.program) { GlStateManager._glUseProgram(program); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index e3efc8a71..5e8c30a54 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -10,6 +10,7 @@ import javax.annotation.Nullable; import com.jozufozu.flywheel.api.MaterialGroup; import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.backend.gl.GlStateTracker; import com.jozufozu.flywheel.backend.instancing.Engine; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.core.compile.ProgramCompiler; @@ -73,6 +74,8 @@ public class InstancingEngine

implements Engine { */ @Override public void render(TaskEngine taskEngine, RenderLayerEvent event) { + GlStateTracker.State restoreState = GlStateTracker.getRestoreState(); + double camX; double camY; double camZ; @@ -92,6 +95,8 @@ public class InstancingEngine

implements Engine { } getGroupsToRender(event.getLayer()).forEach(group -> group.render(viewProjection, camX, camY, camZ, event.getLayer())); + + restoreState.restore(); } private Stream> getGroupsToRender(@Nullable RenderLayer layer) { diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java index e9aca9ff3..e15e91a4e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.SortedSet; import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.gl.GlStateTracker; import com.jozufozu.flywheel.backend.gl.GlTextureUnit; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine; @@ -16,6 +17,7 @@ import com.jozufozu.flywheel.mixin.LevelRendererAccessor; import com.jozufozu.flywheel.util.Lazy; import com.jozufozu.flywheel.util.Pair; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -30,6 +32,7 @@ import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.core.BlockPos; import net.minecraft.server.level.BlockDestructionProgress; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -54,13 +57,20 @@ public class CrumblingRenderer { INVALIDATOR = state.second(); } - public static void renderBreaking(RenderLayerEvent event) { - if (!Backend.canUseInstancing(event.getWorld())) return; - - Int2ObjectMap> activeStages = getActiveStageBlockEntities(event.getWorld()); + public static void render(ClientLevel level, Camera camera, PoseStack stack) { + if (!Backend.canUseInstancing(level)) return; + Int2ObjectMap> activeStages = getActiveStageBlockEntities(level); if (activeStages.isEmpty()) return; + Vec3 cameraPos = camera.getPosition(); + + GlStateTracker.State restoreState = GlStateTracker.getRestoreState(); + CrumblingRenderer.renderBreaking(activeStages, new RenderLayerEvent(level, null, stack, null, cameraPos.x, cameraPos.y, cameraPos.z)); + restoreState.restore(); + } + + private static void renderBreaking(Int2ObjectMap> activeStages, RenderLayerEvent event) { State state = STATE.get(); InstanceManager instanceManager = state.instanceManager; InstancingEngine materials = state.materialManager; diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderMixin.java deleted file mode 100644 index 7cd63581c..000000000 --- a/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.jozufozu.flywheel.mixin; - -import javax.annotation.Nullable; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -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.mojang.blaze3d.vertex.BufferUploader; -import com.mojang.blaze3d.vertex.VertexFormat; - -@Mixin(BufferUploader.class) -public class BufferUploaderMixin { - - @Shadow - @Nullable - private static VertexFormat lastFormat; - - @Inject(method = "reset", at = @At("HEAD")) - private static void stopBufferUploaderFromClearingBufferStateIfNothingIsBound(CallbackInfo ci) { - // Trust our tracker over BufferUploader's. - if (GlStateTracker.getVertexArray() == 0) { - lastFormat = null; - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java index 497a81ee5..f3838d4bc 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java @@ -10,13 +10,11 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.gl.GlStateTracker; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer; import com.jozufozu.flywheel.event.BeginFrameEvent; import com.jozufozu.flywheel.event.ReloadRenderersEvent; import com.jozufozu.flywheel.event.RenderLayerEvent; -import com.mojang.blaze3d.vertex.BufferUploader; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; @@ -30,7 +28,6 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.MinecraftForge; @@ -58,7 +55,7 @@ public class LevelRendererMixin { * This only gets injected if renderChunkLayer is not Overwritten */ @Group(name = "flywheel$renderLayer", min = 1, max = 2) - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ShaderInstance;clear()V"), method = "renderChunkLayer") + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiling/ProfilerFiller;pop()V", ordinal = 1), method = "renderChunkLayer") private void renderLayer(RenderType type, PoseStack stack, double camX, double camY, double camZ, Matrix4f p_172999_, CallbackInfo ci) { flywheel$renderLayer(type, stack, camX, camY, camZ); flywheel$LayerRendered = true; @@ -74,18 +71,11 @@ public class LevelRendererMixin { flywheel$renderLayer(type, stack, camX, camY, camZ); } flywheel$LayerRendered = false; - BufferUploader.reset(); } @Unique private void flywheel$renderLayer(RenderType type, PoseStack stack, double camX, double camY, double camZ) { - RenderBuffers renderBuffers = this.renderBuffers; - - GlStateTracker.State restoreState = GlStateTracker.getRestoreState(); - MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(level, type, stack, renderBuffers, camX, camY, camZ)); - - restoreState.restore(); } @Inject(at = @At("TAIL"), method = "allChanged") @@ -95,17 +85,10 @@ public class LevelRendererMixin { MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(level)); } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;checkPoseStack(Lcom/mojang/blaze3d/vertex/PoseStack;)V", ordinal = 2 // after the game renders the breaking overlay normally ), method = "renderLevel") - private void renderBlockBreaking(PoseStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, Camera info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, CallbackInfo ci) { - if (!Backend.isOn()) return; - - Vec3 cameraPos = info.getPosition(); - - GlStateTracker.State restoreState = GlStateTracker.getRestoreState(); - CrumblingRenderer.renderBreaking(new RenderLayerEvent(level, null, stack, null, cameraPos.x, cameraPos.y, cameraPos.z)); - restoreState.restore(); + private void renderBlockBreaking(PoseStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, CallbackInfo ci) { + CrumblingRenderer.render(level, camera, stack); } // Instancing diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json index cccc7ef58..7a674f5b3 100644 --- a/src/main/resources/flywheel.mixins.json +++ b/src/main/resources/flywheel.mixins.json @@ -8,7 +8,6 @@ "BlockEntityRenderDispatcherAccessor", "BlockEntityTypeMixin", "BufferBuilderMixin", - "BufferUploaderMixin", "CameraMixin", "ClientLevelMixin", "ChunkRebuildHooksMixin", From 2c7a6abcb6f2ecbac8d6f5f8c4379820ec374241 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Wed, 28 Sep 2022 20:05:41 -0700 Subject: [PATCH 03/11] Include new versions in bug report template --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ccdb88cfd..178413ce4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -59,6 +59,8 @@ body: label: Mod Version description: The version of the mod you were using when the bug occured options: + - "0.6.7" + - "0.6.6" - "0.6.5" - "0.6.4" - "0.6.3" @@ -90,6 +92,7 @@ body: label: Minecraft Version description: The version of Minecraft you were using when the bug occured options: + - "1.19.2" - "1.18.2" - "1.18.1" - "1.18" From 98e4831b6ef4ba6a1b4cd9722f4c67db7ee24f85 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sat, 22 Oct 2022 12:36:13 -0700 Subject: [PATCH 04/11] State your state - Address a few bugs with rubidium - Ignore EBOs when restoring state - ElementBuffer deals in raw gl handles - Document all state changes/restores/resets Co-authored-by: PepperCode1 <44146161+peppercode1@users.noreply.github.com> --- .../flywheel/backend/gl/GlStateTracker.java | 4 +- .../instancing/instancing/GPUInstancer.java | 5 + .../instancing/InstancedMaterialGroup.java | 23 ++- .../instancing/InstancingEngine.java | 1 + .../flywheel/backend/model/ElementBuffer.java | 26 +-- .../flywheel/backend/model/IndexedModel.java | 13 +- .../flywheel/backend/model/ModelPool.java | 10 +- .../flywheel/backend/model/VBOModel.java | 1 + .../jozufozu/flywheel/core/QuadConverter.java | 183 ++++++------------ .../core/crumbling/CrumblingGroup.java | 1 + .../core/crumbling/CrumblingRenderer.java | 5 + .../jozufozu/flywheel/core/model/Model.java | 1 + 12 files changed, 119 insertions(+), 154 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java index e63897fc6..77749e8c7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java @@ -39,7 +39,7 @@ public class GlStateTracker { return new State(BUFFERS.clone(), vao, program); } - public static record State(int[] buffers, int vao, int program) { + public record State(int[] buffers, int vao, int program) { public void restore() { if (vao != GlStateTracker.vao) { GlStateManager._glBindVertexArray(vao); @@ -48,7 +48,7 @@ public class GlStateTracker { GlBufferType[] values = GlBufferType.values(); for (int i = 0; i < values.length; i++) { - if (buffers[i] != GlStateTracker.BUFFERS[i]) { + if (buffers[i] != GlStateTracker.BUFFERS[i] && values[i] != GlBufferType.ELEMENT_ARRAY_BUFFER) { GlStateManager._glBindBuffer(values[i].glEnum, buffers[i]); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index 4b469c02f..a127b8e30 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java @@ -45,6 +45,7 @@ public class GPUInstancer extends AbstractInstancer { public void render() { if (invalid()) return; + // XXX VAO is bound and not reset or restored vao.bind(); renderSetup(); @@ -68,12 +69,15 @@ public class GPUInstancer extends AbstractInstancer { vao = new GlVertexArray(); + // XXX Callback seems unnecessary. Remove and extract code to run after alloc call? model = modelAllocator.alloc(modelData, arenaModel -> { + // XXX VAO is bound and not reset or restored vao.bind(); arenaModel.setupState(vao); }); + // XXX VAO is already guaranteed to be bound in model callback vao.bind(); vao.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount()); @@ -108,6 +112,7 @@ public class GPUInstancer extends AbstractInstancer { removeDeletedInstances(); } + // XXX ARRAY_BUFFER is bound and reset instanceVBO.bind(); if (!realloc()) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java index 2bc228ed9..b132596ca 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java @@ -68,15 +68,23 @@ public class InstancedMaterialGroup

implements MaterialG return vertexCount; } + // XXX Overriden in CrumblingGroup + // XXX Runs inside of restore state public void render(Matrix4f viewProjection, double camX, double camY, double camZ, RenderLayer layer) { type.setupRenderState(); - Textures.bindActiveTextures(); - renderAll(viewProjection, camX, camY, camZ, layer); + Textures.bindActiveTextures(); // XXX Changes active unit and bound textures + renderAll(viewProjection, camX, camY, camZ, layer); // XXX May change ARRAY_BUFFER binding (reset or not reset), VAO binding (not reset), shader binding (not reset), call Model.createEBO type.clearRenderState(); + // XXX Should texture bindings be reset or restored? + // XXX Should the active unit be reset or restored? + // XXX Should the VAO binding be reset or restored? + // XXX Should the ARRAY_BUFFER binding be reset or restored? + // XXX Should the shader binding be reset or restored? } + // XXX Internal GL state changes are inconsistent; sometimes bindings are reset to 0, sometimes not protected void renderAll(Matrix4f viewProjection, double camX, double camY, double camZ, RenderLayer layer) { - initializeInstancers(); + initializeInstancers(); // XXX May change ARRAY_BUFFER binding (reset or not reset), VAO binding (not reset), call Model.createEBO vertexCount = 0; instanceCount = 0; @@ -88,6 +96,7 @@ public class InstancedMaterialGroup

implements MaterialG P program = owner.context.getProgram(ProgramContext.create(entry.getKey() .getProgramSpec(), Formats.POS_TEX_NORMAL, layer)); + // XXX Shader is bound and not reset or restored program.bind(); program.uploadViewProjection(viewProjection); program.uploadCameraPos(camX, camY, camZ); @@ -95,7 +104,7 @@ public class InstancedMaterialGroup

implements MaterialG setup(program); for (GPUInstancer instancer : material.getAllInstancers()) { - instancer.render(); + instancer.render(); // XXX May change VAO binding (not reset), ARRAY_BUFFER binding (reset) vertexCount += instancer.getVertexCount(); instanceCount += instancer.getInstanceCount(); } @@ -103,19 +112,19 @@ public class InstancedMaterialGroup

implements MaterialG } private void initializeInstancers() { - ModelAllocator allocator = getModelAllocator(); + ModelAllocator allocator = getModelAllocator(); // XXX May change ARRAY_BUFFER binding (not reset) // initialize all uninitialized instancers... for (InstancedMaterial material : materials.values()) { for (GPUInstancer instancer : material.uninitialized) { - instancer.init(allocator); + instancer.init(allocator); // XXX May change VAO binding (not reset), ARRAY_BUFFER binding (not reset), call Model.createEBO } material.uninitialized.clear(); } if (allocator instanceof ModelPool pool) { // ...and then flush the model arena in case anything was marked for upload - pool.flush(); + pool.flush(); // XXX May change ARRAY_BUFFER binding (reset) } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index 5e8c30a54..2708f474d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -74,6 +74,7 @@ public class InstancingEngine

implements Engine { */ @Override public void render(TaskEngine taskEngine, RenderLayerEvent event) { + // XXX Restore state GlStateTracker.State restoreState = GlStateTracker.getRestoreState(); double camX; diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ElementBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/model/ElementBuffer.java index 8227ad019..07ce772d3 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ElementBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/ElementBuffer.java @@ -1,25 +1,29 @@ package com.jozufozu.flywheel.backend.model; -import com.jozufozu.flywheel.backend.gl.GlNumericType; -import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; +import com.mojang.blaze3d.vertex.VertexFormat; public class ElementBuffer { - private final GlBuffer buffer; - public final int elementCount; - public final GlNumericType eboIndexType; + protected final int elementCount; + protected final VertexFormat.IndexType eboIndexType; + private final int glBuffer; - public ElementBuffer(GlBuffer backing, int elementCount, GlNumericType indexType) { - this.buffer = backing; - this.eboIndexType = indexType; + public ElementBuffer(int backing, int elementCount, VertexFormat.IndexType indexType) { this.elementCount = elementCount; + this.eboIndexType = indexType; + this.glBuffer = backing; } public void bind() { - buffer.bind(); + GlBufferType.ELEMENT_ARRAY_BUFFER.bind(glBuffer); } - public void unbind() { - buffer.unbind(); + public int getElementCount() { + return elementCount; + } + + public VertexFormat.IndexType getEboIndexType() { + return eboIndexType; } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java index 7a372b0c8..3d3e79814 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java @@ -52,27 +52,26 @@ public class IndexedModel implements BufferedModel { * The VBO/VAO should be bound externally. */ public void setupState(GlVertexArray vao) { + // XXX ARRAY_BUFFER is bound and not reset or restored vbo.bind(); vao.enableArrays(getAttributeCount()); vao.bindAttributes(0, getType().getLayout()); + ebo.bind(); } @Override public void drawCall() { - ebo.bind(); - GL20.glDrawElements(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0); + GL20.glDrawElements(primitiveMode.glEnum, ebo.getElementCount(), ebo.getEboIndexType().asGLType, 0); } /** - * Draws many instances of this model, assuming the appropriate state is already bound. - */ + * Draws many instances of this model, assuming the appropriate state is already bound. + */ @Override public void drawInstances(int instanceCount) { if (!valid()) return; - ebo.bind(); - - GL31.glDrawElementsInstanced(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, instanceCount); + GL31.glDrawElementsInstanced(primitiveMode.glEnum, ebo.getElementCount(), ebo.getEboIndexType().asGLType, 0, instanceCount); } public boolean isDeleted() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java b/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java index 5c1d426c7..3d7d330e5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java @@ -42,6 +42,7 @@ public class ModelPool implements ModelAllocator { vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER); + // XXX ARRAY_BUFFER is bound and not reset or restored vbo.bind(); vbo.setGrowthMargin(stride * 64); } @@ -68,6 +69,7 @@ public class ModelPool implements ModelAllocator { if (dirty) { if (anyToRemove) processDeletions(); + // XXX ARRAY_BUFFER is bound and reset vbo.bind(); if (realloc()) { uploadAll(); @@ -182,25 +184,25 @@ public class ModelPool implements ModelAllocator { @Override public void setupState(GlVertexArray vao) { + // XXX ARRAY_BUFFER is bound and not reset or restored vbo.bind(); vao.enableArrays(getAttributeCount()); vao.bindAttributes(0, vertexType.getLayout()); + ebo.bind(); } @Override public void drawCall() { - GL32.glDrawElementsBaseVertex(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, first); + GL32.glDrawElementsBaseVertex(GlPrimitive.TRIANGLES.glEnum, ebo.getElementCount(), ebo.getEboIndexType().asGLType, 0, first); } @Override public void drawInstances(int instanceCount) { if (!valid()) return; - ebo.bind(); - //Backend.log.info(StringUtil.args("drawElementsInstancedBaseVertex", GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, instanceCount, first)); - GL32.glDrawElementsInstancedBaseVertex(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, instanceCount, first); + GL32.glDrawElementsInstancedBaseVertex(GlPrimitive.TRIANGLES.glEnum, ebo.getElementCount(), ebo.getEboIndexType().asGLType, 0, instanceCount, first); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java index 54dccbd28..e51832a63 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java @@ -58,6 +58,7 @@ public class VBOModel implements BufferedModel { * The VBO/VAO should be bound externally. */ public void setupState(GlVertexArray vao) { + // XXX ARRAY_BUFFER is bound and not reset or restored vbo.bind(); vao.enableArrays(getAttributeCount()); vao.bindAttributes(0, getLayout()); diff --git a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java index d1871224b..37ba431b7 100644 --- a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java +++ b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java @@ -1,43 +1,32 @@ package com.jozufozu.flywheel.core; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.EnumMap; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import org.lwjgl.system.MemoryStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.opengl.GL32; +import org.lwjgl.opengl.GL32C; 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.GlBufferType; -import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage; import com.jozufozu.flywheel.backend.model.ElementBuffer; import com.jozufozu.flywheel.event.ReloadRenderersEvent; +import com.mojang.blaze3d.vertex.VertexFormat; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; +import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ReferenceMap; /** * A class to manage EBOs that index quads as triangles. */ -@Mod.EventBusSubscriber(Dist.CLIENT) public class QuadConverter { - public static final int STARTING_CAPACITY = 42; // 255 / 6 = 42 - private static QuadConverter INSTANCE; - @Nonnull + @NotNull public static QuadConverter getInstance() { if (INSTANCE == null) { - INSTANCE = new QuadConverter(STARTING_CAPACITY); + INSTANCE = new QuadConverter(); } return INSTANCE; @@ -48,130 +37,78 @@ public class QuadConverter { return INSTANCE; } - Map ebos; - int[] capacities; + private final Int2ReferenceMap cache = new Int2ReferenceArrayMap<>(); + private final int ebo; + private int quadCapacity; - public QuadConverter(int initialCapacity) { - this.ebos = new EnumMap<>(GlNumericType.class); - initCapacities(); - - fillBuffer(initialCapacity); + public QuadConverter() { + this.ebo = GL32.glGenBuffers(); + this.quadCapacity = 0; } public ElementBuffer quads2Tris(int quads) { - int indexCount = quads * 6; - GlNumericType type = getSmallestIndexType(indexCount); - - if (quads > getCapacity(type)) { - fillBuffer(quads, indexCount, type); + if (quads > quadCapacity) { + grow(quads * 2); } - return new ElementBuffer(getBuffer(type), indexCount, type); + return cache.computeIfAbsent(quads, this::createElementBuffer); } - private void initCapacities() { - this.capacities = new int[GlNumericType.values().length]; + @NotNull + private ElementBuffer createElementBuffer(int quads) { + return new ElementBuffer(ebo, quads * 6, VertexFormat.IndexType.INT); } - private int getCapacity(GlNumericType type) { - return capacities[type.ordinal()]; - } + private void grow(int quads) { + int byteSize = quads * 6 * GlNumericType.UINT.getByteWidth(); + final long ptr = MemoryUtil.nmemAlloc(byteSize); - private void updateCapacity(GlNumericType type, int capacity) { - if (getCapacity(type) < capacity) { - capacities[type.ordinal()] = capacity; - } + fillBuffer(ptr, quads); + + // XXX ARRAY_BUFFER is bound and reset + final var bufferType = GlBufferType.ARRAY_BUFFER; + final int oldBuffer = bufferType.getBoundBuffer(); + bufferType.bind(ebo); + GL32C.nglBufferData(bufferType.glEnum, byteSize, ptr, GlBufferUsage.STATIC_DRAW.glEnum); + bufferType.bind(oldBuffer); + + MemoryUtil.nmemFree(ptr); + + this.quadCapacity = quads; } public void delete() { - ebos.values() - .forEach(GlBuffer::delete); - ebos.clear(); - initCapacities(); + GL32.glDeleteBuffers(ebo); + this.quadCapacity = 0; } - private void fillBuffer(int quads) { - int indexCount = quads * 6; + private void fillBuffer(long ptr, int quads) { + int numVertices = 4 * quads; + int baseVertex = 0; + while (baseVertex < numVertices) { + writeQuadIndicesUnsafe(ptr, baseVertex); - fillBuffer(quads, indexCount, getSmallestIndexType(indexCount)); - } - - private void fillBuffer(int quads, int indexCount, GlNumericType type) { - MemoryStack stack = MemoryStack.stackPush(); - int bytes = indexCount * type.getByteWidth(); - - ByteBuffer indices; - if (bytes > stack.getSize()) { - indices = MemoryUtil.memAlloc(bytes); // not enough space on the preallocated stack - } else { - stack.push(); - indices = stack.malloc(bytes); + baseVertex += 4; + ptr += 6 * 4; } - - indices.order(ByteOrder.nativeOrder()); - - fillBuffer(indices, type, quads); - - GlBuffer buffer = getBuffer(type); - - buffer.bind(); - buffer.upload(indices); - buffer.unbind(); - - if (bytes > stack.getSize()) { - MemoryUtil.memFree(indices); - } else { - stack.pop(); - } - - updateCapacity(type, quads); } - private void fillBuffer(ByteBuffer indices, GlNumericType type, int quads) { - for (int i = 0, max = 4 * quads; i < max; i += 4) { - // triangle a - type.castAndBuffer(indices, i); - type.castAndBuffer(indices, i + 1); - type.castAndBuffer(indices, i + 2); - // triangle b - type.castAndBuffer(indices, i); - type.castAndBuffer(indices, i + 2); - type.castAndBuffer(indices, i + 3); - } - ((Buffer) indices).flip(); + private void writeQuadIndicesUnsafe(long ptr, int baseVertex) { + // triangle a + MemoryUtil.memPutInt(ptr, baseVertex); + MemoryUtil.memPutInt(ptr + 4, baseVertex + 1); + MemoryUtil.memPutInt(ptr + 8, baseVertex + 2); + // triangle b + MemoryUtil.memPutInt(ptr + 12, baseVertex); + MemoryUtil.memPutInt(ptr + 16, baseVertex + 2); + MemoryUtil.memPutInt(ptr + 20, baseVertex + 3); } - private GlBuffer getBuffer(GlNumericType type) { - return ebos.computeIfAbsent(type, $ -> new MappedGlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER)); - } - - /** - * Given the needed number of indices, what is the smallest bit width type that can index everything?
- * - *

-	 * | indexCount   | type  |
-	 * |--------------|-------|
-	 * | [0, 255)     | byte  |
-	 * | [256, 65536)	| short	|
-	 * | [65537, )	| int	|
-	 * 
- */ - private static GlNumericType getSmallestIndexType(int indexCount) { -// indexCount = indexCount >>> 8; -// if (indexCount == 0) { -// return GlNumericType.UBYTE; -// } -// indexCount = indexCount >>> 8; -// if (indexCount == 0) { -// return GlNumericType.USHORT; -// } - - return GlNumericType.UINT; - } - - // make sure this gets reset first so it has a chance to repopulate - @SubscribeEvent(priority = EventPriority.HIGHEST) + // make sure this gets reset first, so it has a chance to repopulate public static void onRendererReload(ReloadRenderersEvent event) { - if (INSTANCE != null) INSTANCE.delete(); + if (INSTANCE != null) { + INSTANCE.delete(); + INSTANCE = null; + } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java index ee113de17..0378b6ee6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java @@ -18,6 +18,7 @@ public class CrumblingGroup

extends InstancedMateria super(owner, type); } + // XXX See notes of overriden method @Override public void render(Matrix4f viewProjection, double camX, double camY, double camZ, RenderLayer layer) { type.setupRenderState(); diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java index e15e91a4e..1455eb25e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java @@ -65,6 +65,7 @@ public class CrumblingRenderer { Vec3 cameraPos = camera.getPosition(); + // XXX Restore state GlStateTracker.State restoreState = GlStateTracker.getRestoreState(); CrumblingRenderer.renderBreaking(activeStages, new RenderLayerEvent(level, null, stack, null, cameraPos.x, cameraPos.y, cameraPos.z)); restoreState.restore(); @@ -87,6 +88,7 @@ public class CrumblingRenderer { instanceManager.beginFrame(SerialTaskEngine.INSTANCE, info); + // XXX Each call applies another restore state even though we are already inside of a restore state materials.render(SerialTaskEngine.INSTANCE, event); instanceManager.invalidate(); @@ -94,6 +96,9 @@ public class CrumblingRenderer { } + // XXX Inconsistent GL state cleanup + // If texture binding and active unit need to be restored, store them in variables before GL state is changed + // instead of guessing that unit 0 and crumbling tex 0 are correct GlTextureUnit.T0.makeActive(); AbstractTexture breaking = textureManager.getTexture(ModelBakery.BREAKING_LOCATIONS.get(0)); if (breaking != null) RenderSystem.bindTexture(breaking.getId()); diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Model.java index eacfd3394..e94d983ec 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Model.java @@ -46,6 +46,7 @@ public interface Model { return Formats.POS_TEX_NORMAL; } + // XXX Since this is public API (technically) we cannot make assumptions about what GL state this method can use or modify unless a contract is established. /** * Create an element buffer object that indexes the vertices of this model. * From edd6c736cf614ac4f99ae9f06fe2fa3c56d56361 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Sun, 6 Nov 2022 14:00:24 -0800 Subject: [PATCH 05/11] Models are temporary - Add Model.delete - Allow BlockModel.createEBO to be called more than once for a single instance - Clear cache on QuadConverter.delete --- .../backend/instancing/instancing/GPUInstancer.java | 3 +-- .../com/jozufozu/flywheel/core/QuadConverter.java | 1 + .../jozufozu/flywheel/core/hardcoded/ModelPart.java | 11 +++++++++++ .../com/jozufozu/flywheel/core/model/BlockModel.java | 11 +++++++++++ .../java/com/jozufozu/flywheel/core/model/Model.java | 2 ++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index a127b8e30..d3522ac81 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java @@ -69,7 +69,6 @@ public class GPUInstancer extends AbstractInstancer { vao = new GlVertexArray(); - // XXX Callback seems unnecessary. Remove and extract code to run after alloc call? model = modelAllocator.alloc(modelData, arenaModel -> { // XXX VAO is bound and not reset or restored vao.bind(); @@ -77,7 +76,7 @@ public class GPUInstancer extends AbstractInstancer { arenaModel.setupState(vao); }); - // XXX VAO is already guaranteed to be bound in model callback + // XXX VAO is bound and not reset or restored vao.bind(); vao.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount()); diff --git a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java index 37ba431b7..266f15489 100644 --- a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java +++ b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java @@ -79,6 +79,7 @@ public class QuadConverter { public void delete() { GL32.glDeleteBuffers(ebo); + this.cache.clear(); this.quadCapacity = 0; } diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java index 67bdeb798..3b1ded7a6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java @@ -51,4 +51,15 @@ public class ModelPart implements Model { public VertexList getReader() { return reader; } + + @Override + public void delete() { + if (reader instanceof AutoCloseable closeable) { + try { + closeable.close(); + } catch (Exception e) { + // + } + } + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java index 8c527bea6..fdfee66d2 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java @@ -47,4 +47,15 @@ public class BlockModel implements Model { public VertexList getReader() { return reader; } + + @Override + public void delete() { + if (reader instanceof AutoCloseable closeable) { + try { + closeable.close(); + } catch (Exception e) { + // + } + } + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Model.java index e94d983ec..55066c90a 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Model.java @@ -62,6 +62,8 @@ public interface Model { .quads2Tris(vertexCount() / 4); } + void delete(); + /** * The size in bytes that this model's data takes up. */ From b76e8b1a897aee8fad878dca4c046bdbf544f3e9 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Thu, 10 Nov 2022 16:30:30 -0800 Subject: [PATCH 06/11] A bit of backporting - Backport general changes from 1.19 - Fix Javadoc of PartialModel - Remove default Model#getType implementation - Increment version to 0.6.8 - Update Parchment --- .editorconfig | 11 ++++++ .github/ISSUE_TEMPLATE/bug_report.yml | 1 + build.gradle | 1 + gradle.properties | 4 +- .../backend/gl/buffer/MappedBuffer.java | 2 +- .../backend/instancing/InstanceManager.java | 11 ++++++ .../backend/model/FallbackAllocator.java | 3 +- .../flywheel/backend/model/IndexedModel.java | 11 +++++- .../jozufozu/flywheel/core/PartialModel.java | 4 +- .../flywheel/core/hardcoded/ModelPart.java | 6 +++ .../flywheel/core/model/BlockModel.java | 23 +++++++++--- .../jozufozu/flywheel/core/model/Model.java | 5 +-- .../flywheel/core/model/WorldModel.java | 37 ------------------- .../core/model/WorldModelBuilder.java | 4 +- .../core/vertex/AbstractVertexList.java | 10 ----- .../flywheel/core/vertex/BlockVertexList.java | 17 ++++----- .../jozufozu/flywheel/event/ForgeEvents.java | 2 - .../flywheel/mixin/ClientMainMixin.java | 28 ++++++++++++++ .../flywheel/mixin/LevelRendererMixin.java | 29 +-------------- .../ChunkRebuildHooksMixin.java | 2 +- .../InstanceAddMixin.java | 2 +- .../InstanceRemoveMixin.java | 2 +- src/main/resources/flywheel.mixins.json | 7 ++-- 23 files changed, 111 insertions(+), 111 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java create mode 100644 src/main/java/com/jozufozu/flywheel/mixin/ClientMainMixin.java rename src/main/java/com/jozufozu/flywheel/mixin/{ => instancemanage}/ChunkRebuildHooksMixin.java (96%) rename src/main/java/com/jozufozu/flywheel/mixin/{ => instancemanage}/InstanceAddMixin.java (95%) rename src/main/java/com/jozufozu/flywheel/mixin/{ => instancemanage}/InstanceRemoveMixin.java (96%) diff --git a/.editorconfig b/.editorconfig index 1eeca6433..f1abc2e0c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,6 +13,17 @@ insert_final_newline = true [*.json] indent_style = space indent_size = 2 +max_line_length = 500 +ij_json_keep_blank_lines_in_code = 0 +ij_json_keep_indents_on_empty_lines = false +ij_json_keep_line_breaks = true +ij_json_space_after_colon = true +ij_json_space_after_comma = true +ij_json_space_before_colon = true +ij_json_space_before_comma = false +ij_json_spaces_within_braces = true +ij_json_spaces_within_brackets = false +ij_json_wrap_long_lines = false [*.java] indent_style = tab diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 178413ce4..468b474f5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -59,6 +59,7 @@ body: label: Mod Version description: The version of the mod you were using when the bug occured options: + - "0.6.8" - "0.6.7" - "0.6.6" - "0.6.5" diff --git a/build.gradle b/build.gradle index 586d9cd02..9ca4ec111 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,7 @@ minecraft { property 'mixin.debug.export', 'true' property 'mixin.env.remapRefMap', 'true' property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" + property 'flw.loadRenderDoc', 'true' arg '-mixin.config=flywheel.mixins.json' diff --git a/gradle.properties b/gradle.properties index d01adbfc2..b43169cd6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G org.gradle.daemon = false # mod version info -mod_version = 0.6.6 +mod_version = 0.6.8 artifact_minecraft_version = 1.18.2 minecraft_version = 1.18.2 @@ -14,7 +14,7 @@ mixingradle_version = 0.7-SNAPSHOT mixin_version = 0.8.5 librarian_version = 1.+ cursegradle_version = 1.4.0 -parchment_version = 2022.07.10 +parchment_version = 2022.11.06 # curseforge info projectId = 486392 diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java index 25155a1d0..c95a398cb 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java @@ -39,7 +39,7 @@ public class MappedBuffer extends VecBuffer implements AutoCloseable { } @Override - public void close() throws Exception { + public void close() { flush(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java index 1f8310d1e..7743fb0b8 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java @@ -1,6 +1,7 @@ package com.jozufozu.flywheel.backend.instancing; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -359,4 +360,14 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift LightUpdater.get(value.world).removeListener(value); } } + + public void queueAddAll(Collection objects) { + if (!Backend.isOn() || objects.isEmpty()) { + return; + } + + synchronized (queuedAdditions) { + queuedAdditions.addAll(objects); + } + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java b/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java index 7520afff2..42d1a67df 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.backend.model; +import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.model.Model; public enum FallbackAllocator implements ModelAllocator { @@ -7,7 +8,7 @@ public enum FallbackAllocator implements ModelAllocator { @Override public BufferedModel alloc(Model model, Callback allocationCallback) { - IndexedModel out = new IndexedModel(model); + IndexedModel out = new IndexedModel(model, Formats.POS_TEX_NORMAL); allocationCallback.onAlloc(out); return out; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java index 3d3e79814..580ded8b5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java @@ -20,6 +20,7 @@ import com.jozufozu.flywheel.core.model.Model; */ public class IndexedModel implements BufferedModel { + protected final VertexType type; protected final Model model; protected final GlPrimitive primitiveMode; protected ElementBuffer ebo; @@ -27,6 +28,11 @@ public class IndexedModel implements BufferedModel { protected boolean deleted; public IndexedModel(Model model) { + this(model, model.getType()); + } + + public IndexedModel(Model model, VertexType type) { + this.type = type; this.model = model; this.primitiveMode = GlPrimitive.TRIANGLES; @@ -38,7 +44,8 @@ public class IndexedModel implements BufferedModel { // mirror it in system memory, so we can write to it, and upload our model. try (MappedBuffer buffer = vbo.getBuffer()) { - model.writeInto(buffer.unwrap()); + type.createWriter(buffer.unwrap()) + .writeVertexList(model.getReader()); } catch (Exception e) { Flywheel.LOGGER.error(String.format("Error uploading model '%s':", model.name()), e); } @@ -80,7 +87,7 @@ public class IndexedModel implements BufferedModel { @Override public VertexType getType() { - return model.getType(); + return type; } public int getVertexCount() { diff --git a/src/main/java/com/jozufozu/flywheel/core/PartialModel.java b/src/main/java/com/jozufozu/flywheel/core/PartialModel.java index 6340e8441..20b1567f5 100644 --- a/src/main/java/com/jozufozu/flywheel/core/PartialModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/PartialModel.java @@ -14,12 +14,12 @@ import net.minecraftforge.client.model.ForgeModelBakery; * A helper class for loading and accessing json models. *
* Creating a PartialModel will make the associated modelLocation automatically load. - * PartialModels must be initialized during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent FMLClientSetupEvent}. + * PartialModels must be initialized the mod class constructor. *
* Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations) * will have their bakedModel fields populated. *
- * Attempting to create a PartialModel after ModelRegistryEvent will cause an error. + * Attempting to create a PartialModel after {@link ModelRegistryEvent} will cause an error. */ public class PartialModel { diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java index 3b1ded7a6..25546213e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java @@ -3,6 +3,7 @@ package com.jozufozu.flywheel.core.hardcoded; import java.util.List; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.model.Model; import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe; @@ -52,6 +53,11 @@ public class ModelPart implements Model { return reader; } + @Override + public VertexType getType() { + return Formats.POS_TEX_NORMAL; + } + @Override public void delete() { if (reader instanceof AutoCloseable closeable) { diff --git a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java index fdfee66d2..76e23da8f 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java @@ -1,6 +1,7 @@ package com.jozufozu.flywheel.core.model; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.Formats; import com.mojang.blaze3d.vertex.PoseStack; @@ -12,10 +13,8 @@ import net.minecraft.world.level.block.state.BlockState; * A model of a single block. */ public class BlockModel implements Model { - private static final PoseStack IDENTITY = new PoseStack(); private final VertexList reader; - private final String name; public BlockModel(BlockState state) { @@ -25,12 +24,21 @@ public class BlockModel implements Model { } public BlockModel(BakedModel model, BlockState referenceState) { - this(model, referenceState, IDENTITY); + this(new BakedModelBuilder(model).withReferenceState(referenceState), referenceState.toString()); } public BlockModel(BakedModel model, BlockState referenceState, PoseStack ms) { - reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilder(model, referenceState, ms)); - name = referenceState.toString(); + this(new BakedModelBuilder(model).withReferenceState(referenceState) + .withPoseStack(ms), referenceState.toString()); + } + + public BlockModel(Bufferable bufferable, String name) { + this(bufferable.build(), name); + } + + public BlockModel(ShadeSeparatedBufferBuilder bufferBuilder, String name) { + this.name = name; + reader = Formats.BLOCK.createReader(bufferBuilder); } @Override @@ -48,6 +56,11 @@ public class BlockModel implements Model { return reader; } + @Override + public VertexType getType() { + return Formats.BLOCK; + } + @Override public void delete() { if (reader instanceof AutoCloseable closeable) { diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Model.java index 55066c90a..b0d31a15f 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Model.java @@ -5,7 +5,6 @@ import java.nio.ByteBuffer; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.model.ElementBuffer; -import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.QuadConverter; /** @@ -42,9 +41,7 @@ public interface Model { */ int vertexCount(); - default VertexType getType() { - return Formats.POS_TEX_NORMAL; - } + VertexType getType(); // XXX Since this is public API (technically) we cannot make assumptions about what GL state this method can use or modify unless a contract is established. /** diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java deleted file mode 100644 index c144f43c6..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.jozufozu.flywheel.core.model; - -import com.jozufozu.flywheel.api.vertex.VertexList; -import com.jozufozu.flywheel.api.vertex.VertexType; -import com.jozufozu.flywheel.core.Formats; -import com.mojang.blaze3d.vertex.BufferBuilder; - -public class WorldModel implements Model { - - private final VertexList reader; - private final String name; - - public WorldModel(BufferBuilder bufferBuilder, String name) { - this.reader = Formats.BLOCK.createReader(bufferBuilder); - this.name = name; - } - - @Override - public String name() { - return name; - } - - @Override - public VertexType getType() { - return Formats.BLOCK; - } - - @Override - public int vertexCount() { - return reader.getVertexCount(); - } - - @Override - public VertexList getReader() { - return reader; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java index 38bda7d1c..fa209c2d6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java @@ -80,7 +80,7 @@ public final class WorldModelBuilder implements Bufferable { return this; } - public WorldModel intoMesh(String name) { - return new WorldModel(ModelUtil.getBufferBuilder(this), name); + public BlockModel intoMesh(String name) { + return new BlockModel(ModelUtil.getBufferBuilder(this), name); } } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java index a68e0c943..97475da4c 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java @@ -7,7 +7,6 @@ import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.vertex.VertexList; import com.mojang.blaze3d.platform.MemoryTracker; -import com.mojang.blaze3d.vertex.BufferBuilder; public abstract class AbstractVertexList implements VertexList, AutoCloseable { @@ -22,15 +21,6 @@ public abstract class AbstractVertexList implements VertexList, AutoCloseable { init(copyFrom); } - public AbstractVertexList(BufferBuilder builder) { - var pair = builder.popNextBuffer(); - ByteBuffer copyFrom = pair.getSecond(); - this.contents = MemoryTracker.create(copyFrom.capacity()); - this.vertexCount = pair.getFirst().vertexCount(); - this.base = MemoryUtil.memAddress(this.contents); - init(copyFrom); - } - private void init(ByteBuffer copyFrom) { this.contents.order(copyFrom.order()); this.contents.put(copyFrom); diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java index f84385f78..ef46bdf36 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java @@ -1,18 +1,17 @@ package com.jozufozu.flywheel.core.vertex; +import java.nio.ByteBuffer; + import com.jozufozu.flywheel.api.vertex.ShadedVertexList; -import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder; import com.jozufozu.flywheel.util.RenderMath; -import com.mojang.blaze3d.vertex.BufferBuilder; public class BlockVertexList extends AbstractVertexList { private final int stride; - public BlockVertexList(BufferBuilder builder) { - super(builder); - this.stride = builder.getVertexFormat() - .getVertexSize(); + public BlockVertexList(ByteBuffer copyFrom, int vertexCount, int stride) { + super(copyFrom, vertexCount); + this.stride = stride; } @Override @@ -93,9 +92,9 @@ public class BlockVertexList extends AbstractVertexList { private final int unshadedStartVertex; - public Shaded(ShadeSeparatedBufferBuilder builder) { - super(builder); - unshadedStartVertex = builder.getUnshadedStartVertex(); + public Shaded(ByteBuffer copyFrom, int vertexCount, int stride, int unshadedStartVertex) { + super(copyFrom, vertexCount, stride); + this.unshadedStartVertex = unshadedStartVertex; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java index 056966700..2fdd3d4b9 100644 --- a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java +++ b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java @@ -18,9 +18,7 @@ public class ForgeEvents { @SubscribeEvent public static void addToDebugScreen(RenderGameOverlayEvent.Text event) { - if (Minecraft.getInstance().options.renderDebug) { - InstancedRenderDispatcher.getDebugString(event.getRight()); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ClientMainMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ClientMainMixin.java new file mode 100644 index 000000000..e753a1a83 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/ClientMainMixin.java @@ -0,0 +1,28 @@ +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 net.minecraft.client.main.Main; + +@Mixin(Main.class) +public class ClientMainMixin { + + @Inject(method = "main", at = @At("HEAD")) + private static void injectRenderDoc(CallbackInfo ci) { + // Only try to load RenderDoc if a system property is set. + if (System.getProperty("flw.loadRenderDoc") == null) { + return; + } + + try { + System.loadLibrary("renderdoc"); + } catch (Throwable ignored) { + // Oh well, we tried. + // On Windows, RenderDoc installs to "C:\Program Files\RenderDoc\" + System.err.println("Is RenderDoc in your PATH?"); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java index f3838d4bc..f4895c7f8 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java @@ -3,9 +3,7 @@ package com.jozufozu.flywheel.mixin; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Group; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -48,33 +46,8 @@ public class LevelRendererMixin { MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(level, camera, frustum)); } - @Unique - private boolean flywheel$LayerRendered; - - /** - * This only gets injected if renderChunkLayer is not Overwritten - */ - @Group(name = "flywheel$renderLayer", min = 1, max = 2) - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiling/ProfilerFiller;pop()V", ordinal = 1), method = "renderChunkLayer") - private void renderLayer(RenderType type, PoseStack stack, double camX, double camY, double camZ, Matrix4f p_172999_, CallbackInfo ci) { - flywheel$renderLayer(type, stack, camX, camY, camZ); - flywheel$LayerRendered = true; - } - - /** - * This always gets injected. - */ - @Group(name = "flywheel$renderLayer") @Inject(at = @At("TAIL"), method = "renderChunkLayer") - private void renderLayerSodium(RenderType type, PoseStack stack, double camX, double camY, double camZ, Matrix4f p_172999_, CallbackInfo ci) { - if (!flywheel$LayerRendered) { - flywheel$renderLayer(type, stack, camX, camY, camZ); - } - flywheel$LayerRendered = false; - } - - @Unique - private void flywheel$renderLayer(RenderType type, PoseStack stack, double camX, double camY, double camZ) { + private void renderLayer(RenderType type, PoseStack stack, double camX, double camY, double camZ, Matrix4f projection, CallbackInfo ci) { MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(level, type, stack, renderBuffers, camX, camY, camZ)); } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java similarity index 96% rename from src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java rename to src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java index a4accbe24..e16d78545 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.mixin; +package com.jozufozu.flywheel.mixin.instancemanage; import java.util.Set; diff --git a/src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java similarity index 95% rename from src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java rename to src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java index b28fbfa84..7568c28e9 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.mixin; +package com.jozufozu.flywheel.mixin.instancemanage; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java similarity index 96% rename from src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java rename to src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java index 0ee0fd088..1d115cfda 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.mixin; +package com.jozufozu.flywheel.mixin.instancemanage; import javax.annotation.Nullable; diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json index 7a674f5b3..b6c311ea6 100644 --- a/src/main/resources/flywheel.mixins.json +++ b/src/main/resources/flywheel.mixins.json @@ -10,13 +10,11 @@ "BufferBuilderMixin", "CameraMixin", "ClientLevelMixin", - "ChunkRebuildHooksMixin", + "ClientMainMixin", "EntityTypeMixin", "FixFabulousDepthMixin", "FrustumMixin", "GlStateManagerMixin", - "InstanceAddMixin", - "InstanceRemoveMixin", "LevelRendererAccessor", "LevelRendererMixin", "PausedPartialTickAccessor", @@ -24,6 +22,9 @@ "RenderTypeMixin", "atlas.AtlasDataMixin", "atlas.SheetDataAccessor", + "instancemanage.ChunkRebuildHooksMixin", + "instancemanage.InstanceAddMixin", + "instancemanage.InstanceRemoveMixin", "light.LightUpdateMixin", "light.NetworkLightUpdateMixin", "matrix.Matrix3fMixin", From 7fe2ca08c1419165eca24d222ac66ceec1c0d627 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Tue, 22 Nov 2022 13:04:03 -0800 Subject: [PATCH 07/11] Models are (actually) temporary - Call Model#delete on instancer delete - Add constraint to modelSupplier in Material#model - Fix memory leak in ModelPart - Add ArrayModelRenderer#getModel --- .../java/com/jozufozu/flywheel/api/Material.java | 1 + .../instancing/batching/BatchedMaterial.java | 5 +++++ .../instancing/batching/BatchedMaterialGroup.java | 3 +++ .../instancing/batching/BatchingEngine.java | 4 +++- .../backend/instancing/batching/CPUInstancer.java | 4 ++++ .../instancing/instancing/GPUInstancer.java | 2 ++ .../instancing/instancing/InstancedMaterial.java | 14 +++++++------- .../instancing/instancing/InstancingEngine.java | 1 - .../flywheel/backend/model/ArrayModelRenderer.java | 4 ++++ .../flywheel/core/hardcoded/ModelPart.java | 7 ++++++- .../flywheel/core/model/WorldModelBuilder.java | 2 +- 11 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/api/Material.java b/src/main/java/com/jozufozu/flywheel/api/Material.java index f6a963cf7..69956a8e0 100644 --- a/src/main/java/com/jozufozu/flywheel/api/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/Material.java @@ -19,6 +19,7 @@ public interface Material { * * @param key An object that uniquely identifies the model. * @param modelSupplier A factory that creates the Model that you want to render. + * Each time {@link Supplier#get()} is called, a new Model must be created. * @return An instancer for the given model, capable of rendering many copies for little cost. */ Instancer model(Object key, Supplier modelSupplier); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java index cf97a5b1b..4e256f08c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java @@ -42,4 +42,9 @@ public class BatchedMaterial implements Material { models.values() .forEach(CPUInstancer::clear); } + + public void delete() { + models.values().forEach(CPUInstancer::delete); + models.clear(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index 37787e7c6..16aa5402e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -67,6 +67,9 @@ public class BatchedMaterialGroup implements MaterialGroup { } public void delete() { + materials.values() + .forEach(BatchedMaterial::delete); + materials.clear(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java index aa6e7f683..04220410a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java @@ -64,11 +64,13 @@ public class BatchingEngine implements Engine { @Override public void delete() { + for (Map groups : layers.values()) { + groups.values().forEach(BatchedMaterialGroup::delete); + } } @Override public void beginFrame(Camera info) { - } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java index 828827103..f4f052875 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java @@ -73,4 +73,8 @@ public class CPUInstancer extends AbstractInstancer { public void notifyDirty() { // noop } + + public void delete() { + modelData.delete(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index d3522ac81..448e319d4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java @@ -104,6 +104,8 @@ public class GPUInstancer extends AbstractInstancer { instanceVBO.delete(); vao.delete(); + + modelData.delete(); } protected void renderSetup() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java index 7a8373136..344917388 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java @@ -43,6 +43,10 @@ public class InstancedMaterial implements Material { }); } + public Collection> getAllInstancers() { + return models.values(); + } + public int getInstanceCount() { return models.values().stream().mapToInt(GPUInstancer::getInstanceCount).sum(); } @@ -57,11 +61,6 @@ public class InstancedMaterial implements Material { .allMatch(GPUInstancer::isEmpty); } - public void delete() { - models.values().forEach(GPUInstancer::delete); - models.clear(); - } - /** * Clear all instance data without freeing resources. */ @@ -70,7 +69,8 @@ public class InstancedMaterial implements Material { .forEach(GPUInstancer::clear); } - public Collection> getAllInstancers() { - return models.values(); + public void delete() { + models.values().forEach(GPUInstancer::delete); + models.clear(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index 2708f474d..4edc1b951 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -116,7 +116,6 @@ public class InstancingEngine

implements Engine { @Override public void delete() { for (Map> groups : layers.values()) { - groups.values().forEach(InstancedMaterialGroup::delete); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java index f190aa103..241638e43 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java @@ -14,6 +14,10 @@ public class ArrayModelRenderer { this.model = model; } + public Model getModel() { + return model; + } + /** * Renders this model, checking first if there is anything to render. */ diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java index 25546213e..b58f4ec7b 100644 --- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java @@ -1,7 +1,10 @@ package com.jozufozu.flywheel.core.hardcoded; +import java.nio.ByteBuffer; import java.util.List; +import org.lwjgl.system.MemoryUtil; + import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.Formats; @@ -26,12 +29,14 @@ public class ModelPart implements Model { this.vertices = vertices; } - PosTexNormalWriterUnsafe writer = Formats.POS_TEX_NORMAL.createWriter(MemoryTracker.create(size())); + ByteBuffer buffer = MemoryTracker.create(size()); + PosTexNormalWriterUnsafe writer = Formats.POS_TEX_NORMAL.createWriter(buffer); for (PartBuilder.CuboidBuilder cuboid : cuboids) { cuboid.buffer(writer); } reader = writer.intoReader(); + MemoryUtil.memFree(buffer); } public static PartBuilder builder(String name, int sizeU, int sizeV) { diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java index fa209c2d6..f4b8f1912 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java @@ -81,6 +81,6 @@ public final class WorldModelBuilder implements Bufferable { } public BlockModel intoMesh(String name) { - return new BlockModel(ModelUtil.getBufferBuilder(this), name); + return new BlockModel(this, name); } } From d3b09ecb144d0cfb86e9f78ea47988cd701d77d0 Mon Sep 17 00:00:00 2001 From: Marc Hermans Date: Thu, 1 Dec 2022 21:24:11 +0100 Subject: [PATCH 08/11] Switch to the block vertex format. --- .../backend/instancing/instancing/InstancedMaterialGroup.java | 4 ++-- .../jozufozu/flywheel/backend/model/FallbackAllocator.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java index b132596ca..dd0802559 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java @@ -94,7 +94,7 @@ public class InstancedMaterialGroup

implements MaterialG if (material.nothingToRender()) continue; P program = owner.context.getProgram(ProgramContext.create(entry.getKey() - .getProgramSpec(), Formats.POS_TEX_NORMAL, layer)); + .getProgramSpec(), Formats.BLOCK, layer)); // XXX Shader is bound and not reset or restored program.bind(); @@ -155,7 +155,7 @@ public class InstancedMaterialGroup

implements MaterialG .onAMDWindows()) { return FallbackAllocator.INSTANCE; } else { - return new ModelPool(Formats.POS_TEX_NORMAL); + return new ModelPool(Formats.BLOCK); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java b/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java index 42d1a67df..28d203d1f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java @@ -8,7 +8,7 @@ public enum FallbackAllocator implements ModelAllocator { @Override public BufferedModel alloc(Model model, Callback allocationCallback) { - IndexedModel out = new IndexedModel(model, Formats.POS_TEX_NORMAL); + IndexedModel out = new IndexedModel(model, Formats.BLOCK); allocationCallback.onAlloc(out); return out; } From f5acaeb1d79d34373e927b2ed03bef5794a248b9 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Wed, 14 Dec 2022 09:16:21 -0800 Subject: [PATCH 09/11] Update changelog.txt --- changelog.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/changelog.txt b/changelog.txt index c7781fb32..9ccbe5e24 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,28 @@ +0.6.8: +Fixes + - Fix colored vertices being incorrectly rendered through instancing + - Fix some miscellaneous bugs with sodium/rubidium + - Fix memory leak associated with model storage +Technical/API + - Memory for models is freed when they are no longer in use + - Element buffers now deal in raw gl handles + - Element buffers are no longer considered part of state resoration + - Quad -> Tri element buffer properly resets itself + +0.6.7: +...is 1.19 only :ioa: + +0.6.6: +Fixes + - Fix instanced entities not rendering correctly when chunk loading is slow +Technical/API + - GL state is more reliably managed + - Slight memory improvements when using Iris/Oculus through lazy instatiation + +0.6.5: +Fixes + - Fix crash with batching backend and Rubidium + 0.6.4: Fixes - Fix shader detection with oculus From d96ad156e132c491825225b64dd9f1d485c95bba Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Sat, 31 Dec 2022 14:34:59 -0800 Subject: [PATCH 10/11] Fix IndexedModel allocating incorrect amount of bytes - model.size() returned the byte size relative to the model's VertexType, but the byte size relative to the passed VertexType is needed instead --- .../java/com/jozufozu/flywheel/backend/model/IndexedModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java index 580ded8b5..7187bb7c0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java @@ -40,7 +40,7 @@ public class IndexedModel implements BufferedModel { vbo.bind(); // allocate the buffer on the gpu - vbo.ensureCapacity(model.size()); + vbo.ensureCapacity(type.byteOffset(model.vertexCount())); // mirror it in system memory, so we can write to it, and upload our model. try (MappedBuffer buffer = vbo.getBuffer()) { From 3034d3d9b549c24a01c9bcb8e58d621c39732046 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:08:32 -0800 Subject: [PATCH 11/11] Increment version --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + gradle.properties | 2 +- src/main/resources/META-INF/mods.toml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 468b474f5..3dbe6f0b0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -59,6 +59,7 @@ body: label: Mod Version description: The version of the mod you were using when the bug occured options: + - "0.6.8.a" - "0.6.8" - "0.6.7" - "0.6.6" diff --git a/gradle.properties b/gradle.properties index b43169cd6..c870cce22 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G org.gradle.daemon = false # mod version info -mod_version = 0.6.8 +mod_version = 0.6.8.a artifact_minecraft_version = 1.18.2 minecraft_version = 1.18.2 diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 1ca2ff67b..3ddcc67c7 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -10,7 +10,7 @@ version = "${file.jarVersion}" displayName = "Flywheel" logoFile = "logo.png" displayURL = "https://www.curseforge.com/minecraft/mc-mods/flywheel" -updateJSONURL = "https://api.modrinth.com/updates/5lpsZoRi/forge_updates.json" +updateJSONURL = "https://api.modrinth.com/updates/flywheel/forge_updates.json" authors = "Jozufozu" description = ''' A modern engine for modded minecraft.'''