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 3dd74fe4b2
19 changed files with 144 additions and 70 deletions

View File

@ -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

View File

@ -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"

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

View File

@ -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

View File

@ -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]);
}
}

View File

@ -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;
}
}
}

View File

@ -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<T> {
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.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<Entity> {
@ -44,14 +42,6 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
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);
}
}

View File

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

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -27,11 +27,11 @@ public class InstancingDrawManager {
private final Map<InstancerKey<?>, GPUInstancer<?>> instancers = new HashMap<>();
private final List<UninitializedInstancer> uninitializedInstancers = 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<>();
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()));

View File

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

View File

@ -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<ElementBuffer> 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

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.mixin;
package com.jozufozu.flywheel.mixin.instancemanage;
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.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.spongepowered.asm.mixin.Mixin;

View File

@ -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.'''

View File

@ -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",