mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-26 15:06:28 +01:00
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:
parent
45ba75af78
commit
80127664d2
25 changed files with 210 additions and 139 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"pack": {
|
||||
"description": "Flywheel resources",
|
||||
"pack_format": 18
|
||||
"pack_format": 15
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue