Fix crash after compilation error during in-world resource reload

- Store *Programs inside engines to disallow replacement and use
reference counting to delete programs at the appropriate time
- Move CompilationHarness, Compile, and SourceLoader to compile.core
- Fix packed material comments
- Fix pack.mcmeta pack format
- Remove Embeddium version range
This commit is contained in:
PepperCode1 2024-01-17 10:37:39 -08:00
parent 45ba75af78
commit 80127664d2
25 changed files with 210 additions and 139 deletions

View file

@ -157,8 +157,7 @@ tasks.named('processResources', ProcessResources).configure {
forge_version : forge_version,
forge_version_range : forge_version_range,
loader_version_range : loader_version_range,
mod_version : mod_version,
embeddium_version_range: embeddium_version_range
mod_version : mod_version
]
inputs.properties replaceProperties

View file

@ -10,7 +10,6 @@ forge_version=47.2.19
minecraft_version_range=[1.20.1,1.20.3)
forge_version_range=[47,)
loader_version_range=[47,)
embeddium_version_range=[0.2.10,0.3)
# build dependency versions
forgegradle_version = [6.0.16,6.2)

View file

@ -21,7 +21,7 @@ public class Backends {
public static final Backend INSTANCING = SimpleBackend.builder()
.engineMessage(Component.literal("Using Instancing Engine")
.withStyle(ChatFormatting.GREEN))
.engineFactory(level -> new InstancingEngine(256))
.engineFactory(level -> new InstancingEngine(InstancingPrograms.get(), 256))
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsInstancing() && InstancingPrograms.allLoaded())
.register(Flywheel.rl("instancing"));
@ -31,7 +31,7 @@ public class Backends {
public static final Backend INDIRECT = SimpleBackend.builder()
.engineMessage(Component.literal("Using Indirect Engine")
.withStyle(ChatFormatting.GREEN))
.engineFactory(level -> new IndirectEngine(256))
.engineFactory(level -> new IndirectEngine(IndirectPrograms.get(), 256))
.fallback(() -> Backends.INSTANCING)
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsIndirect() && IndirectPrograms.allLoaded())
.register(Flywheel.rl("indirect"));

View file

@ -0,0 +1,31 @@
package com.jozufozu.flywheel.backend.compile;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class AbstractPrograms {
private final AtomicInteger refCount = new AtomicInteger();
private volatile boolean isDeleted;
public int refCount() {
return refCount.get();
}
public void acquire() {
if (isDeleted) {
throw new IllegalStateException("Tried to acquire deleted instance of '" + getClass().getName() + "'!");
}
refCount.getAndIncrement();
}
public void release() {
int newCount = refCount.decrementAndGet();
if (newCount == 0) {
isDeleted = true;
delete();
} else if (newCount < 0) {
throw new IllegalStateException("Tried to delete instance of '" + getClass().getName() + "' more times than it was acquired!");
}
}
protected abstract void delete();
}

View file

@ -11,6 +11,7 @@ import com.jozufozu.flywheel.backend.ShaderIndices;
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.backend.compile.core.CompilerStats;
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
import com.jozufozu.flywheel.backend.glsl.generate.FnSignature;
@ -19,13 +20,12 @@ import com.jozufozu.flywheel.backend.glsl.generate.GlslExpr;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
public class FlwPrograms {
public final class FlwPrograms {
private FlwPrograms() {
}
public static void reload(ResourceManager resourceManager) {
private static void reload(ResourceManager resourceManager) {
var sources = new ShaderSources(resourceManager);
var preLoadStats = new CompilerStats();
var loadChecker = new SourceLoader(sources, preLoadStats);

View file

@ -11,6 +11,8 @@ import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
import com.jozufozu.flywheel.backend.compile.core.Compile;
import com.jozufozu.flywheel.backend.gl.GlCompat;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
@ -20,20 +22,23 @@ import com.jozufozu.flywheel.backend.glsl.SourceComponent;
import net.minecraft.resources.ResourceLocation;
public class IndirectPrograms {
public class IndirectPrograms extends AbstractPrograms {
private static final ResourceLocation CULL_SHADER_MAIN = Flywheel.rl("internal/indirect/cull.glsl");
private static final ResourceLocation APPLY_SHADER_MAIN = Flywheel.rl("internal/indirect/apply.glsl");
private static final ResourceLocation SCATTER_SHADER_MAIN = Flywheel.rl("internal/indirect/scatter.glsl");
public static IndirectPrograms instance;
private static final Compile<InstanceType<?>> CULL = new Compile<>();
private static final Compile<ResourceLocation> UTIL = new Compile<>();
@Nullable
private static IndirectPrograms instance;
private final Map<PipelineProgramKey, GlProgram> pipeline;
private final Map<InstanceType<?>, GlProgram> culling;
private final GlProgram apply;
private final GlProgram scatter;
public IndirectPrograms(Map<PipelineProgramKey, GlProgram> pipeline, Map<InstanceType<?>, GlProgram> culling, GlProgram apply, GlProgram scatter) {
private IndirectPrograms(Map<PipelineProgramKey, GlProgram> pipeline, Map<InstanceType<?>, GlProgram> culling, GlProgram apply, GlProgram scatter) {
this.pipeline = pipeline;
this.culling = culling;
this.apply = apply;
@ -41,7 +46,8 @@ public class IndirectPrograms {
}
static void reload(ShaderSources sources, ImmutableList<PipelineProgramKey> pipelineKeys, UniformComponent uniformComponent, List<SourceComponent> vertexComponents, List<SourceComponent> fragmentComponents) {
_delete();
IndirectPrograms newInstance = null;
var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INDIRECT, uniformComponent, vertexComponents, fragmentComponents);
var cullingCompiler = createCullingCompiler(uniformComponent, sources);
var applyCompiler = createUtilCompiler(sources);
@ -52,38 +58,17 @@ public class IndirectPrograms {
var utils = applyCompiler.compileAndReportErrors(List.of(APPLY_SHADER_MAIN, SCATTER_SHADER_MAIN));
if (pipelineResult != null && cullingResult != null && utils != null) {
instance = new IndirectPrograms(pipelineResult, cullingResult, utils.get(APPLY_SHADER_MAIN), utils.get(SCATTER_SHADER_MAIN));
newInstance = new IndirectPrograms(pipelineResult, cullingResult, utils.get(APPLY_SHADER_MAIN), utils.get(SCATTER_SHADER_MAIN));
}
} catch (Throwable e) {
Flywheel.LOGGER.error("Failed to compile indirect programs", e);
} catch (Throwable t) {
Flywheel.LOGGER.error("Failed to compile indirect programs", t);
}
pipelineCompiler.delete();
cullingCompiler.delete();
applyCompiler.delete();
}
private static ImmutableList<InstanceType<?>> createCullingKeys() {
ImmutableList.Builder<InstanceType<?>> builder = ImmutableList.builder();
for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
builder.add(instanceType);
}
return builder.build();
}
@Nullable
public static IndirectPrograms get() {
return instance;
}
public static boolean allLoaded() {
return instance != null;
}
private static void _delete() {
if (instance != null) {
instance.delete();
instance = null;
}
setInstance(newInstance);
}
private static CompilationHarness<InstanceType<?>> createCullingCompiler(UniformComponent uniformComponent, ShaderSources sources) {
@ -106,6 +91,33 @@ public class IndirectPrograms {
.harness(sources);
}
private static ImmutableList<InstanceType<?>> createCullingKeys() {
ImmutableList.Builder<InstanceType<?>> builder = ImmutableList.builder();
for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
builder.add(instanceType);
}
return builder.build();
}
private static void setInstance(@Nullable IndirectPrograms newInstance) {
if (instance != null) {
instance.release();
}
if (newInstance != null) {
newInstance.acquire();
}
instance = newInstance;
}
@Nullable
public static IndirectPrograms get() {
return instance;
}
public static boolean allLoaded() {
return instance != null;
}
public GlProgram getIndirectProgram(InstanceType<?> instanceType, Context contextShader) {
return pipeline.get(new PipelineProgramKey(instanceType, contextShader));
}
@ -122,7 +134,8 @@ public class IndirectPrograms {
return scatter;
}
public void delete() {
@Override
protected void delete() {
pipeline.values()
.forEach(GlProgram::delete);
culling.values()

View file

@ -14,28 +14,44 @@ import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
public class InstancingPrograms {
static InstancingPrograms instance;
public class InstancingPrograms extends AbstractPrograms {
@Nullable
private static InstancingPrograms instance;
private final Map<PipelineProgramKey, GlProgram> pipeline;
public InstancingPrograms(Map<PipelineProgramKey, GlProgram> pipeline) {
private InstancingPrograms(Map<PipelineProgramKey, GlProgram> pipeline) {
this.pipeline = pipeline;
}
static void reload(ShaderSources sources, ImmutableList<PipelineProgramKey> pipelineKeys, UniformComponent uniformComponent, List<SourceComponent> vertexComponents, List<SourceComponent> fragmentComponents) {
_delete();
var instancingCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCED_ARRAYS, uniformComponent, vertexComponents, fragmentComponents);
InstancingPrograms newInstance = null;
var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCED_ARRAYS, uniformComponent, vertexComponents, fragmentComponents);
try {
var result = instancingCompiler.compileAndReportErrors(pipelineKeys);
var pipelineResult = pipelineCompiler.compileAndReportErrors(pipelineKeys);
if (result != null) {
instance = new InstancingPrograms(result);
if (pipelineResult != null) {
newInstance = new InstancingPrograms(pipelineResult);
}
} catch (Throwable e) {
Flywheel.LOGGER.error("Failed to compile instancing programs", e);
} catch (Throwable t) {
Flywheel.LOGGER.error("Failed to compile instancing programs", t);
}
instancingCompiler.delete();
pipelineCompiler.delete();
setInstance(newInstance);
}
private static void setInstance(@Nullable InstancingPrograms newInstance) {
if (instance != null) {
instance.release();
}
if (newInstance != null) {
newInstance.acquire();
}
instance = newInstance;
}
@Nullable
@ -47,18 +63,12 @@ public class InstancingPrograms {
return instance != null;
}
static void _delete() {
if (instance != null) {
instance.delete();
instance = null;
}
}
public GlProgram get(InstanceType<?> instanceType, Context contextShader) {
return pipeline.get(new PipelineProgramKey(instanceType, contextShader));
}
public void delete() {
@Override
protected void delete() {
pipeline.values()
.forEach(GlProgram::delete);
}

View file

@ -9,7 +9,10 @@ import com.jozufozu.flywheel.api.layout.UnsignedIntegerRepr;
import com.jozufozu.flywheel.api.layout.ValueRepr;
import com.jozufozu.flywheel.api.layout.VectorElementType;
public class LayoutInterpreter {
public final class LayoutInterpreter {
private LayoutInterpreter() {
}
public static int attributeCount(ElementType type) {
if (type instanceof ScalarElementType) {
return 1;
@ -34,8 +37,15 @@ public class LayoutInterpreter {
throw new IllegalArgumentException("Unknown type " + type);
}
public static String matrixTypeName(MatrixElementType matrix) {
return "mat" + matrix.columns() + "x" + matrix.rows();
public static String scalarTypeName(ValueRepr repr) {
if (repr instanceof IntegerRepr) {
return "int";
} else if (repr instanceof UnsignedIntegerRepr) {
return "uint";
} else if (repr instanceof FloatRepr) {
return "float";
}
throw new IllegalArgumentException("Unknown repr " + repr);
}
public static String vectorTypeName(ValueRepr repr, int size) {
@ -49,14 +59,7 @@ public class LayoutInterpreter {
throw new IllegalArgumentException("Unknown repr " + repr);
}
public static String scalarTypeName(ValueRepr repr) {
if (repr instanceof IntegerRepr) {
return "int";
} else if (repr instanceof UnsignedIntegerRepr) {
return "uint";
} else if (repr instanceof FloatRepr) {
return "float";
}
throw new IllegalArgumentException("Unknown repr " + repr);
public static String matrixTypeName(MatrixElementType matrix) {
return "mat" + matrix.columns() + "x" + matrix.rows();
}
}

View file

@ -4,6 +4,8 @@ import java.util.List;
import com.jozufozu.flywheel.backend.InternalVertex;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
import com.jozufozu.flywheel.backend.compile.core.Compile;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
import com.jozufozu.flywheel.backend.glsl.SourceComponent;

View file

@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.backend.compile.SourceLoader;
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
import com.jozufozu.flywheel.backend.glsl.SourceFile;
import com.jozufozu.flywheel.backend.glsl.generate.FnSignature;

View file

@ -5,7 +5,7 @@ import java.util.Collection;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.backend.compile.SourceLoader;
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
import com.jozufozu.flywheel.backend.glsl.SourceFile;
import com.jozufozu.flywheel.backend.glsl.generate.GlslBuilder;

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import java.util.Collection;
import java.util.HashMap;
@ -7,9 +7,6 @@ import java.util.Map;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.compile.core.CompilerStats;
import com.jozufozu.flywheel.backend.compile.core.ProgramLinker;
import com.jozufozu.flywheel.backend.compile.core.ShaderCompiler;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.glsl.ShaderSources;

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import java.util.ArrayList;
import java.util.Collection;
@ -13,9 +13,6 @@ import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.backend.compile.core.Compilation;
import com.jozufozu.flywheel.backend.compile.core.ProgramLinker;
import com.jozufozu.flywheel.backend.compile.core.ShaderCompiler;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;

View file

@ -1,15 +1,13 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.backend.compile.core.CompilerStats;
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
import com.jozufozu.flywheel.backend.glsl.SourceFile;
import net.minecraft.resources.ResourceLocation;
public class SourceLoader {
private final ShaderSources sources;
private final CompilerStats stats;

View file

@ -20,7 +20,8 @@ public class CommonCrumbling {
.transparency(Transparency.CRUMBLING)
.writeMask(WriteMask.COLOR)
.useOverlay(false)
.useLight(false);
.useLight(false)
.diffuse(false);
}
public static int getDiffuseTexture(Material material) {

View file

@ -8,7 +8,7 @@ import com.jozufozu.flywheel.backend.ShaderIndices;
import net.minecraft.util.Mth;
// Materials are unpacked in "flywheel:flywheel/internal/material.glsl"
// Materials are unpacked in "flywheel:flywheel/internal/packed_material.glsl"
public final class MaterialEncoder {
// The number of bits each property takes up
private static final int BLUR_LENGTH = 1;
@ -65,7 +65,7 @@ public final class MaterialEncoder {
}
// Packed format:
// diffuse[1] | useOverlay[1] | useLight[1] | writeMask[2] | transparency[3] | depthTest[4] | polygonOffset[1] | backfaceCulling[1] | mipmap[1] | blur[1]
// diffuse[1] | useLight[1] | useOverlay[1] | writeMask[2] | transparency[3] | depthTest[4] | polygonOffset[1] | backfaceCulling[1] | mipmap[1] | blur[1]
public static int packProperties(Material material) {
int bits = 0;

View file

@ -36,34 +36,34 @@ public class IndirectCullingGroup<I extends Instance> {
private static final int DRAW_BARRIER_BITS = GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT;
private final GlProgram cullProgram;
private final GlProgram applyProgram;
private final GlProgram drawProgram;
private final InstanceType<I> instanceType;
private final long objectStride;
private final IndirectBuffers buffers;
private final IndirectMeshPool meshPool;
private final List<IndirectModel> indirectModels = new ArrayList<>();
private final List<IndirectDraw> indirectDraws = new ArrayList<>();
private final Map<RenderStage, List<MultiDraw>> multiDraws = new EnumMap<>(RenderStage.class);
private final InstanceType<I> instanceType;
private final IndirectPrograms programs;
private final GlProgram cullProgram;
private final GlProgram applyProgram;
private final GlProgram drawProgram;
private boolean needsDrawBarrier;
private boolean hasNewDraws;
private int instanceCountThisFrame;
IndirectCullingGroup(InstanceType<I> instanceType) {
IndirectCullingGroup(InstanceType<I> instanceType, IndirectPrograms programs) {
this.instanceType = instanceType;
var programs = IndirectPrograms.get();
objectStride = instanceType.layout()
.byteSize() + IndirectBuffers.INT_SIZE;
buffers = new IndirectBuffers(objectStride);
meshPool = new IndirectMeshPool();
this.programs = programs;
cullProgram = programs.getCullingProgram(instanceType);
applyProgram = programs.getApplyProgram();
drawProgram = programs.getIndirectProgram(instanceType, Contexts.DEFAULT);
objectStride = instanceType.layout()
.byteSize() + IndirectBuffers.INT_SIZE;
buffers = new IndirectBuffers(objectStride);
meshPool = new IndirectMeshPool();
}
public void flush(StagingBuffer stagingBuffer) {
@ -200,8 +200,7 @@ public class IndirectCullingGroup<I extends Instance> {
}
public void bindForCrumbling() {
var program = IndirectPrograms.get()
.getIndirectProgram(instanceType, Contexts.CRUMBLING);
var program = programs.getIndirectProgram(instanceType, Contexts.CRUMBLING);
program.bind();

View file

@ -18,6 +18,7 @@ import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
import com.jozufozu.flywheel.backend.engine.InstancerKey;
@ -34,10 +35,16 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.client.resources.model.ModelBakery;
public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>> {
private final StagingBuffer stagingBuffer = new StagingBuffer();
private final IndirectPrograms programs;
private final StagingBuffer stagingBuffer;
private final Map<InstanceType<?>, IndirectCullingGroup<?>> cullingGroups = new HashMap<>();
private final GlBuffer crumblingDrawBuffer = new GlBuffer();
public IndirectDrawManager(IndirectPrograms programs) {
this.programs = programs;
stagingBuffer = new StagingBuffer(this.programs);
}
@Override
protected <I extends Instance> IndirectInstancer<?> create(InstanceType<I> type) {
return new IndirectInstancer<>(type);
@ -52,7 +59,7 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
return;
}
var group = (IndirectCullingGroup<I>) cullingGroups.computeIfAbsent(key.type(), IndirectCullingGroup::new);
var group = (IndirectCullingGroup<I>) cullingGroups.computeIfAbsent(key.type(), t -> new IndirectCullingGroup<>(t, programs));
group.add((IndirectInstancer<I>) instancer, model, stage);
}

View file

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.task.Plan;
import com.jozufozu.flywheel.api.task.TaskExecutor;
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
import com.jozufozu.flywheel.backend.engine.AbstractEngine;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
@ -19,13 +20,18 @@ import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
public class IndirectEngine extends AbstractEngine {
private final IndirectDrawManager drawManager = new IndirectDrawManager();
private final IndirectPrograms programs;
private final IndirectDrawManager drawManager;
private final Flag flushFlag = new NamedFlag("flushed");
public IndirectEngine(int maxOriginDistance) {
public IndirectEngine(IndirectPrograms programs, int maxOriginDistance) {
super(maxOriginDistance);
programs.acquire();
this.programs = programs;
drawManager = new IndirectDrawManager(this.programs);
}
@Override
@ -52,9 +58,10 @@ public class IndirectEngine extends AbstractEngine {
}
try (var restoreState = GlStateTracker.getRestoreState()) {
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
int prevActiveTexture = GlStateManager._getActiveTexture();
Minecraft.getInstance().gameRenderer.overlayTexture().setupOverlayColor();
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
gameRenderer.overlayTexture().setupOverlayColor();
gameRenderer.lightTexture().turnOnLightLayer();
GlTextureUnit.T1.makeActive();
RenderSystem.bindTexture(RenderSystem.getShaderTexture(1));
@ -65,8 +72,8 @@ public class IndirectEngine extends AbstractEngine {
MaterialRenderState.reset();
Minecraft.getInstance().gameRenderer.overlayTexture().teardownOverlayColor();
Minecraft.getInstance().gameRenderer.lightTexture().turnOffLightLayer();
gameRenderer.overlayTexture().teardownOverlayColor();
gameRenderer.lightTexture().turnOffLightLayer();
GlStateManager._activeTexture(prevActiveTexture);
}
}
@ -90,5 +97,6 @@ public class IndirectEngine extends AbstractEngine {
@Override
public void delete() {
drawManager.delete();
programs.release();
}
}

View file

@ -12,6 +12,7 @@ import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
import com.jozufozu.flywheel.backend.gl.GlCompat;
import com.jozufozu.flywheel.backend.gl.GlFence;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
@ -29,6 +30,14 @@ public class StagingBuffer {
private final long map;
private final long capacity;
private final OverflowStagingBuffer overflow = new OverflowStagingBuffer();
private final TransferList transfers = new TransferList();
private final PriorityQueue<FencedRegion> fencedRegions = new ObjectArrayFIFOQueue<>();
private final GlBuffer scatterBuffer = new GlBuffer();
private final ScatterList scatterList = new ScatterList();
private final GlProgram scatterProgram;
/**
* The position in the buffer at the time of the last flush.
*/
@ -58,17 +67,14 @@ public class StagingBuffer {
@Nullable
private MemoryBlock scratch;
private final OverflowStagingBuffer overflow = new OverflowStagingBuffer();
private final TransferList transfers = new TransferList();
private final PriorityQueue<FencedRegion> fencedRegions = new ObjectArrayFIFOQueue<>();
private final GlBuffer scatterBuffer = new GlBuffer();
private final ScatterList scatterList = new ScatterList();
public StagingBuffer() {
this(DEFAULT_CAPACITY);
public StagingBuffer(IndirectPrograms programs) {
this(DEFAULT_CAPACITY, programs);
}
public StagingBuffer(long capacity) {
public StagingBuffer(long capacity, IndirectPrograms programs) {
scatterProgram = IndirectPrograms.get()
.getScatterProgram();
this.capacity = capacity;
vbo = GL45C.glCreateBuffers();
@ -247,9 +253,7 @@ public class StagingBuffer {
* <a href=https://on-demand.gputechconf.com/gtc/2016/presentation/s6138-christoph-kubisch-pierre-boudier-gpu-driven-rendering.pdf>this presentation</a>
*/
private void dispatchComputeCopies() {
IndirectPrograms.get()
.getScatterProgram()
.bind();
scatterProgram.bind();
// These bindings don't change between dstVbos.
GL45.glBindBufferBase(GL45C.GL_SHADER_STORAGE_BUFFER, 0, scatterBuffer.handle());

View file

@ -23,7 +23,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.client.resources.model.ModelBakery;
public class InstancedCrumbling {
public static void render(List<Engine.CrumblingBlock> crumblingBlocks) {
public static void render(List<Engine.CrumblingBlock> crumblingBlocks, InstancingPrograms programs) {
// Sort draw calls into buckets, so we don't have to do as many shader binds.
var byShaderState = doCrumblingSort(crumblingBlocks);
@ -48,8 +48,7 @@ public class InstancedCrumbling {
CommonCrumbling.applyCrumblingProperties(crumblingMaterial, baseMaterial);
var program = InstancingPrograms.get()
.get(shader.instanceType(), Contexts.CRUMBLING);
var program = programs.get(shader.instanceType(), Contexts.CRUMBLING);
program.bind();
UniformBuffer.get().sync();
@ -108,7 +107,7 @@ public class InstancedCrumbling {
}
}
}
return out;
}
}

View file

@ -28,14 +28,17 @@ import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
public class InstancingEngine extends AbstractEngine {
private final InstancingPrograms programs;
private final InstancedDrawManager drawManager = new InstancedDrawManager();
private final Flag flushFlag = new NamedFlag("flushed");
public InstancingEngine(int maxOriginDistance) {
public InstancingEngine(InstancingPrograms programs, int maxOriginDistance) {
super(maxOriginDistance);
programs.acquire();
this.programs = programs;
}
@Override
@ -64,9 +67,10 @@ public class InstancingEngine extends AbstractEngine {
}
try (var state = GlStateTracker.getRestoreState()) {
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
int prevActiveTexture = GlStateManager._getActiveTexture();
Minecraft.getInstance().gameRenderer.overlayTexture().setupOverlayColor();
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
gameRenderer.overlayTexture().setupOverlayColor();
gameRenderer.lightTexture().turnOnLightLayer();
GlTextureUnit.T1.makeActive();
RenderSystem.bindTexture(RenderSystem.getShaderTexture(1));
@ -75,8 +79,8 @@ public class InstancingEngine extends AbstractEngine {
render(drawSet);
Minecraft.getInstance().gameRenderer.overlayTexture().teardownOverlayColor();
Minecraft.getInstance().gameRenderer.lightTexture().turnOffLightLayer();
gameRenderer.overlayTexture().teardownOverlayColor();
gameRenderer.lightTexture().turnOffLightLayer();
GlStateManager._activeTexture(prevActiveTexture);
}
}
@ -86,7 +90,7 @@ public class InstancingEngine extends AbstractEngine {
// Need to wait for flush before we can inspect instancer state.
executor.syncUntil(flushFlag::isRaised);
InstancedCrumbling.render(crumblingBlocks);
InstancedCrumbling.render(crumblingBlocks, programs);
}
@Override
@ -97,6 +101,7 @@ public class InstancingEngine extends AbstractEngine {
@Override
public void delete() {
drawManager.delete();
programs.release();
}
private void render(InstancedDrawManager.DrawSet drawSet) {
@ -110,8 +115,7 @@ public class InstancingEngine extends AbstractEngine {
continue;
}
var program = InstancingPrograms.get()
.get(shader.instanceType(), Contexts.DEFAULT);
var program = programs.get(shader.instanceType(), Contexts.DEFAULT);
program.bind();
UniformBuffer.get().sync();

View file

@ -31,9 +31,9 @@ side = "CLIENT"
[[dependencies.flywheel]]
modId = "rubidium"
# This replicates a "breaks" dependency.
# There's a mixin crash with Rubidium <0.7.0.
mandatory = false
# This should be a "breaks" dependency.
# There's a mixin crash with Rubidum < 0.7.0
versionRange = "[0.7.0,)"
ordering = "NONE"
side = "CLIENT"

View file

@ -35,7 +35,7 @@ const uint _FLW_USE_LIGHT_MASK = ((1u << _FLW_USE_LIGHT_LENGTH) - 1u) << _FLW_US
const uint _FLW_DIFFUSE_MASK = ((1u << _FLW_DIFFUSE_LENGTH) - 1u) << _FLW_DIFFUSE_OFFSET;
// Packed format:
// diffuse[1] | useOverlay[1] | useLight[1] | writeMask[2] | transparency[3] | depthTest[4] | polygonOffset[1] | backfaceCulling[1] | mipmap[1] | blur[1]
// diffuse[1] | useLight[1] | useOverlay[1] | writeMask[2] | transparency[3] | depthTest[4] | polygonOffset[1] | backfaceCulling[1] | mipmap[1] | blur[1]
void _flw_unpackMaterialProperties(uint p, out FlwMaterial m) {
m.blur = (p & _FLW_BLUR_MASK) != 0u;
m.mipmap = (p & _FLW_MIPMAP_MASK) != 0u;

View file

@ -1,6 +1,6 @@
{
"pack": {
"description": "Flywheel resources",
"pack_format": 18
"pack_format": 15
}
}