mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-06 04:16:36 +01:00
No more leaks
- Free all DrawBuffers on renderer reload - Add flw.debugMemorySafety flag to detect leaked untracked MemoryBlocks - Replace VertexListProviderRegistry with static methods in VertexListProvider and a VertexFormatMixin - Make the DrawBuffer constructor accept a VertexFormat instead of a RenderType - Merge TStack into TransformStack - Move all duck interfaces/extensions to extension package - Make mixin style more consistent
This commit is contained in:
parent
cfa79ec550
commit
2fe69350ef
57 changed files with 317 additions and 233 deletions
|
@ -45,6 +45,7 @@ minecraft {
|
|||
property 'mixin.env.remapRefMap', 'true'
|
||||
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
|
||||
property 'flw.dumpShaderSource', 'true'
|
||||
property 'flw.debugMemorySafety', 'true'
|
||||
|
||||
arg '-mixin.config=flywheel.mixins.json'
|
||||
|
||||
|
@ -114,8 +115,8 @@ dependencies {
|
|||
// switch to implementation for debugging
|
||||
compileOnly fg.deobf("maven.modrinth:starlight-forge:1.0.2+1.18.2")
|
||||
|
||||
compileOnly fg.deobf("maven.modrinth:rubidium:0.5.2a")
|
||||
compileOnly fg.deobf("curse.maven:oculus-581495:3821406")
|
||||
compileOnly fg.deobf("maven.modrinth:rubidium:0.5.3a")
|
||||
compileOnly fg.deobf("maven.modrinth:oculus:1.18.2-1.2.5a")
|
||||
|
||||
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
|||
import com.jozufozu.flywheel.backend.RenderWork;
|
||||
import com.jozufozu.flywheel.backend.ShadersModHandler;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.backend.instancing.batching.DrawBuffer;
|
||||
import com.jozufozu.flywheel.config.BackendTypeArgument;
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
|
@ -18,7 +19,6 @@ import com.jozufozu.flywheel.core.compile.ProgramCompiler;
|
|||
import com.jozufozu.flywheel.core.model.Models;
|
||||
import com.jozufozu.flywheel.event.EntityWorldHandler;
|
||||
import com.jozufozu.flywheel.event.ForgeEvents;
|
||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
|
||||
import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
@ -77,9 +77,10 @@ public class Flywheel {
|
|||
|
||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
||||
|
||||
forgeEventBus.addListener(EventPriority.HIGHEST, QuadConverter::onRendererReload);
|
||||
forgeEventBus.addListener(ProgramCompiler::invalidateAll);
|
||||
forgeEventBus.addListener(Models::onReload);
|
||||
forgeEventBus.addListener(EventPriority.HIGHEST, QuadConverter::onReloadRenderers);
|
||||
forgeEventBus.addListener(ProgramCompiler::onReloadRenderers);
|
||||
forgeEventBus.addListener(Models::onReloadRenderers);
|
||||
forgeEventBus.addListener(DrawBuffer::onReloadRenderers);
|
||||
|
||||
forgeEventBus.addListener(InstancedRenderDispatcher::onReloadRenderers);
|
||||
forgeEventBus.addListener(InstancedRenderDispatcher::onRenderStage);
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
package com.jozufozu.flywheel.api.vertex;
|
||||
|
||||
import com.jozufozu.flywheel.core.vertex.InferredVertexListProviderImpl;
|
||||
import com.jozufozu.flywheel.extension.VertexFormatExtension;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
public interface VertexListProvider {
|
||||
ReusableVertexList createVertexList();
|
||||
|
||||
static VertexListProvider get(VertexFormat format) {
|
||||
VertexFormatExtension extension = (VertexFormatExtension) format;
|
||||
VertexListProvider provider = extension.flywheel$getVertexListProvider();
|
||||
if (provider == null) {
|
||||
provider = new InferredVertexListProviderImpl(format);
|
||||
extension.flywheel$setVertexListProvider(provider);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
static void set(VertexFormat format, VertexListProvider provider) {
|
||||
((VertexFormatExtension) format).flywheel$setVertexListProvider(provider);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
|||
import com.jozufozu.flywheel.core.Components;
|
||||
import com.jozufozu.flywheel.core.RenderContext;
|
||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||
import com.jozufozu.flywheel.util.ClientLevelExtension;
|
||||
import com.jozufozu.flywheel.extension.ClientLevelExtension;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
|
|
@ -9,12 +9,12 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.SimpleBlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityTypeExtension;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.SimpleEntityInstancingController;
|
||||
import com.jozufozu.flywheel.extension.BlockEntityTypeExtension;
|
||||
import com.jozufozu.flywheel.extension.EntityTypeExtension;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
|
|
@ -3,7 +3,8 @@ package com.jozufozu.flywheel.backend.instancing.batching;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.jozufozu.flywheel.util.RenderTypeExtension;
|
||||
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
|
||||
import com.jozufozu.flywheel.extension.RenderTypeExtension;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
|
|
@ -67,6 +67,7 @@ public class BatchingEngine implements Engine {
|
|||
public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
|
||||
// FIXME: properly support material stages
|
||||
// This also breaks block outlines on batched block entities
|
||||
// and makes translucent blocks occlude everything Flywheel renders
|
||||
if (stage != RenderStage.AFTER_FINAL_END_BATCH) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
||||
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
|
||||
import com.jozufozu.flywheel.core.vertex.VertexListProviderRegistry;
|
||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
/**
|
||||
* A byte buffer that can be used to draw vertices through multiple {@link ReusableVertexList}s.
|
||||
*
|
||||
* The number of vertices needs to be known ahead of time.
|
||||
*/
|
||||
public class DrawBuffer {
|
||||
private final RenderType parent;
|
||||
private static final List<DrawBuffer> ALL = new ArrayList<>();
|
||||
|
||||
private final VertexFormat format;
|
||||
private final int stride;
|
||||
private final VertexListProvider provider;
|
||||
|
@ -29,11 +31,12 @@ public class DrawBuffer {
|
|||
private int expectedVertices;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public DrawBuffer(RenderType parent) {
|
||||
this.parent = parent;
|
||||
format = parent.format();
|
||||
public DrawBuffer(VertexFormat format) {
|
||||
this.format = format;
|
||||
stride = format.getVertexSize();
|
||||
provider = VertexListProviderRegistry.getOrInfer(format);
|
||||
provider = VertexListProvider.get(format);
|
||||
|
||||
ALL.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,7 +69,8 @@ public class DrawBuffer {
|
|||
|
||||
public ReusableVertexList slice(int startVertex, int vertexCount) {
|
||||
ReusableVertexList vertexList = provider.createVertexList();
|
||||
vertexList.ptr(memory.ptr() + startVertex * stride);
|
||||
vertexList.ptr(memory.ptr());
|
||||
vertexList.shiftPtr(startVertex);
|
||||
vertexList.setVertexCount(vertexCount);
|
||||
return vertexList;
|
||||
}
|
||||
|
@ -101,7 +105,12 @@ public class DrawBuffer {
|
|||
}
|
||||
|
||||
public void free() {
|
||||
buffer = null;
|
||||
memory.free();
|
||||
memory = null;
|
||||
buffer = null;
|
||||
}
|
||||
|
||||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||
ALL.forEach(DrawBuffer::free);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.jozufozu.flywheel.api.material.Material;
|
|||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
|
||||
public class DrawCall {
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.instancing.instancing;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package com.jozufozu.flywheel.backend.memory;
|
||||
|
||||
import java.lang.ref.Cleaner;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.util.StringUtil;
|
||||
|
||||
class DebugMemoryBlockImpl extends MemoryBlockImpl {
|
||||
final CleaningAction cleaningAction;
|
||||
final Cleaner.Cleanable cleanable;
|
||||
|
||||
DebugMemoryBlockImpl(long ptr, long size, Cleaner cleaner) {
|
||||
super(ptr, size);
|
||||
cleaningAction = new CleaningAction(ptr, size, getStackTrace());
|
||||
cleanable = cleaner.register(this, cleaningAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
void freeInner() {
|
||||
super.freeInner();
|
||||
cleaningAction.freed = true;
|
||||
cleanable.clean();
|
||||
}
|
||||
|
||||
static StackWalker.StackFrame[] getStackTrace() {
|
||||
return StackWalker.getInstance().walk(s -> s.skip(4).toArray(StackWalker.StackFrame[]::new));
|
||||
}
|
||||
|
||||
static MemoryBlock malloc(long size) {
|
||||
MemoryBlock block = new DebugMemoryBlockImpl(FlwMemoryTracker.malloc(size), size, FlwMemoryTracker.CLEANER);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
static MemoryBlock calloc(long num, long size) {
|
||||
MemoryBlock block = new DebugMemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size, FlwMemoryTracker.CLEANER);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
static class CleaningAction implements Runnable {
|
||||
final long ptr;
|
||||
final long size;
|
||||
final StackWalker.StackFrame[] allocationSite;
|
||||
|
||||
boolean freed;
|
||||
|
||||
CleaningAction(long ptr, long size, StackWalker.StackFrame[] allocationSite) {
|
||||
this.ptr = ptr;
|
||||
this.size = size;
|
||||
this.allocationSite = allocationSite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!freed) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder
|
||||
.append("Reclaimed ")
|
||||
.append(size)
|
||||
.append(" bytes at address ")
|
||||
.append(StringUtil.formatAddress(ptr))
|
||||
.append(" that were leaked from allocation site:");
|
||||
for (StackWalker.StackFrame frame : allocationSite) {
|
||||
builder.append("\n\t");
|
||||
builder.append(frame);
|
||||
}
|
||||
Flywheel.LOGGER.warn(builder.toString());
|
||||
|
||||
FlwMemoryTracker.free(ptr);
|
||||
FlwMemoryTracker._freeCPUMemory(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,11 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.util.StringUtil;
|
||||
|
||||
public class FlwMemoryTracker {
|
||||
public static final boolean DEBUG_MEMORY_SAFETY = System.getProperty("flw.debugMemorySafety") != null;
|
||||
|
||||
static final Cleaner CLEANER = Cleaner.create();
|
||||
|
||||
private static long cpuMemory = 0;
|
||||
|
@ -54,7 +58,7 @@ public class FlwMemoryTracker {
|
|||
public static long realloc(long ptr, long size) {
|
||||
ptr = MemoryUtil.nmemRealloc(ptr, size);
|
||||
if (ptr == MemoryUtil.NULL) {
|
||||
throw new OutOfMemoryError("Failed to reallocate " + size + " bytes for address 0x" + Long.toHexString(ptr));
|
||||
throw new OutOfMemoryError("Failed to reallocate " + size + " bytes for address " + StringUtil.formatAddress(ptr));
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
@ -26,18 +26,26 @@ public sealed interface MemoryBlock permits MemoryBlockImpl {
|
|||
void free();
|
||||
|
||||
static MemoryBlock malloc(long size) {
|
||||
return MemoryBlockImpl.mallocBlock(size);
|
||||
if (FlwMemoryTracker.DEBUG_MEMORY_SAFETY) {
|
||||
return DebugMemoryBlockImpl.malloc(size);
|
||||
} else {
|
||||
return MemoryBlockImpl.malloc(size);
|
||||
}
|
||||
}
|
||||
|
||||
static MemoryBlock mallocTracked(long size) {
|
||||
return TrackedMemoryBlockImpl.mallocBlockTracked(size);
|
||||
return TrackedMemoryBlockImpl.malloc(size);
|
||||
}
|
||||
|
||||
static MemoryBlock calloc(long num, long size) {
|
||||
return MemoryBlockImpl.callocBlock(num, size);
|
||||
if (FlwMemoryTracker.DEBUG_MEMORY_SAFETY) {
|
||||
return DebugMemoryBlockImpl.calloc(num, size);
|
||||
} else {
|
||||
return MemoryBlockImpl.calloc(num, size);
|
||||
}
|
||||
}
|
||||
|
||||
static MemoryBlock callocTracked(long num, long size) {
|
||||
return TrackedMemoryBlockImpl.callocBlockTracked(num, size);
|
||||
return TrackedMemoryBlockImpl.calloc(num, size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
sealed class MemoryBlockImpl implements MemoryBlock permits TrackedMemoryBlockImpl {
|
||||
non-sealed class MemoryBlockImpl implements MemoryBlock {
|
||||
final long ptr;
|
||||
final long size;
|
||||
|
||||
|
@ -86,13 +86,13 @@ sealed class MemoryBlockImpl implements MemoryBlock permits TrackedMemoryBlockIm
|
|||
freeInner();
|
||||
}
|
||||
|
||||
static MemoryBlock mallocBlock(long size) {
|
||||
static MemoryBlock malloc(long size) {
|
||||
MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.malloc(size), size);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
static MemoryBlock callocBlock(long num, long size) {
|
||||
static MemoryBlock calloc(long num, long size) {
|
||||
MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.memory;
|
|||
|
||||
import java.lang.ref.Cleaner;
|
||||
|
||||
final class TrackedMemoryBlockImpl extends MemoryBlockImpl {
|
||||
class TrackedMemoryBlockImpl extends MemoryBlockImpl {
|
||||
final CleaningAction cleaningAction;
|
||||
final Cleaner.Cleanable cleanable;
|
||||
|
||||
|
@ -24,13 +24,13 @@ final class TrackedMemoryBlockImpl extends MemoryBlockImpl {
|
|||
cleanable.clean();
|
||||
}
|
||||
|
||||
static MemoryBlock mallocBlockTracked(long size) {
|
||||
static MemoryBlock malloc(long size) {
|
||||
MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.malloc(size), size, FlwMemoryTracker.CLEANER);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
static MemoryBlock callocBlockTracked(long num, long size) {
|
||||
static MemoryBlock calloc(long num, long size) {
|
||||
MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size, FlwMemoryTracker.CLEANER);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
|
|
|
@ -85,7 +85,7 @@ public class QuadConverter {
|
|||
}
|
||||
|
||||
// make sure this gets reset first, so it has a chance to repopulate
|
||||
public static void onRendererReload(ReloadRenderersEvent event) {
|
||||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||
if (INSTANCE != null) {
|
||||
INSTANCE.delete();
|
||||
INSTANCE = null;
|
||||
|
|
|
@ -70,7 +70,7 @@ public class ProgramCompiler extends Memoizer<ProgramCompiler.Context, GlProgram
|
|||
value.delete();
|
||||
}
|
||||
|
||||
public static void invalidateAll(ReloadRenderersEvent ignored) {
|
||||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||
INSTANCE.invalidate();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,11 @@ import org.lwjgl.system.MemoryUtil;
|
|||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.vertex.Formats;
|
||||
import com.jozufozu.flywheel.core.vertex.VertexListProviderRegistry;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
@ -58,7 +58,7 @@ public class ModelUtil {
|
|||
long srcPtr = MemoryUtil.memAddress(src);
|
||||
long dstPtr = dst.ptr();
|
||||
|
||||
ReusableVertexList srcList = VertexListProviderRegistry.getOrInfer(srcFormat).createVertexList();
|
||||
ReusableVertexList srcList = VertexListProvider.get(srcFormat).createVertexList();
|
||||
ReusableVertexList dstList = dstVertexType.createVertexList();
|
||||
srcList.ptr(srcPtr);
|
||||
dstList.ptr(dstPtr);
|
||||
|
|
|
@ -41,7 +41,7 @@ public class Models {
|
|||
return stack;
|
||||
}
|
||||
|
||||
public static void onReload(ReloadRenderersEvent event) {
|
||||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||
deleteAll(BLOCK_STATE.values());
|
||||
deleteAll(PARTIAL.values());
|
||||
deleteAll(PARTIAL_DIR.values());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.jozufozu.flywheel.core.structs.transformed;
|
||||
|
||||
import com.jozufozu.flywheel.core.structs.ColoredLitWriter;
|
||||
import com.jozufozu.flywheel.util.MatrixWrite;
|
||||
import com.jozufozu.flywheel.extension.MatrixWrite;
|
||||
|
||||
public class TransformedWriter extends ColoredLitWriter<TransformedPart> {
|
||||
public static final TransformedWriter INSTANCE = new TransformedWriter();
|
||||
|
|
|
@ -8,7 +8,7 @@ import com.jozufozu.flywheel.core.Components;
|
|||
import com.jozufozu.flywheel.core.RenderContext;
|
||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||
import com.jozufozu.flywheel.util.MatrixWrite;
|
||||
import com.jozufozu.flywheel.extension.MatrixWrite;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.Vec3i;
|
||||
|
|
|
@ -6,16 +6,6 @@ public abstract class AbstractVertexList implements ReusableVertexList {
|
|||
protected long ptr;
|
||||
protected int vertexCount;
|
||||
|
||||
@Override
|
||||
public int getVertexCount() {
|
||||
return vertexCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVertexCount(int vertexCount) {
|
||||
this.vertexCount = vertexCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long ptr() {
|
||||
return ptr;
|
||||
|
@ -25,4 +15,14 @@ public abstract class AbstractVertexList implements ReusableVertexList {
|
|||
public void ptr(long ptr) {
|
||||
this.ptr = ptr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVertexCount() {
|
||||
return vertexCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVertexCount(int vertexCount) {
|
||||
this.vertexCount = vertexCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,15 +50,4 @@ public class InferredVertexFormatInfo {
|
|||
this.lightOffset = lightOffset;
|
||||
this.normalOffset = normalOffset;
|
||||
}
|
||||
|
||||
protected InferredVertexFormatInfo(InferredVertexFormatInfo formatInfo) {
|
||||
format = formatInfo.format;
|
||||
stride = formatInfo.stride;
|
||||
positionOffset = formatInfo.positionOffset;
|
||||
colorOffset = formatInfo.colorOffset;
|
||||
textureOffset = formatInfo.textureOffset;
|
||||
overlayOffset = formatInfo.overlayOffset;
|
||||
lightOffset = formatInfo.lightOffset;
|
||||
normalOffset = formatInfo.normalOffset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,18 +4,33 @@ import org.lwjgl.system.MemoryUtil;
|
|||
|
||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||
import com.jozufozu.flywheel.util.RenderMath;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
|
||||
public final class InferredVertexListImpl extends InferredVertexFormatInfo implements ReusableVertexList {
|
||||
private long ptr;
|
||||
private int vertexCount;
|
||||
public class InferredVertexListImpl extends AbstractVertexList implements ReusableVertexList {
|
||||
protected final VertexFormat format;
|
||||
protected final int stride;
|
||||
|
||||
protected final int positionOffset;
|
||||
protected final int colorOffset;
|
||||
protected final int textureOffset;
|
||||
protected final int overlayOffset;
|
||||
protected final int lightOffset;
|
||||
protected final int normalOffset;
|
||||
|
||||
public InferredVertexListImpl(InferredVertexFormatInfo formatInfo) {
|
||||
super(formatInfo);
|
||||
format = formatInfo.format;
|
||||
stride = formatInfo.stride;
|
||||
positionOffset = formatInfo.positionOffset;
|
||||
colorOffset = formatInfo.colorOffset;
|
||||
textureOffset = formatInfo.textureOffset;
|
||||
overlayOffset = formatInfo.overlayOffset;
|
||||
lightOffset = formatInfo.lightOffset;
|
||||
normalOffset = formatInfo.normalOffset;
|
||||
}
|
||||
|
||||
private long idxPtr(int index) {
|
||||
protected long idxPtr(int index) {
|
||||
return ptr + index * stride;
|
||||
}
|
||||
|
||||
|
@ -187,28 +202,8 @@ public final class InferredVertexListImpl extends InferredVertexFormatInfo imple
|
|||
MemoryUtil.memPutByte(idxPtr(index) + normalOffset + 2, RenderMath.nb(normalZ));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVertexCount() {
|
||||
return vertexCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long ptr() {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ptr(long ptr) {
|
||||
this.ptr = ptr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shiftPtr(int vertices) {
|
||||
ptr += vertices * stride;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVertexCount(int vertexCount) {
|
||||
this.vertexCount = vertexCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
package com.jozufozu.flywheel.core.vertex;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
public class VertexListProviderRegistry {
|
||||
private static final Map<VertexFormat, Holder> HOLDERS = new ConcurrentHashMap<>();
|
||||
|
||||
private static Holder getOrCreateHolder(VertexFormat format) {
|
||||
return HOLDERS.computeIfAbsent(format, Holder::new);
|
||||
}
|
||||
|
||||
public static void register(VertexFormat format, VertexListProvider provider) {
|
||||
getOrCreateHolder(format).registeredProvider = provider;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VertexListProvider get(VertexFormat format) {
|
||||
return getOrCreateHolder(format).get();
|
||||
}
|
||||
|
||||
public static VertexListProvider getOrInfer(VertexFormat format) {
|
||||
return getOrCreateHolder(format).getOrInfer();
|
||||
}
|
||||
|
||||
private static class Holder {
|
||||
public final VertexFormat format;
|
||||
public VertexListProvider registeredProvider;
|
||||
public VertexListProvider inferredProvider;
|
||||
|
||||
public Holder(VertexFormat format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VertexListProvider get() {
|
||||
return registeredProvider;
|
||||
}
|
||||
|
||||
public VertexListProvider getOrInfer() {
|
||||
if (registeredProvider != null) {
|
||||
return registeredProvider;
|
||||
}
|
||||
if (inferredProvider == null) {
|
||||
inferredProvider = new InferredVertexListProviderImpl(format);
|
||||
}
|
||||
return inferredProvider;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||
package com.jozufozu.flywheel.extension;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
public interface BlockEntityTypeExtension<T extends BlockEntity> {
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||
package com.jozufozu.flywheel.extension;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.util;
|
||||
package com.jozufozu.flywheel.extension;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
|
@ -1,7 +1,9 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||
package com.jozufozu.flywheel.extension;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
public interface EntityTypeExtension<T extends Entity> {
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.util;
|
||||
package com.jozufozu.flywheel.extension;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.util;
|
||||
package com.jozufozu.flywheel.extension;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.batching.DrawBuffer;
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.jozufozu.flywheel.extension;
|
||||
|
||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
/**
|
||||
* Duck interface to make VertexFormat store a VertexListProvider.
|
||||
*
|
||||
* @see VertexFormat
|
||||
*/
|
||||
public interface VertexFormatExtension {
|
||||
|
||||
/**
|
||||
* @return The VertexListProvider associated with this VertexFormat.
|
||||
*/
|
||||
VertexListProvider flywheel$getVertexListProvider();
|
||||
|
||||
void flywheel$setVertexListProvider(VertexListProvider provider);
|
||||
}
|
|
@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension;
|
||||
import com.jozufozu.flywheel.extension.BlockEntityTypeExtension;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.lwjgl.system.MemoryUtil;
|
|||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.batching.BufferBuilderExtension;
|
||||
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexFormatElement;
|
||||
|
|
|
@ -13,13 +13,13 @@ import com.mojang.blaze3d.vertex.VertexFormat;
|
|||
|
||||
@Mixin(BufferUploader.class)
|
||||
public class BufferUploaderMixin {
|
||||
|
||||
@Shadow
|
||||
@Nullable
|
||||
private static VertexFormat lastFormat;
|
||||
|
||||
// Stop BufferUploader from clearing buffer state if nothing is bound
|
||||
@Inject(method = "reset", at = @At("HEAD"))
|
||||
private static void stopBufferUploaderFromClearingBufferStateIfNothingIsBound(CallbackInfo ci) {
|
||||
private static void flywheel$onReset(CallbackInfo ci) {
|
||||
// Trust our tracker over BufferUploader's.
|
||||
if (GlStateTracker.getVertexArray() == 0) {
|
||||
lastFormat = null;
|
||||
|
|
|
@ -16,9 +16,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
|
||||
@Mixin(targets = "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$RenderChunk$RebuildTask")
|
||||
public class ChunkRebuildHooksMixin {
|
||||
|
||||
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
|
||||
private <E extends BlockEntity> void addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> set, E be, CallbackInfo ci) {
|
||||
private <E extends BlockEntity> void flywheel$addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> set, E be, CallbackInfo ci) {
|
||||
if (Backend.canUseInstancing(be.getLevel())) {
|
||||
if (InstancedRenderRegistry.canInstance(be.getType()))
|
||||
InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be);
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
import com.google.common.collect.Lists;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.util.ClientLevelExtension;
|
||||
import com.jozufozu.flywheel.extension.ClientLevelExtension;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
@ -19,7 +19,6 @@ import net.minecraft.world.level.entity.LevelEntityGetter;
|
|||
|
||||
@Mixin(ClientLevel.class)
|
||||
public abstract class ClientLevelMixin implements ClientLevelExtension {
|
||||
|
||||
@Shadow
|
||||
protected abstract LevelEntityGetter<Entity> getEntities();
|
||||
|
||||
|
@ -29,7 +28,7 @@ public abstract class ClientLevelMixin implements ClientLevelExtension {
|
|||
}
|
||||
|
||||
@Inject(method = "entitiesForRendering", at = @At("RETURN"), cancellable = true)
|
||||
private void filterEntities(CallbackInfoReturnable<Iterable<Entity>> cir) {
|
||||
private void flywheel$filterEntities(CallbackInfoReturnable<Iterable<Entity>> cir) {
|
||||
if (Backend.isOn()) {
|
||||
Iterable<Entity> entities = cir.getReturnValue();
|
||||
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityTypeExtension;
|
||||
import com.jozufozu.flywheel.extension.EntityTypeExtension;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
|
|
@ -16,9 +16,8 @@ import net.minecraft.client.renderer.LightTexture;
|
|||
|
||||
@Mixin(LevelRenderer.class)
|
||||
public class FixFabulousDepthMixin {
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/client/renderer/PostChain;process(F)V"))
|
||||
private void disableTransparencyShaderDepth(PoseStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, Camera p_228426_6_, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) {
|
||||
private void flywheel$disableTransparencyShaderDepth(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
|
||||
GlStateManager._depthMask(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,23 +11,22 @@ import net.minecraft.client.renderer.FogRenderer;
|
|||
|
||||
@Mixin(FogRenderer.class)
|
||||
public class FogUpdateMixin {
|
||||
private static void flywheel$updateFog() {
|
||||
Components.FOG_PROVIDER.update();
|
||||
}
|
||||
|
||||
@Inject(method = "setupNoFog", at = @At("TAIL"))
|
||||
private static void onNoFog(CallbackInfo ci) {
|
||||
private static void flywheel$onNoFog(CallbackInfo ci) {
|
||||
flywheel$updateFog();
|
||||
}
|
||||
|
||||
@Inject(method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V", remap = false, at = @At("TAIL"))
|
||||
private static void onFog(CallbackInfo ci) {
|
||||
private static void flywheel$onFog(CallbackInfo ci) {
|
||||
flywheel$updateFog();
|
||||
}
|
||||
|
||||
@Inject(method = "levelFogColor", at = @At("TAIL"))
|
||||
private static void onFogColor(CallbackInfo ci) {
|
||||
private static void flywheel$onFogColor(CallbackInfo ci) {
|
||||
flywheel$updateFog();
|
||||
}
|
||||
|
||||
private static void flywheel$updateFog() {
|
||||
Components.FOG_PROVIDER.update();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,19 +11,18 @@ import com.mojang.blaze3d.platform.GlStateManager;
|
|||
|
||||
@Mixin(GlStateManager.class)
|
||||
public class GlStateManagerMixin {
|
||||
|
||||
@Inject(method = "_glBindBuffer", at = @At("TAIL"))
|
||||
private static void onBindBuffer(int pTarget, int pBuffer, CallbackInfo ci) {
|
||||
private static void flywheel$onBindBuffer(int pTarget, int pBuffer, CallbackInfo ci) {
|
||||
GlStateTracker._setBuffer(GlBufferType.fromTarget(pTarget), pBuffer);
|
||||
}
|
||||
|
||||
@Inject(method = "_glBindVertexArray", at = @At("TAIL"))
|
||||
private static void onBindVertexArray(int pArray, CallbackInfo ci) {
|
||||
private static void flywheel$onBindVertexArray(int pArray, CallbackInfo ci) {
|
||||
GlStateTracker._setVertexArray(pArray);
|
||||
}
|
||||
|
||||
@Inject(method = "_glUseProgram", at = @At("TAIL"))
|
||||
private static void onUseProgram(int pProgram, CallbackInfo ci) {
|
||||
private static void flywheel$onUseProgram(int pProgram, CallbackInfo ci) {
|
||||
GlStateTracker._setProgram(pProgram);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,14 +16,13 @@ import net.minecraft.world.level.chunk.LevelChunk;
|
|||
|
||||
@Mixin(LevelChunk.class)
|
||||
public class InstanceAddMixin {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
Level level;
|
||||
|
||||
@Inject(method = "setBlockEntity",
|
||||
at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))
|
||||
private void blockEntityAdded(BlockEntity be, CallbackInfo ci) {
|
||||
private void flywheel$onBlockEntityAdded(BlockEntity be, CallbackInfo ci) {
|
||||
if (level.isClientSide && Backend.isOn()) {
|
||||
InstancedRenderDispatcher.getBlockEntities(this.level)
|
||||
.add(be);
|
||||
|
|
|
@ -16,13 +16,12 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
|
||||
@Mixin(BlockEntity.class)
|
||||
public class InstanceRemoveMixin {
|
||||
|
||||
@Shadow
|
||||
@Nullable
|
||||
protected Level level;
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "setRemoved")
|
||||
private void removeInstance(CallbackInfo ci) {
|
||||
private void flywheel$removeInstance(CallbackInfo ci) {
|
||||
if (level instanceof ClientLevel && Backend.isOn()) {
|
||||
InstancedRenderDispatcher.getBlockEntities(this.level)
|
||||
.remove((BlockEntity) (Object) this);
|
||||
|
|
|
@ -24,7 +24,7 @@ public class LevelRendererInstanceUpdateMixin {
|
|||
* This gets called when a block is marked for rerender by vanilla.
|
||||
*/
|
||||
@Inject(at = @At("TAIL"), method = "setBlockDirty(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V")
|
||||
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
|
||||
private void flywheel$checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
|
||||
if (!Backend.isOn()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import net.minecraft.client.renderer.LightTexture;
|
|||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after sodium
|
||||
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after Sodium
|
||||
public class LevelRendererMixin {
|
||||
@Shadow
|
||||
private ClientLevel level;
|
||||
|
@ -38,20 +38,20 @@ public class LevelRendererMixin {
|
|||
private RenderBuffers renderBuffers;
|
||||
|
||||
@Unique
|
||||
private RenderContext renderContext;
|
||||
private RenderContext flywheel$renderContext;
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "renderLevel")
|
||||
private void beginRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
|
||||
renderContext = new RenderContext((LevelRenderer) (Object) this, level, pPoseStack, RenderContext.createViewProjection(pPoseStack, pProjectionMatrix), pProjectionMatrix, renderBuffers, pCamera);
|
||||
private void flywheel$beginRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
|
||||
flywheel$renderContext = new RenderContext((LevelRenderer) (Object) this, level, pPoseStack, RenderContext.createViewProjection(pPoseStack, pProjectionMatrix), pProjectionMatrix, renderBuffers, pCamera);
|
||||
|
||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(renderContext));
|
||||
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(flywheel$renderContext));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "renderLevel")
|
||||
private void endRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
|
||||
renderContext = null;
|
||||
private void flywheel$endRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
|
||||
flywheel$renderContext = null;
|
||||
}
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "allChanged")
|
||||
|
@ -61,92 +61,92 @@ public class LevelRendererMixin {
|
|||
MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(level));
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 2, shift = Shift.BY, by = 2 // after the game renders the breaking overlay normally
|
||||
), method = "renderLevel")
|
||||
private void renderCrumbling(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
|
||||
if (renderContext != null) {
|
||||
// TODO: Crumbling
|
||||
}
|
||||
}
|
||||
// @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 2, shift = Shift.BY, by = 2 // after the game renders the breaking overlay normally
|
||||
// ), method = "renderLevel")
|
||||
// private void flywheel$renderCrumbling(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
|
||||
// if (flywheel$renderContext != null) {
|
||||
// // TODO: Crumbling
|
||||
// }
|
||||
// }
|
||||
|
||||
// STAGE DISPATCHING
|
||||
|
||||
@Unique
|
||||
private void flywheel$dispatch(RenderStage stage) {
|
||||
if (renderContext != null) {
|
||||
if (flywheel$renderContext != null) {
|
||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||
MinecraftForge.EVENT_BUS.post(new RenderStageEvent(renderContext, stage));
|
||||
MinecraftForge.EVENT_BUS.post(new RenderStageEvent(flywheel$renderContext, stage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=sky"))
|
||||
private void onStage$beforeSky(CallbackInfo ci) {
|
||||
private void flywheel$onStage$beforeSky(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.BEFORE_SKY);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=fog"))
|
||||
private void onStage$afterSky(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterSky(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_SKY);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=terrain"))
|
||||
private void onStage$beforeTerrain(CallbackInfo ci) {
|
||||
private void flywheel$onStage$beforeTerrain(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.BEFORE_TERRAIN);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=entities"))
|
||||
private void onStage$afterSolidTerrain(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterSolidTerrain(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_SOLID_TERRAIN);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBuffers;bufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 0))
|
||||
private void onStage$beforeEntities(CallbackInfo ci) {
|
||||
private void flywheel$onStage$beforeEntities(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.BEFORE_ENTITIES);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=blockentities"))
|
||||
private void onStage$beforeBlockEntities(CallbackInfo ci) {
|
||||
private void flywheel$onStage$beforeBlockEntities(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_ENTITIES);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/OutlineBufferSource;endOutlineBatch()V", ordinal = 0))
|
||||
private void onStage$afterSolidBlockEntities(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterSolidBlockEntities(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_BLOCK_ENTITIES);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch()V", ordinal = 0))
|
||||
private void onStage$beforeCrumbling(CallbackInfo ci) {
|
||||
private void flywheel$onStage$beforeCrumbling(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.BEFORE_CRUMBLING);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/LevelRenderer;translucentTarget:Lcom/mojang/blaze3d/pipeline/RenderTarget;", opcode = Opcodes.GETFIELD, ordinal = 0))
|
||||
private void onStage$afterFinalEndBatch$fabulous(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterFinalEndBatch$fabulous(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_FINAL_END_BATCH);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/LevelRenderer;particlesTarget:Lcom/mojang/blaze3d/pipeline/RenderTarget;", opcode = Opcodes.GETFIELD, ordinal = 0))
|
||||
private void onStage$afterTranslucentTerrain$fabulous(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterTranslucentTerrain$fabulous(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_TRANSLUCENT_TERRAIN);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch()V", ordinal = 2, shift = Shift.AFTER))
|
||||
private void onStage$afterFinalEndBatch(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterFinalEndBatch(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_FINAL_END_BATCH);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V", ordinal = 6, shift = Shift.AFTER))
|
||||
private void onStage$afterTranslucentTerrain(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterTranslucentTerrain(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_TRANSLUCENT_TERRAIN);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;FLnet/minecraft/client/renderer/culling/Frustum;)V", shift = Shift.AFTER))
|
||||
private void onStage$afterParticles(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterParticles(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_PARTICLES);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;renderSnowAndRain(Lnet/minecraft/client/renderer/LightTexture;FDDD)V", shift = Shift.AFTER))
|
||||
private void onStage$afterWeather(CallbackInfo ci) {
|
||||
private void flywheel$onStage$afterWeather(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_WEATHER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import net.minecraft.client.Minecraft;
|
|||
|
||||
@Mixin(Minecraft.class)
|
||||
public interface PausedPartialTickAccessor {
|
||||
|
||||
@Accessor("pausePartialTick")
|
||||
float flywheel$getPartialTicksPaused();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.batching.DrawBuffer;
|
||||
import com.jozufozu.flywheel.util.RenderTypeExtension;
|
||||
import com.jozufozu.flywheel.extension.RenderTypeExtension;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
|
@ -18,7 +18,7 @@ public class RenderTypeMixin implements RenderTypeExtension {
|
|||
@NotNull
|
||||
public DrawBuffer flywheel$getDrawBuffer() {
|
||||
if (flywheel$drawBuffer == null) {
|
||||
flywheel$drawBuffer = new DrawBuffer((RenderType) (Object) this);
|
||||
flywheel$drawBuffer = new DrawBuffer(((RenderType) (Object) this).format());
|
||||
}
|
||||
return flywheel$drawBuffer;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.jozufozu.flywheel.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
||||
import com.jozufozu.flywheel.extension.VertexFormatExtension;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
@Mixin(VertexFormat.class)
|
||||
public class VertexFormatMixin implements VertexFormatExtension {
|
||||
@Unique
|
||||
private VertexListProvider flywheel$vertexListProvider;
|
||||
|
||||
@Override
|
||||
public VertexListProvider flywheel$getVertexListProvider() {
|
||||
return flywheel$vertexListProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flywheel$setVertexListProvider(VertexListProvider provider) {
|
||||
flywheel$vertexListProvider = provider;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package com.jozufozu.flywheel.mixin.light;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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;
|
||||
|
@ -15,6 +17,9 @@ import net.minecraft.world.level.chunk.ChunkSource;
|
|||
|
||||
@Mixin(ClientChunkCache.class)
|
||||
public abstract class LightUpdateMixin extends ChunkSource {
|
||||
@Shadow
|
||||
@Final
|
||||
ClientLevel level;
|
||||
|
||||
/**
|
||||
* JUSTIFICATION: This method is called after a lighting tick once per subchunk where a
|
||||
|
@ -23,11 +28,8 @@ public abstract class LightUpdateMixin extends ChunkSource {
|
|||
* and we should too.
|
||||
*/
|
||||
@Inject(at = @At("HEAD"), method = "onLightUpdate")
|
||||
private void onLightUpdate(LightLayer type, SectionPos pos, CallbackInfo ci) {
|
||||
ClientChunkCache thi = ((ClientChunkCache) (Object) this);
|
||||
ClientLevel world = (ClientLevel) thi.getLevel();
|
||||
|
||||
LightUpdater.get(world)
|
||||
private void flywheel$onLightUpdate(LightLayer type, SectionPos pos, CallbackInfo ci) {
|
||||
LightUpdater.get(level)
|
||||
.onLightUpdate(type, pos.asLong());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,8 @@ import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
|
|||
|
||||
@Mixin(ClientPacketListener.class)
|
||||
public class NetworkLightUpdateMixin {
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "handleLightUpdatePacket")
|
||||
private void onLightPacket(ClientboundLightUpdatePacket packet, CallbackInfo ci) {
|
||||
private void flywheel$onLightPacket(ClientboundLightUpdatePacket packet, CallbackInfo ci) {
|
||||
RenderWork.enqueue(() -> {
|
||||
ClientLevel world = Minecraft.getInstance().level;
|
||||
|
||||
|
|
|
@ -6,12 +6,11 @@ import org.lwjgl.system.MemoryUtil;
|
|||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import com.jozufozu.flywheel.util.MatrixWrite;
|
||||
import com.jozufozu.flywheel.extension.MatrixWrite;
|
||||
import com.mojang.math.Matrix3f;
|
||||
|
||||
@Mixin(Matrix3f.class)
|
||||
public abstract class Matrix3fMixin implements MatrixWrite {
|
||||
|
||||
@Shadow protected float m00;
|
||||
@Shadow protected float m01;
|
||||
@Shadow protected float m02;
|
||||
|
|
|
@ -6,12 +6,11 @@ import org.lwjgl.system.MemoryUtil;
|
|||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import com.jozufozu.flywheel.util.MatrixWrite;
|
||||
import com.jozufozu.flywheel.extension.MatrixWrite;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
@Mixin(Matrix4f.class)
|
||||
public abstract class Matrix4fMixin implements MatrixWrite {
|
||||
|
||||
@Shadow protected float m00;
|
||||
@Shadow protected float m01;
|
||||
@Shadow protected float m02;
|
||||
|
|
|
@ -8,34 +8,33 @@ import com.mojang.math.Quaternion;
|
|||
|
||||
@Mixin(PoseStack.class)
|
||||
public abstract class PoseStackMixin implements TransformStack {
|
||||
|
||||
@Override
|
||||
public TransformStack multiply(Quaternion quaternion) {
|
||||
((PoseStack)(Object) this).mulPose(quaternion);
|
||||
((PoseStack) (Object) this).mulPose(quaternion);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformStack scale(float factorX, float factorY, float factorZ) {
|
||||
((PoseStack)(Object) this).scale(factorX, factorY, factorZ);
|
||||
((PoseStack) (Object) this).scale(factorX, factorY, factorZ);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformStack pushPose() {
|
||||
((PoseStack)(Object) this).pushPose();
|
||||
((PoseStack) (Object) this).pushPose();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformStack popPose() {
|
||||
((PoseStack)(Object) this).popPose();
|
||||
((PoseStack) (Object) this).popPose();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformStack translate(double x, double y, double z) {
|
||||
((PoseStack)(Object) this).translate(x, y, z);
|
||||
((PoseStack) (Object) this).translate(x, y, z);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,10 @@ public class StringUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static String formatAddress(long address) {
|
||||
return "0x" + Long.toHexString(address);
|
||||
}
|
||||
|
||||
public static String args(String functionName, Object... args) {
|
||||
|
||||
return functionName + '(' + Arrays.stream(args)
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package com.jozufozu.flywheel.util.transform;
|
||||
|
||||
public interface TStack<Self> {
|
||||
Self pushPose();
|
||||
|
||||
Self popPose();
|
||||
}
|
|
@ -2,7 +2,11 @@ package com.jozufozu.flywheel.util.transform;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
public interface TransformStack extends Transform<TransformStack>, TStack<TransformStack> {
|
||||
public interface TransformStack extends Transform<TransformStack> {
|
||||
TransformStack pushPose();
|
||||
|
||||
TransformStack popPose();
|
||||
|
||||
static TransformStack cast(PoseStack stack) {
|
||||
return (TransformStack) stack;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"LevelRendererMixin",
|
||||
"PausedPartialTickAccessor",
|
||||
"RenderTypeMixin",
|
||||
"VertexFormatMixin",
|
||||
"light.LightUpdateMixin",
|
||||
"light.NetworkLightUpdateMixin",
|
||||
"matrix.Matrix3fMixin",
|
||||
|
|
Loading…
Reference in a new issue