Merge branch '1.18/dev' into 1.18/next

# Conflicts:
#	.github/ISSUE_TEMPLATE/bug_report.yml
#	build.gradle
#	gradle.properties
#	src/main/java/com/jozufozu/flywheel/api/Material.java
#	src/main/java/com/jozufozu/flywheel/backend/gl/GlStateTracker.java
#	src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/ElementBuffer.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
#	src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java
#	src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java
#	src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java
#	src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java
#	src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java
#	src/main/java/com/jozufozu/flywheel/core/QuadConverter.java
#	src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java
#	src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java
#	src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java
#	src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java
#	src/main/java/com/jozufozu/flywheel/core/model/Model.java
#	src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java
#	src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java
#	src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java
#	src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
#	src/main/java/com/jozufozu/flywheel/mixin/ClientMainMixin.java
#	src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java
#	src/main/resources/flywheel.mixins.json
This commit is contained in:
Jozufozu 2023-03-28 12:56:56 -07:00
commit 135f1e3fd2
19 changed files with 144 additions and 70 deletions

View File

@ -13,6 +13,17 @@ insert_final_newline = true
[*.json] [*.json]
indent_style = space indent_style = space
indent_size = 2 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] [*.java]
indent_style = tab indent_style = tab

View File

@ -60,6 +60,10 @@ body:
description: The version of the mod you were using when the bug occured description: The version of the mod you were using when the bug occured
options: options:
- "0.7.0" - "0.7.0"
- "0.6.8.a"
- "0.6.8"
- "0.6.7"
- "0.6.6"
- "0.6.5" - "0.6.5"
- "0.6.4" - "0.6.4"
- "0.6.3" - "0.6.3"
@ -91,6 +95,7 @@ body:
label: Minecraft Version label: Minecraft Version
description: The version of Minecraft you were using when the bug occured description: The version of Minecraft you were using when the bug occured
options: options:
- "1.19.2"
- "1.18.2" - "1.18.2"
- "1.18.1" - "1.18.1"
- "1.18" - "1.18"

View File

@ -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: 0.6.4:
Fixes Fixes
- Fix shader detection with oculus - Fix shader detection with oculus

View File

@ -14,7 +14,7 @@ mixingradle_version = 0.7-SNAPSHOT
mixin_version = 0.8.5 mixin_version = 0.8.5
librarian_version = 1.+ librarian_version = 1.+
cursegradle_version = 1.4.0 cursegradle_version = 1.4.0
parchment_version = 2022.07.10 parchment_version = 2022.11.06
# curseforge info # curseforge info
projectId = 486392 projectId = 486392

View File

@ -48,7 +48,7 @@ public class GlStateTracker {
GlBufferType[] values = GlBufferType.values(); GlBufferType[] values = GlBufferType.values();
for (int i = 0; i < values.length; i++) { 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]); GlStateManager._glBindBuffer(values[i].glEnum, buffers[i]);
} }
} }

View File

@ -137,12 +137,11 @@ public class GlVertexArray extends GlObject {
} }
} }
public void bindElementArray(GlBuffer ebo) { public void bindElementArray(int ebo) {
int handle = ebo.handle(); if (elementBufferBinding != ebo) {
if (elementBufferBinding != handle) {
bind(); bind();
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(handle); GlBufferType.ELEMENT_ARRAY_BUFFER.bind(ebo);
elementBufferBinding = handle; elementBufferBinding = ebo;
} }
} }
} }

View File

@ -1,6 +1,8 @@
package com.jozufozu.flywheel.backend.instancing; package com.jozufozu.flywheel.backend.instancing;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -261,4 +263,14 @@ public abstract class InstanceManager<T> {
LightUpdater.get(value.level).removeListener(value); LightUpdater.get(value.level).removeListener(value);
} }
} }
public void queueAddAll(Collection<? extends T> objects) {
if (!Backend.isOn() || objects.isEmpty()) {
return;
}
synchronized (queuedAdditions) {
queuedAdditions.addAll(objects);
}
}
} }

View File

@ -9,9 +9,7 @@ import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry; import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import com.jozufozu.flywheel.backend.instancing.One2OneStorage; import com.jozufozu.flywheel.backend.instancing.One2OneStorage;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
public class EntityInstanceManager extends InstanceManager<Entity> { public class EntityInstanceManager extends InstanceManager<Entity> {
@ -44,14 +42,6 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
Level level = entity.level; Level level = entity.level;
if (Backend.isFlywheelLevel(level)) { return Backend.isFlywheelLevel(level);
BlockPos pos = entity.blockPosition();
BlockGetter existingChunk = level.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
return existingChunk != null;
}
return false;
} }
} }

View File

@ -62,7 +62,7 @@ public class IndirectCullingGroup<T extends InstancedPart> {
vertexArray = glCreateVertexArrays(); vertexArray = glCreateVertexArrays();
elementBuffer = QuadConverter.getInstance() elementBuffer = QuadConverter.getInstance()
.quads2Tris(2048).buffer.handle(); .quads2Tris(2048).glBuffer;
setupVertexArray(); setupVertexArray();
compute = ComputeCullerCompiler.INSTANCE.get(structType); compute = ComputeCullerCompiler.INSTANCE.get(structType);

View File

@ -1,17 +1,29 @@
package com.jozufozu.flywheel.backend.instancing.instancing; package com.jozufozu.flywheel.backend.instancing.instancing;
import com.jozufozu.flywheel.backend.gl.GlNumericType; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.mojang.blaze3d.vertex.VertexFormat;
public class ElementBuffer { public class ElementBuffer {
public final GlBuffer buffer; protected final int elementCount;
public final int elementCount; protected final VertexFormat.IndexType eboIndexType;
public final GlNumericType eboIndexType; public final int glBuffer;
public ElementBuffer(GlBuffer backing, int elementCount, GlNumericType indexType) { public ElementBuffer(int backing, int elementCount, VertexFormat.IndexType indexType) {
this.buffer = backing;
this.eboIndexType = indexType;
this.elementCount = elementCount; 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;
} }
} }

View File

@ -228,15 +228,15 @@ public class InstancedMeshPool {
vao.enableArrays(getAttributeCount()); vao.enableArrays(getAttributeCount());
vao.bindAttributes(InstancedMeshPool.this.vbo, 0, vertexType.getLayout(), byteIndex); vao.bindAttributes(InstancedMeshPool.this.vbo, 0, vertexType.getLayout(), byteIndex);
} }
vao.bindElementArray(ebo.buffer); vao.bindElementArray(ebo.glBuffer);
vao.bind(); vao.bind();
} }
private void draw(int instanceCount) { private void draw(int instanceCount) {
if (instanceCount > 1) { 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 { } else {
GL32.glDrawElements(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0); GL32.glDrawElements(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0);
} }
} }

View File

@ -27,11 +27,11 @@ public class InstancingDrawManager {
private final Map<InstancerKey<?>, GPUInstancer<?>> instancers = new HashMap<>(); private final Map<InstancerKey<?>, GPUInstancer<?>> instancers = new HashMap<>();
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>(); private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
private final List<GPUInstancer<?>> initializedInstancers = new ArrayList<>(); private final List<GPUInstancer<?>> initializedInstancers = new ArrayList<>();
private final Map<RenderStage, DrawSet> drawDets = new EnumMap<>(RenderStage.class); private final Map<RenderStage, DrawSet> drawSets = new EnumMap<>(RenderStage.class);
private final Map<VertexType, InstancedMeshPool> meshPools = new HashMap<>(); private final Map<VertexType, InstancedMeshPool> meshPools = new HashMap<>();
public DrawSet get(RenderStage stage) { public DrawSet get(RenderStage stage) {
return drawDets.getOrDefault(stage, DrawSet.EMPTY); return drawSets.getOrDefault(stage, DrawSet.EMPTY);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -67,9 +67,9 @@ public class InstancingDrawManager {
.forEach(InstancedMeshPool::delete); .forEach(InstancedMeshPool::delete);
meshPools.clear(); meshPools.clear();
drawDets.values() drawSets.values()
.forEach(DrawSet::delete); .forEach(DrawSet::delete);
drawDets.clear(); drawSets.clear();
initializedInstancers.forEach(GPUInstancer::delete); initializedInstancers.forEach(GPUInstancer::delete);
initializedInstancers.clear(); initializedInstancers.clear();
@ -80,7 +80,7 @@ public class InstancingDrawManager {
} }
private void add(GPUInstancer<?> instancer, Model model, RenderStage stage) { 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(); var meshes = model.getMeshes();
for (var entry : meshes.entrySet()) { for (var entry : meshes.entrySet()) {
DrawCall drawCall = new DrawCall(instancer, entry.getKey(), alloc(entry.getValue())); DrawCall drawCall = new DrawCall(instancer, entry.getKey(), alloc(entry.getValue()));

View File

@ -16,12 +16,12 @@ import net.minecraftforge.client.model.ForgeModelBakery;
* A helper class for loading and accessing json models. * A helper class for loading and accessing json models.
* <br> * <br>
* Creating a PartialModel will make the associated modelLocation automatically load. * 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.
* <br> * <br>
* Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations) * Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations)
* will have their bakedModel fields populated. * will have their bakedModel fields populated.
* <br> * <br>
* 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 { public class PartialModel {

View File

@ -2,14 +2,19 @@ package com.jozufozu.flywheel.core;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.lwjgl.opengl.GL32;
import org.lwjgl.opengl.GL32C;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.backend.gl.GlNumericType; 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.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.backend.instancing.instancing.ElementBuffer;
import com.jozufozu.flywheel.event.ReloadRenderersEvent; 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. * A class to manage EBOs that index quads as triangles.
@ -32,56 +37,71 @@ public class QuadConverter {
return INSTANCE; return INSTANCE;
} }
private final GlBuffer ebo; private final Int2ReferenceMap<ElementBuffer> cache = new Int2ReferenceArrayMap<>();
private final int ebo;
private int quadCapacity; private int quadCapacity;
public QuadConverter() { public QuadConverter() {
this.ebo = new GlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER); this.ebo = GL32.glGenBuffers();
this.quadCapacity = 0; this.quadCapacity = 0;
} }
public ElementBuffer quads2Tris(int quads) { public ElementBuffer quads2Tris(int quads) {
int indexCount = quads * 6;
if (quads > quadCapacity) { if (quads > quadCapacity) {
ebo.ensureCapacity((long) indexCount * GlNumericType.UINT.getByteWidth()); grow(quads * 2);
try (MappedBuffer map = ebo.map()) {
fillBuffer(map.getPtr(), quads);
} }
ebo.unbind();
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; this.quadCapacity = quads;
} }
return new ElementBuffer(ebo, indexCount, GlNumericType.UINT);
}
public void delete() { public void delete() {
ebo.delete(); GL32.glDeleteBuffers(ebo);
this.cache.clear();
this.quadCapacity = 0; this.quadCapacity = 0;
} }
private void fillBuffer(long addr, int quads) { private void fillBuffer(long ptr, int quads) {
int numVertices = 4 * quads; int numVertices = 4 * quads;
int baseVertex = 0; int baseVertex = 0;
while (baseVertex < numVertices) { while (baseVertex < numVertices) {
writeQuadIndices(addr, baseVertex); writeQuadIndicesUnsafe(ptr, baseVertex);
baseVertex += 4; baseVertex += 4;
addr += 6 * 4; ptr += 6 * 4;
} }
} }
private void writeQuadIndices(long addr, int baseVertex) { private void writeQuadIndicesUnsafe(long ptr, int baseVertex) {
// triangle a // triangle a
MemoryUtil.memPutInt(addr, baseVertex); MemoryUtil.memPutInt(ptr, baseVertex);
MemoryUtil.memPutInt(addr + 4, baseVertex + 1); MemoryUtil.memPutInt(ptr + 4, baseVertex + 1);
MemoryUtil.memPutInt(addr + 8, baseVertex + 2); MemoryUtil.memPutInt(ptr + 8, baseVertex + 2);
// triangle b // triangle b
MemoryUtil.memPutInt(addr + 12, baseVertex); MemoryUtil.memPutInt(ptr + 12, baseVertex);
MemoryUtil.memPutInt(addr + 16, baseVertex + 2); MemoryUtil.memPutInt(ptr + 16, baseVertex + 2);
MemoryUtil.memPutInt(addr + 20, baseVertex + 3); MemoryUtil.memPutInt(ptr + 20, baseVertex + 3);
} }
// make sure this gets reset first, so it has a chance to repopulate // make sure this gets reset first, so it has a chance to repopulate

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.mixin; package com.jozufozu.flywheel.mixin.instancemanage;
import java.util.Set; import java.util.Set;

View File

@ -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.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.mixin; package com.jozufozu.flywheel.mixin.instancemanage;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;

View File

@ -10,7 +10,7 @@ version = "${file.jarVersion}"
displayName = "Flywheel" displayName = "Flywheel"
logoFile = "logo.png" logoFile = "logo.png"
displayURL = "https://www.curseforge.com/minecraft/mc-mods/flywheel" 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" authors = "Jozufozu"
description = ''' description = '''
A modern engine for modded minecraft.''' A modern engine for modded minecraft.'''

View File

@ -8,21 +8,21 @@
"BlockEntityRenderDispatcherAccessor", "BlockEntityRenderDispatcherAccessor",
"BlockEntityTypeMixin", "BlockEntityTypeMixin",
"BufferBuilderMixin", "BufferBuilderMixin",
"ChunkRebuildHooksMixin",
"ClientLevelMixin", "ClientLevelMixin",
"ClientMainMixin", "ClientMainMixin",
"EntityTypeMixin", "EntityTypeMixin",
"FixFabulousDepthMixin", "FixFabulousDepthMixin",
"FogUpdateMixin", "FogUpdateMixin",
"GlStateManagerMixin", "GlStateManagerMixin",
"InstanceAddMixin",
"InstanceRemoveMixin",
"LevelRendererAccessor", "LevelRendererAccessor",
"LevelRendererInstanceUpdateMixin", "LevelRendererInstanceUpdateMixin",
"LevelRendererMixin", "LevelRendererMixin",
"PausedPartialTickAccessor", "PausedPartialTickAccessor",
"RenderTypeMixin", "RenderTypeMixin",
"VertexFormatMixin", "VertexFormatMixin",
"instancemanage.ChunkRebuildHooksMixin",
"instancemanage.InstanceAddMixin",
"instancemanage.InstanceRemoveMixin",
"light.LightUpdateMixin", "light.LightUpdateMixin",
"light.NetworkLightUpdateMixin", "light.NetworkLightUpdateMixin",
"matrix.Matrix3fAccessor", "matrix.Matrix3fAccessor",