diff --git a/.editorconfig b/.editorconfig index 2c468ead4..6319172a3 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 a4a763b61..2e779635d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -60,6 +60,10 @@ body: description: The version of the mod you were using when the bug occured options: - "0.7.0" + - "0.6.8.a" + - "0.6.8" + - "0.6.7" + - "0.6.6" - "0.6.5" - "0.6.4" - "0.6.3" @@ -91,6 +95,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" 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 diff --git a/gradle.properties b/gradle.properties index 79c69ac95..f84cf5fd1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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/GlStateTracker.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java index fc978eb90..830467b2f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java @@ -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/gl/array/GlVertexArray.java b/src/main/java/com/jozufozu/flywheel/backend/gl/array/GlVertexArray.java index d2ba0d15a..a93ae4682 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/array/GlVertexArray.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/array/GlVertexArray.java @@ -137,12 +137,11 @@ public class GlVertexArray extends GlObject { } } - public void bindElementArray(GlBuffer ebo) { - int handle = ebo.handle(); - if (elementBufferBinding != handle) { + public void bindElementArray(int ebo) { + if (elementBufferBinding != ebo) { bind(); - GlBufferType.ELEMENT_ARRAY_BUFFER.bind(handle); - elementBufferBinding = handle; + GlBufferType.ELEMENT_ARRAY_BUFFER.bind(ebo); + elementBufferBinding = ebo; } } } 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 d8e88904a..7cce94249 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,8 @@ 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; import java.util.Set; @@ -261,4 +263,14 @@ public abstract class InstanceManager { LightUpdater.get(value.level).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/instancing/entity/EntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java index 33e42b155..04779dfb5 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 @@ -9,9 +9,7 @@ import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry; import com.jozufozu.flywheel.backend.instancing.One2OneStorage; -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 { @@ -44,14 +42,6 @@ public class EntityInstanceManager extends InstanceManager { Level level = entity.level; - if (Backend.isFlywheelLevel(level)) { - BlockPos pos = entity.blockPosition(); - - BlockGetter existingChunk = level.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4); - - return existingChunk != null; - } - - return false; + return Backend.isFlywheelLevel(level); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectCullingGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectCullingGroup.java index fe426247d..ae3f47c9b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectCullingGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectCullingGroup.java @@ -62,7 +62,7 @@ public class IndirectCullingGroup { vertexArray = glCreateVertexArrays(); elementBuffer = QuadConverter.getInstance() - .quads2Tris(2048).buffer.handle(); + .quads2Tris(2048).glBuffer; setupVertexArray(); compute = ComputeCullerCompiler.INSTANCE.get(structType); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/ElementBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/ElementBuffer.java index 4164b6261..e22ce8c85 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/ElementBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/ElementBuffer.java @@ -1,17 +1,29 @@ package com.jozufozu.flywheel.backend.instancing.instancing; -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 { - public final GlBuffer buffer; - public final int elementCount; - public final GlNumericType eboIndexType; + protected final int elementCount; + protected final VertexFormat.IndexType eboIndexType; + public 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() { + GlBufferType.ELEMENT_ARRAY_BUFFER.bind(glBuffer); + } + + public int getElementCount() { + return elementCount; + } + + public VertexFormat.IndexType getEboIndexType() { + return eboIndexType; } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMeshPool.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMeshPool.java index 329fbc04b..0dcc8eccc 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMeshPool.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMeshPool.java @@ -228,15 +228,15 @@ public class InstancedMeshPool { vao.enableArrays(getAttributeCount()); vao.bindAttributes(InstancedMeshPool.this.vbo, 0, vertexType.getLayout(), byteIndex); } - vao.bindElementArray(ebo.buffer); + vao.bindElementArray(ebo.glBuffer); vao.bind(); } private void draw(int instanceCount) { if (instanceCount > 1) { - GL32.glDrawElementsInstanced(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, instanceCount); + GL32.glDrawElementsInstanced(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0, instanceCount); } else { - GL32.glDrawElements(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0); + GL32.glDrawElements(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingDrawManager.java index 06fdfa886..6bd7d40f1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingDrawManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingDrawManager.java @@ -27,11 +27,11 @@ public class InstancingDrawManager { private final Map, GPUInstancer> instancers = new HashMap<>(); private final List uninitializedInstancers = new ArrayList<>(); private final List> initializedInstancers = new ArrayList<>(); - private final Map drawDets = new EnumMap<>(RenderStage.class); + private final Map drawSets = new EnumMap<>(RenderStage.class); private final Map meshPools = new HashMap<>(); public DrawSet get(RenderStage stage) { - return drawDets.getOrDefault(stage, DrawSet.EMPTY); + return drawSets.getOrDefault(stage, DrawSet.EMPTY); } @SuppressWarnings("unchecked") @@ -67,9 +67,9 @@ public class InstancingDrawManager { .forEach(InstancedMeshPool::delete); meshPools.clear(); - drawDets.values() + drawSets.values() .forEach(DrawSet::delete); - drawDets.clear(); + drawSets.clear(); initializedInstancers.forEach(GPUInstancer::delete); initializedInstancers.clear(); @@ -80,7 +80,7 @@ public class InstancingDrawManager { } private void add(GPUInstancer instancer, Model model, RenderStage stage) { - DrawSet drawSet = drawDets.computeIfAbsent(stage, DrawSet::new); + DrawSet drawSet = drawSets.computeIfAbsent(stage, DrawSet::new); var meshes = model.getMeshes(); for (var entry : meshes.entrySet()) { DrawCall drawCall = new DrawCall(instancer, entry.getKey(), alloc(entry.getValue())); diff --git a/src/main/java/com/jozufozu/flywheel/core/PartialModel.java b/src/main/java/com/jozufozu/flywheel/core/PartialModel.java index 64572104a..47c6d2900 100644 --- a/src/main/java/com/jozufozu/flywheel/core/PartialModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/PartialModel.java @@ -16,12 +16,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/QuadConverter.java b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java index ca6c74322..fe3b1a98a 100644 --- a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java +++ b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java @@ -2,14 +2,19 @@ package com.jozufozu.flywheel.core; 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.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage; import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer; import com.jozufozu.flywheel.event.ReloadRenderersEvent; +import com.mojang.blaze3d.vertex.VertexFormat; + +import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ReferenceMap; /** * A class to manage EBOs that index quads as triangles. @@ -32,56 +37,71 @@ public class QuadConverter { return INSTANCE; } - private final GlBuffer ebo; + private final Int2ReferenceMap cache = new Int2ReferenceArrayMap<>(); + private final int ebo; private int quadCapacity; public QuadConverter() { - this.ebo = new GlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER); + this.ebo = GL32.glGenBuffers(); this.quadCapacity = 0; } public ElementBuffer quads2Tris(int quads) { - int indexCount = quads * 6; - if (quads > quadCapacity) { - ebo.ensureCapacity((long) indexCount * GlNumericType.UINT.getByteWidth()); - - try (MappedBuffer map = ebo.map()) { - fillBuffer(map.getPtr(), quads); - } - ebo.unbind(); - - this.quadCapacity = quads; + grow(quads * 2); } - return new ElementBuffer(ebo, indexCount, GlNumericType.UINT); + return cache.computeIfAbsent(quads, this::createElementBuffer); + } + + @NotNull + private ElementBuffer createElementBuffer(int quads) { + return new ElementBuffer(ebo, quads * 6, VertexFormat.IndexType.INT); + } + + private void grow(int quads) { + int byteSize = quads * 6 * GlNumericType.UINT.getByteWidth(); + final long ptr = MemoryUtil.nmemAlloc(byteSize); + + fillBuffer(ptr, quads); + + 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() { - ebo.delete(); + GL32.glDeleteBuffers(ebo); + this.cache.clear(); this.quadCapacity = 0; } - private void fillBuffer(long addr, int quads) { + private void fillBuffer(long ptr, int quads) { int numVertices = 4 * quads; int baseVertex = 0; while (baseVertex < numVertices) { - writeQuadIndices(addr, baseVertex); + writeQuadIndicesUnsafe(ptr, baseVertex); baseVertex += 4; - addr += 6 * 4; + ptr += 6 * 4; } } - private void writeQuadIndices(long addr, int baseVertex) { + private void writeQuadIndicesUnsafe(long ptr, int baseVertex) { // triangle a - MemoryUtil.memPutInt(addr, baseVertex); - MemoryUtil.memPutInt(addr + 4, baseVertex + 1); - MemoryUtil.memPutInt(addr + 8, baseVertex + 2); + MemoryUtil.memPutInt(ptr, baseVertex); + MemoryUtil.memPutInt(ptr + 4, baseVertex + 1); + MemoryUtil.memPutInt(ptr + 8, baseVertex + 2); // triangle b - MemoryUtil.memPutInt(addr + 12, baseVertex); - MemoryUtil.memPutInt(addr + 16, baseVertex + 2); - MemoryUtil.memPutInt(addr + 20, baseVertex + 3); + MemoryUtil.memPutInt(ptr + 12, baseVertex); + MemoryUtil.memPutInt(ptr + 16, baseVertex + 2); + MemoryUtil.memPutInt(ptr + 20, baseVertex + 3); } // make sure this gets reset first, so it has a chance to repopulate 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 95% rename from src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java rename to src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java index 3436cb033..559ac6ba9 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 e33205c2e..7ca54cb1c 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 a7c1f1285..2630faa34 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 org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; 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.''' diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json index 502c4882d..e72ceff1d 100644 --- a/src/main/resources/flywheel.mixins.json +++ b/src/main/resources/flywheel.mixins.json @@ -8,21 +8,21 @@ "BlockEntityRenderDispatcherAccessor", "BlockEntityTypeMixin", "BufferBuilderMixin", - "ChunkRebuildHooksMixin", "ClientLevelMixin", "ClientMainMixin", "EntityTypeMixin", "FixFabulousDepthMixin", "FogUpdateMixin", "GlStateManagerMixin", - "InstanceAddMixin", - "InstanceRemoveMixin", "LevelRendererAccessor", "LevelRendererInstanceUpdateMixin", "LevelRendererMixin", "PausedPartialTickAccessor", "RenderTypeMixin", "VertexFormatMixin", + "instancemanage.ChunkRebuildHooksMixin", + "instancemanage.InstanceAddMixin", + "instancemanage.InstanceRemoveMixin", "light.LightUpdateMixin", "light.NetworkLightUpdateMixin", "matrix.Matrix3fAccessor",