From e7339dc7ef5ac096f52867348241cfaeb0dbf600 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Tue, 9 Aug 2022 15:38:56 -0700 Subject: [PATCH] Condensing culling - Adapt compilers to work with arbitrary instance types - Use single compiler for all draw shaders - Temp solution for instanced array attributes - Introduce pipeline shaders --- .../java/com/jozufozu/flywheel/Flywheel.java | 4 +- .../flywheel/api/pipeline/PipelineShader.java | 8 + .../com/jozufozu/flywheel/backend/Loader.java | 8 +- .../backend/instancing/PipelineCompiler.java | 154 +++++++++++ .../indirect/ComputeCullerCompiler.java | 13 +- .../indirect/IndirectDrawCompiler.java | 65 ----- .../instancing/indirect/IndirectEngine.java | 16 +- .../instancing/indirect/IndirectList.java | 29 +- .../instancing/InstancedArraysCompiler.java | 252 ------------------ .../instancing/InstancingEngine.java | 6 +- .../jozufozu/flywheel/core/Components.java | 33 ++- .../flywheel/core/source/FileResolution.java | 21 ++ .../flywheel/core/source/SourceChecks.java | 8 + .../flywheel/core/source/SourceFile.java | 5 +- .../flywheel/flywheel/instance/oriented.vert | 10 +- .../flywheel/instance/oriented_indirect.glsl | 2 +- .../flywheel/instance/transformed.vert | 8 +- .../flywheel/flywheel/layout/block.vert | 1 + .../flywheel/layout/pos_tex_normal.vert | 1 + .../draw.frag} | 2 - .../indirect_cull.glsl} | 12 +- .../indirect_draw.vert} | 8 +- .../pipeline/instanced_arrays_draw.vert | 8 + .../assets/flywheel/flywheel/util/types.glsl | 17 ++ 24 files changed, 299 insertions(+), 392 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/api/pipeline/PipelineShader.java create mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/PipelineCompiler.java delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectDrawCompiler.java delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedArraysCompiler.java rename src/main/resources/assets/flywheel/flywheel/{compute/draw_instances.frag => pipeline/draw.frag} (64%) rename src/main/resources/assets/flywheel/flywheel/{compute/cull_instances.glsl => pipeline/indirect_cull.glsl} (90%) rename src/main/resources/assets/flywheel/flywheel/{compute/draw_instances.vert => pipeline/indirect_draw.vert} (64%) create mode 100644 src/main/resources/assets/flywheel/flywheel/pipeline/instanced_arrays_draw.vert create mode 100644 src/main/resources/assets/flywheel/flywheel/util/types.glsl diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index 925dd3eb4..d03a87d29 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -16,7 +16,7 @@ import com.jozufozu.flywheel.core.DebugRender; import com.jozufozu.flywheel.core.PartialModel; import com.jozufozu.flywheel.core.QuadConverter; import com.jozufozu.flywheel.core.StitchedSprite; -import com.jozufozu.flywheel.backend.instancing.instancing.InstancedArraysCompiler; +import com.jozufozu.flywheel.backend.instancing.PipelineCompiler; import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer; import com.jozufozu.flywheel.core.model.Models; import com.jozufozu.flywheel.event.EntityWorldHandler; @@ -80,7 +80,7 @@ public class Flywheel { forgeEventBus.addListener(FlwCommands::registerClientCommands); forgeEventBus.addListener(EventPriority.HIGHEST, QuadConverter::onRendererReload); - forgeEventBus.addListener(InstancedArraysCompiler::invalidateAll); + forgeEventBus.addListener(PipelineCompiler::invalidateAll); forgeEventBus.addListener(Models::onReload); forgeEventBus.addListener(MeshPool::reset); forgeEventBus.addListener(CrumblingRenderer::onReloadRenderers); diff --git a/src/main/java/com/jozufozu/flywheel/api/pipeline/PipelineShader.java b/src/main/java/com/jozufozu/flywheel/api/pipeline/PipelineShader.java new file mode 100644 index 000000000..155614856 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/pipeline/PipelineShader.java @@ -0,0 +1,8 @@ +package com.jozufozu.flywheel.api.pipeline; + +import com.jozufozu.flywheel.backend.gl.GLSLVersion; +import com.jozufozu.flywheel.core.source.FileResolution; + +public record PipelineShader(GLSLVersion glslVersion, FileResolution vertex, FileResolution fragment) { + +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/Loader.java b/src/main/java/com/jozufozu/flywheel/backend/Loader.java index 25893bac4..8db9c2da0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Loader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Loader.java @@ -6,10 +6,10 @@ import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.core.ComponentRegistry; import com.jozufozu.flywheel.api.context.ContextShader; -import com.jozufozu.flywheel.backend.instancing.instancing.InstancedArraysCompiler; +import com.jozufozu.flywheel.backend.instancing.PipelineCompiler; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer; import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.source.ShaderLoadingException; import com.jozufozu.flywheel.core.source.ShaderSources; import com.jozufozu.flywheel.core.source.error.ErrorReporter; import com.jozufozu.flywheel.util.StringUtil; @@ -69,8 +69,8 @@ public class Loader implements ResourceManagerReloadListener { for (StructType structType : ComponentRegistry.structTypes) { for (VertexType vertexType : ComponentRegistry.vertexTypes) { for (ContextShader contextShader : ComponentRegistry.contextShaders) { - var ctx = new InstancedArraysCompiler.Context(vertexType, material, structType.getInstanceShader(), contextShader); - InstancedArraysCompiler.INSTANCE.getProgram(ctx); + var ctx = new PipelineCompiler.Context(vertexType, material, structType.getInstanceShader(), contextShader, Components.INSTANCED_ARRAYS); + PipelineCompiler.INSTANCE.getProgram(ctx); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/PipelineCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/PipelineCompiler.java new file mode 100644 index 000000000..1cf21721a --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/PipelineCompiler.java @@ -0,0 +1,154 @@ +package com.jozufozu.flywheel.backend.instancing; + +import java.util.List; + +import com.google.common.collect.ImmutableList; +import com.jozufozu.flywheel.api.context.ContextShader; +import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.pipeline.PipelineShader; +import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.backend.gl.GLSLVersion; +import com.jozufozu.flywheel.backend.gl.shader.GlProgram; +import com.jozufozu.flywheel.backend.gl.shader.GlShader; +import com.jozufozu.flywheel.backend.gl.shader.ShaderType; +import com.jozufozu.flywheel.core.compile.*; +import com.jozufozu.flywheel.core.source.CompilationContext; +import com.jozufozu.flywheel.core.source.FileResolution; +import com.jozufozu.flywheel.core.source.SourceFile; +import com.jozufozu.flywheel.event.ReloadRenderersEvent; + +import net.minecraft.resources.ResourceLocation; + +/** + * A caching compiler. + * + *

+ * This class is responsible for compiling programs on the fly. An instance of this class will keep a cache of + * compiled programs, and will only compile a program if it is not already in the cache. + *

+ *

+ * A ProgramCompiler is also responsible for deleting programs and shaders on renderer reload. + *

+ */ +public class PipelineCompiler extends Memoizer { + + public static final PipelineCompiler INSTANCE = new PipelineCompiler(); + + private final ShaderCompiler shaderCompiler; + + private PipelineCompiler() { + this.shaderCompiler = new ShaderCompiler(); + } + + /** + * Get or compile a spec to the given vertex type, accounting for all game state conditions specified by the spec. + * + * @param ctx The context of compilation. + * @return A compiled GlProgram. + */ + public GlProgram getProgram(PipelineCompiler.Context ctx) { + return super.get(ctx); + } + + @Override + public void invalidate() { + super.invalidate(); + shaderCompiler.invalidate(); + } + + @Override + protected GlProgram _create(PipelineCompiler.Context ctx) { + + var glslVersion = ctx.pipelineShader() + .glslVersion(); + + var vertex = new ShaderCompiler.Context(glslVersion, ShaderType.VERTEX, ctx.getVertexComponents()); + var fragment = new ShaderCompiler.Context(glslVersion, ShaderType.FRAGMENT, ctx.getFragmentComponents()); + + return new ProgramAssembler(ctx.instanceShader.getFileLoc()) + .attachShader(shaderCompiler.get(vertex)) + .attachShader(shaderCompiler.get(fragment)) + .link() + .build(ctx.contextShader.factory()); + } + + @Override + protected void _destroy(GlProgram value) { + value.delete(); + } + + public static void invalidateAll(ReloadRenderersEvent ignored) { + INSTANCE.invalidate(); + } + + /** + * Represents the entire context of a program's usage. + * + * @param vertexType The vertexType the program should be adapted for. + * @param material The material shader to use. + * @param instanceShader The instance shader to use. + * @param contextShader The context shader to use. + */ + public record Context(VertexType vertexType, Material material, FileResolution instanceShader, + ContextShader contextShader, PipelineShader pipelineShader) { + + ImmutableList getVertexComponents() { + return ImmutableList.of(vertexType.getLayoutShader().getFile(), instanceShader.getFile(), material.getVertexShader().getFile(), + contextShader.getVertexShader(), pipelineShader.vertex().getFile()); + } + + ImmutableList getFragmentComponents() { + return ImmutableList.of(material.getFragmentShader().getFile(), contextShader.getFragmentShader(), + pipelineShader.fragment().getFile()); + } + } + + /** + * Handles compilation and deletion of vertex shaders. + */ + public static class ShaderCompiler extends Memoizer { + + public ShaderCompiler() { + } + + @Override + protected GlShader _create(Context key) { + StringBuilder finalSource = new StringBuilder(); + + finalSource.append(key.generateHeader()); + finalSource.append("#extension GL_ARB_explicit_attrib_location : enable\n"); + finalSource.append("#extension GL_ARB_conservative_depth : enable\n"); + finalSource.append("#extension GL_ARB_enhanced_layouts : enable\n"); + + var ctx = new CompilationContext(); + + var names = ImmutableList.builder(); + for (var file : key.components) { + finalSource.append(file.generateFinalSource(ctx)); + names.add(file.name); + } + + try { + return new GlShader(finalSource.toString(), key.shaderType, names.build()); + } catch (ShaderCompilationException e) { + throw e.withErrorLog(ctx); + } + } + + @Override + protected void _destroy(GlShader value) { + value.delete(); + } + + /** + * @param glslVersion The GLSL version to use. + * @param components A list of shader components to stitch together, in order. + */ + public record Context(GLSLVersion glslVersion, ShaderType shaderType, List components) { + + public String generateHeader() { + return CompileUtil.generateHeader(glslVersion, shaderType); + } + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/ComputeCullerCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/ComputeCullerCompiler.java index 151fbcb03..5f664367b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/ComputeCullerCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/ComputeCullerCompiler.java @@ -5,6 +5,7 @@ import com.jozufozu.flywheel.backend.gl.GLSLVersion; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.GlShader; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.compile.CompileUtil; import com.jozufozu.flywheel.core.compile.Memoizer; import com.jozufozu.flywheel.core.compile.ProgramAssembler; @@ -23,14 +24,18 @@ public class ComputeCullerCompiler extends Memoizer { @Override protected GlProgram _create(FileResolution file) { + var finalSource = new StringBuilder(); CompilationContext context = new CompilationContext(); - var header = CompileUtil.generateHeader(GLSLVersion.V460, ShaderType.COMPUTE); - String source = file.getFile() - .generateFinalSource(context); + finalSource.append(CompileUtil.generateHeader(GLSLVersion.V460, ShaderType.COMPUTE)); + finalSource.append(file.getFile() + .generateFinalSource(context)); + + finalSource.append(Components.Pipeline.INDIRECT_CULL.getFile() + .generateFinalSource(context)); try { - var shader = new GlShader(header + source, ShaderType.COMPUTE, ImmutableList.of(file.getFileLoc())); + var shader = new GlShader(finalSource.toString(), ShaderType.COMPUTE, ImmutableList.of(file.getFileLoc())); return new ProgramAssembler(file.getFileLoc()).attachShader(shader) .link() diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectDrawCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectDrawCompiler.java deleted file mode 100644 index 80fc7bbc5..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectDrawCompiler.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing.indirect; - -import org.jetbrains.annotations.NotNull; - -import com.google.common.collect.ImmutableList; -import com.jozufozu.flywheel.backend.gl.GLSLVersion; -import com.jozufozu.flywheel.backend.gl.shader.GlProgram; -import com.jozufozu.flywheel.backend.gl.shader.GlShader; -import com.jozufozu.flywheel.backend.gl.shader.ShaderType; -import com.jozufozu.flywheel.core.WorldProgram; -import com.jozufozu.flywheel.core.compile.CompileUtil; -import com.jozufozu.flywheel.core.compile.Memoizer; -import com.jozufozu.flywheel.core.compile.ProgramAssembler; -import com.jozufozu.flywheel.core.compile.ShaderCompilationException; -import com.jozufozu.flywheel.core.source.CompilationContext; -import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.source.ShaderLoadingException; -import com.jozufozu.flywheel.core.source.SourceFile; -import com.jozufozu.flywheel.event.ReloadRenderersEvent; - -public class IndirectDrawCompiler extends Memoizer { - public static final IndirectDrawCompiler INSTANCE = new IndirectDrawCompiler(); - - private IndirectDrawCompiler() { - } - - @Override - protected GlProgram _create(IndirectDrawCompiler.Program program) { - - GlShader vertexShader = compile(program.vertex.getFile(), ShaderType.VERTEX); - GlShader fragmentShader = compile(program.fragment.getFile(), ShaderType.FRAGMENT); - - return new ProgramAssembler(program.vertex.getFileLoc()) - .attachShader(vertexShader) - .attachShader(fragmentShader) - .link() - .build(WorldProgram::new); - } - - @NotNull - private static GlShader compile(SourceFile file, ShaderType type) { - var context = new CompilationContext(); - try { - var header = CompileUtil.generateHeader(GLSLVersion.V460, type); - var source = file.generateFinalSource(context); - - return new GlShader(header + source, type, ImmutableList.of(file.name)); - } catch (ShaderCompilationException e) { - throw e.withErrorLog(context); - } - } - - @Override - protected void _destroy(GlProgram value) { - value.delete(); - } - - public static void invalidateAll(ReloadRenderersEvent ignored) { - INSTANCE.invalidate(); - } - - public record Program(FileResolution vertex, FileResolution fragment) { - - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java index a422428cc..c47c9c59d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java @@ -19,7 +19,7 @@ import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.core.RenderContext; import com.jozufozu.flywheel.api.context.ContextShader; -import com.jozufozu.flywheel.backend.instancing.instancing.InstancedArraysCompiler; +import com.jozufozu.flywheel.backend.instancing.PipelineCompiler; import com.jozufozu.flywheel.core.source.FileResolution; import com.jozufozu.flywheel.core.uniform.UniformBuffer; import com.jozufozu.flywheel.util.WeakHashSet; @@ -91,20 +91,6 @@ public class IndirectEngine implements Engine { RenderSystem.enableCull(); } - protected void setup(ShaderState desc) { - - VertexType vertexType = desc.vertex(); - FileResolution instanceShader = desc.instance() - .getInstanceShader(); - Material material = desc.material(); - - var ctx = new InstancedArraysCompiler.Context(vertexType, material, instanceShader, context); - - InstancedArraysCompiler.INSTANCE.getProgram(ctx) - .bind(); - UniformBuffer.getInstance().sync(); - } - public void clearAll() { factories.values().forEach(IndirectFactory::clear); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectList.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectList.java index fb5874298..c5b982471 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectList.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectList.java @@ -12,6 +12,7 @@ import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.struct.StorageBufferWriter; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; +import com.jozufozu.flywheel.backend.instancing.PipelineCompiler; import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.QuadConverter; @@ -21,7 +22,7 @@ import com.jozufozu.flywheel.core.vertex.Formats; public class IndirectList { - private static final long DRAW_COMMAND_STRIDE = 48; + private static final long DRAW_COMMAND_STRIDE = 36; private static final long DRAW_COMMAND_OFFSET = 0; final StorageBufferWriter storageBufferWriter; @@ -73,18 +74,20 @@ public class IndirectList { meshPool = new IndirectMeshPool(Formats.BLOCK, 1024); // FIXME: Resizable buffers - maxObjectCount = 1024L; + maxObjectCount = 64 * 64 * 64; maxBatchCount = 64; objectStride = storageBufferWriter.getAlignment(); - glNamedBufferStorage(objectBuffer, objectStride * maxObjectCount, GL_DYNAMIC_STORAGE_BIT); - glNamedBufferStorage(targetBuffer, 4 * maxObjectCount, GL_DYNAMIC_STORAGE_BIT); - glNamedBufferStorage(batchBuffer, 4 * maxObjectCount, GL_DYNAMIC_STORAGE_BIT); + int persistentBits = GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT; + glNamedBufferStorage(objectBuffer, objectStride * maxObjectCount, persistentBits); + glNamedBufferStorage(targetBuffer, 4 * maxObjectCount, 0); + glNamedBufferStorage(batchBuffer, 4 * maxObjectCount, persistentBits); glNamedBufferStorage(drawBuffer, DRAW_COMMAND_STRIDE * maxBatchCount, GL_DYNAMIC_STORAGE_BIT); - glNamedBufferStorage(debugBuffer, 4 * maxObjectCount, GL_DYNAMIC_STORAGE_BIT); + glNamedBufferStorage(debugBuffer, 4 * maxObjectCount, 0); - objectClientStorage = MemoryUtil.nmemAlloc(objectStride * maxObjectCount); - batchIDClientStorage = MemoryUtil.nmemAlloc(4 * maxObjectCount); + int mapBits = persistentBits | GL_MAP_FLUSH_EXPLICIT_BIT; + objectClientStorage = nglMapNamedBufferRange(objectBuffer, 0, objectStride * maxObjectCount, mapBits); + batchIDClientStorage = nglMapNamedBufferRange(batchBuffer, 0, 4 * maxObjectCount, mapBits); vertexArray = glCreateVertexArrays(); @@ -92,8 +95,8 @@ public class IndirectList { .quads2Tris(2048).buffer.handle(); setupVertexArray(); - compute = ComputeCullerCompiler.INSTANCE.get(Components.Files.CULL_INSTANCES); - draw = IndirectDrawCompiler.INSTANCE.get(new IndirectDrawCompiler.Program(Components.Files.DRAW_INDIRECT_VERTEX, Components.Files.DRAW_INDIRECT_FRAGMENT)); + compute = ComputeCullerCompiler.INSTANCE.get(Components.Files.ORIENTED_INDIRECT); + draw = PipelineCompiler.INSTANCE.get(new PipelineCompiler.Context(Formats.BLOCK, Materials.BELL, Components.Files.ORIENTED_INDIRECT, Components.WORLD, Components.INDIRECT)); } private void setupVertexArray() { @@ -184,8 +187,8 @@ public class IndirectList { batchID++; } - nglNamedBufferSubData(objectBuffer, 0, objectPtr - objectClientStorage, objectClientStorage); - nglNamedBufferSubData(batchBuffer, 0, batchIDPtr - batchIDClientStorage, batchIDClientStorage); + glFlushMappedNamedBufferRange(objectBuffer, 0, objectPtr - objectClientStorage); + glFlushMappedNamedBufferRange(batchBuffer, 0, batchIDPtr - batchIDClientStorage); } private void uploadIndirectCommands() { @@ -229,7 +232,7 @@ public class IndirectList { MemoryUtil.memPutInt(ptr + 12, mesh.getBaseVertex()); // baseVertex MemoryUtil.memPutInt(ptr + 16, baseInstance); // baseInstance - boundingSphere.getToAddress(ptr + 32); // boundingSphere + boundingSphere.getToAddress(ptr + 20); // boundingSphere } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedArraysCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedArraysCompiler.java deleted file mode 100644 index 4a4f92779..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedArraysCompiler.java +++ /dev/null @@ -1,252 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing.instancing; - -import java.util.ArrayList; - -import com.google.common.collect.ImmutableList; -import com.jozufozu.flywheel.api.context.ContextShader; -import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.api.vertex.VertexType; -import com.jozufozu.flywheel.backend.gl.GLSLVersion; -import com.jozufozu.flywheel.backend.gl.shader.GlProgram; -import com.jozufozu.flywheel.backend.gl.shader.GlShader; -import com.jozufozu.flywheel.backend.gl.shader.ShaderType; -import com.jozufozu.flywheel.core.compile.*; -import com.jozufozu.flywheel.core.source.CompilationContext; -import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.source.SourceFile; -import com.jozufozu.flywheel.core.source.parse.ShaderField; -import com.jozufozu.flywheel.core.source.span.Span; -import com.jozufozu.flywheel.event.ReloadRenderersEvent; -import com.jozufozu.flywheel.util.Pair; - -/** - * A caching compiler. - * - *

- * This class is responsible for compiling programs on the fly. An instance of this class will keep a cache of - * compiled programs, and will only compile a program if it is not already in the cache. - *

- *

- * A ProgramCompiler is also responsible for deleting programs and shaders on renderer reload. - *

- */ -public class InstancedArraysCompiler extends Memoizer { - - public static final InstancedArraysCompiler INSTANCE = new InstancedArraysCompiler(); - - private final VertexCompiler vertexCompiler; - private final FragmentCompiler fragmentCompiler; - - private InstancedArraysCompiler() { - this.vertexCompiler = new VertexCompiler(); - this.fragmentCompiler = new FragmentCompiler(); - } - - /** - * Get or compile a spec to the given vertex type, accounting for all game state conditions specified by the spec. - * - * @param ctx The context of compilation. - * @return A compiled GlProgram. - */ - public GlProgram getProgram(InstancedArraysCompiler.Context ctx) { - return super.get(ctx); - } - - @Override - public void invalidate() { - super.invalidate(); - vertexCompiler.invalidate(); - fragmentCompiler.invalidate(); - } - - @Override - protected GlProgram _create(InstancedArraysCompiler.Context ctx) { - // TODO: try-catch here to prevent crashing if shaders failed to compile - Material material = ctx.material; - FileResolution instanceShader = ctx.instanceShader(); - ContextShader contextShader = ctx.contextShader; - - var vertex = new VertexCompiler.Context(ctx.vertexType(), instanceShader.getFile(), material.getVertexShader().getFile(), - contextShader.getVertexShader()); - - var fragment = new FragmentCompiler.Context(material.getFragmentShader().getFile(), contextShader.getFragmentShader()); - - return new ProgramAssembler(instanceShader.getFileLoc()) - .attachShader(vertexCompiler.get(vertex)) - .attachShader(fragmentCompiler.get(fragment)) - .link() - .build(contextShader.factory()); - } - - @Override - protected void _destroy(GlProgram value) { - value.delete(); - } - - public static void invalidateAll(ReloadRenderersEvent ignored) { - INSTANCE.invalidate(); - } - - /** - * Represents the entire context of a program's usage. - * - * @param vertexType The vertexType the program should be adapted for. - * @param material The material shader to use. - * @param instanceShader The instance shader to use. - * @param contextShader The context shader to use. - */ - public record Context(VertexType vertexType, Material material, FileResolution instanceShader, - ContextShader contextShader) { - } - - /** - * Handles compilation and deletion of vertex shaders. - */ - public static class VertexCompiler extends Memoizer { - - public VertexCompiler() { - } - - @Override - protected GlShader _create(Context key) { - StringBuilder finalSource = new StringBuilder(); - - finalSource.append(CompileUtil.generateHeader(GLSLVersion.V420, ShaderType.VERTEX)); - finalSource.append("#extension GL_ARB_explicit_attrib_location : enable\n"); - - var index = new CompilationContext(); - - // LAYOUT - - var layoutShader = key.vertexType.getLayoutShader().getFile(); - finalSource.append(layoutShader.generateFinalSource(index)); - - // INSTANCE - - int attributeBaseIndex = key.vertexType.getLayout() - .getAttributeCount(); - - var instanceShader = key.instanceShader; - var replacements = new ArrayList>(); - for (ShaderField field : instanceShader.fields.values()) { - if (field.decoration != ShaderField.Decoration.IN) { - continue; - } - - int location = Integer.parseInt(field.location.get()); - int newLocation = location + attributeBaseIndex; - replacements.add(Pair.of(field.location, Integer.toString(newLocation))); - } - finalSource.append(instanceShader.generateFinalSource(index, replacements)); - - // MATERIAL - - var materialShader = key.materialShader; - finalSource.append(materialShader.generateFinalSource(index)); - - // CONTEXT - - var contextShaderSource = key.contextShader; - finalSource.append(contextShaderSource.generateFinalSource(index)); - - // MAIN - - finalSource.append(""" - void main() { - flw_layoutVertex(); - - flw_instanceVertex(); - - flw_materialVertex(); - - flw_contextVertex(); - } - """); - - try { - return new GlShader(finalSource.toString(), ShaderType.VERTEX, ImmutableList.of(layoutShader.name, instanceShader.name, materialShader.name, contextShaderSource.name)); - } catch (ShaderCompilationException e) { - throw e.withErrorLog(index); - } - } - - @Override - protected void _destroy(GlShader value) { - value.delete(); - } - - /** - * @param vertexType The vertex type to use. - * @param instanceShader The instance shader source. - * @param materialShader The vertex material shader source. - * @param contextShader The context shader source. - */ - public record Context(VertexType vertexType, SourceFile instanceShader, SourceFile materialShader, SourceFile contextShader) { - } - } - - /** - * Handles compilation and deletion of fragment shaders. - */ - public static class FragmentCompiler extends Memoizer { - - public FragmentCompiler() { - } - - @Override - protected GlShader _create(Context key) { - StringBuilder finalSource = new StringBuilder(); - - finalSource.append(CompileUtil.generateHeader(GLSLVersion.V420, ShaderType.FRAGMENT)); - finalSource.append("#extension GL_ARB_conservative_depth : enable\n"); - - var ctx = new CompilationContext(); - - // MATERIAL - - SourceFile materialShader = key.materialShader; - finalSource.append(materialShader.generateFinalSource(ctx)); - - // CONTEXT - - SourceFile contextShaderSource = key.contextShader; - finalSource.append(contextShaderSource.generateFinalSource(ctx)); - - // MAIN - - finalSource.append(generateFooter()); - - try { - return new GlShader(finalSource.toString(), ShaderType.FRAGMENT, ImmutableList.of(materialShader.name, contextShaderSource.name)); - } catch (ShaderCompilationException e) { - throw e.withErrorLog(ctx); - } - } - - protected String generateFooter() { - return """ - void main() { - flw_initFragment(); - - flw_materialFragment(); - - flw_contextFragment(); - } - """; - } - - @Override - protected void _destroy(GlShader value) { - value.delete(); - } - - /** - * Represents the conditions under which a shader is compiled. - * - * @param materialShader The fragment material shader source. - */ - public record Context(SourceFile materialShader, SourceFile contextShader) { - - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index e8d21a692..5685795fa 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -17,7 +17,9 @@ import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.gl.GlTextureUnit; import com.jozufozu.flywheel.backend.instancing.Engine; import com.jozufozu.flywheel.backend.instancing.InstanceManager; +import com.jozufozu.flywheel.backend.instancing.PipelineCompiler; import com.jozufozu.flywheel.backend.instancing.TaskEngine; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.RenderContext; import com.jozufozu.flywheel.api.context.ContextShader; import com.jozufozu.flywheel.core.source.FileResolution; @@ -136,9 +138,9 @@ public class InstancingEngine implements Engine { .getInstanceShader(); Material material = desc.material(); - var ctx = new InstancedArraysCompiler.Context(vertexType, material, instanceShader, context); + var ctx = new PipelineCompiler.Context(vertexType, material, instanceShader, context, Components.INSTANCED_ARRAYS); - InstancedArraysCompiler.INSTANCE.getProgram(ctx) + PipelineCompiler.INSTANCE.getProgram(ctx) .bind(); UniformBuffer.getInstance().sync(); } diff --git a/src/main/java/com/jozufozu/flywheel/core/Components.java b/src/main/java/com/jozufozu/flywheel/core/Components.java index b031bea83..ab85c20d4 100644 --- a/src/main/java/com/jozufozu/flywheel/core/Components.java +++ b/src/main/java/com/jozufozu/flywheel/core/Components.java @@ -4,6 +4,8 @@ import java.util.function.BiConsumer; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.context.ContextShader; +import com.jozufozu.flywheel.api.pipeline.PipelineShader; +import com.jozufozu.flywheel.backend.gl.GLSLVersion; import com.jozufozu.flywheel.core.crumbling.CrumblingProgram; import com.jozufozu.flywheel.core.source.FileResolution; import com.jozufozu.flywheel.core.source.SourceChecks; @@ -27,6 +29,9 @@ public class Components { public static final ContextShader WORLD = ComponentRegistry.register(new ContextShader(WorldProgram::new, Files.WORLD_VERTEX, Files.WORLD_FRAGMENT)); public static final ContextShader CRUMBLING = ComponentRegistry.register(new ContextShader(CrumblingProgram::new, Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT)); + public static final PipelineShader INSTANCED_ARRAYS = new PipelineShader(GLSLVersion.V420, Pipeline.INSTANCED_ARRAYS_DRAW, Pipeline.DRAW_FRAGMENT); + public static final PipelineShader INDIRECT = new PipelineShader(GLSLVersion.V460, Pipeline.INDIRECT_DRAW, Pipeline.DRAW_FRAGMENT); + public static void init() { Files.init(); Formats.init(); @@ -34,6 +39,18 @@ public class Components { Materials.init(); } + public static class Pipeline { + public static final FileResolution DRAW_FRAGMENT = pipeline("pipeline/draw.frag"); + public static final FileResolution INSTANCED_ARRAYS_DRAW = pipeline("pipeline/instanced_arrays_draw.vert"); + public static final FileResolution INDIRECT_DRAW = pipeline("pipeline/indirect_draw.vert"); + public static final FileResolution INDIRECT_CULL = pipeline("pipeline/indirect_cull.glsl"); + + private static FileResolution pipeline(String name) { + return FileResolution.get(Flywheel.rl(name)) + .validateWith(Checks.PIPELINE); + } + } + public static class Files { public static final FileResolution VIEW_UNIFORMS = uniform(Flywheel.rl("uniform/view.glsl")); @@ -42,7 +59,9 @@ public class Components { public static final FileResolution BLOCK_LAYOUT = layoutVertex(ResourceUtil.subPath(Names.BLOCK, ".vert")); public static final FileResolution POS_TEX_NORMAL_LAYOUT = layoutVertex(ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert")); public static final FileResolution TRANSFORMED = instanceVertex(ResourceUtil.subPath(Names.TRANSFORMED, ".vert")); + public static final FileResolution TRANSFORMED_INDIRECT = instanceVertex(ResourceUtil.subPath(Names.TRANSFORMED, "_indirect.glsl")); public static final FileResolution ORIENTED = instanceVertex(ResourceUtil.subPath(Names.ORIENTED, ".vert")); + public static final FileResolution ORIENTED_INDIRECT = instanceVertex(ResourceUtil.subPath(Names.ORIENTED, "_indirect.glsl")); public static final FileResolution DEFAULT_VERTEX = materialVertex(ResourceUtil.subPath(Names.DEFAULT, ".vert")); public static final FileResolution SHADED_VERTEX = materialVertex(ResourceUtil.subPath(Names.SHADED, ".vert")); public static final FileResolution DEFAULT_FRAGMENT = materialFragment(ResourceUtil.subPath(Names.DEFAULT, ".frag")); @@ -51,9 +70,6 @@ public class Components { public static final FileResolution WORLD_FRAGMENT = contextFragment(ResourceUtil.subPath(Names.WORLD, ".frag")); public static final FileResolution CRUMBLING_VERTEX = contextVertex(ResourceUtil.subPath(Names.CRUMBLING, ".vert")); public static final FileResolution CRUMBLING_FRAGMENT = contextFragment(ResourceUtil.subPath(Names.CRUMBLING, ".frag")); - public static final FileResolution CULL_INSTANCES = compute(Flywheel.rl("compute/cull_instances.glsl")); - public static final FileResolution DRAW_INDIRECT_VERTEX = FileResolution.get(ResourceUtil.subPath(Names.DRAW_INDIRECT, ".vert")); - public static final FileResolution DRAW_INDIRECT_FRAGMENT = FileResolution.get(ResourceUtil.subPath(Names.DRAW_INDIRECT, ".frag")); private static FileResolution compute(ResourceLocation rl) { return FileResolution.get(rl); @@ -69,8 +85,7 @@ public class Components { } private static FileResolution instanceVertex(ResourceLocation location) { - return FileResolution.get(location) - .validateWith(Checks.INSTANCE_VERTEX); + return FileResolution.get(location); // .validateWith(Checks.INSTANCE_VERTEX); } private static FileResolution materialVertex(ResourceLocation location) { @@ -100,12 +115,16 @@ public class Components { public static class Checks { - public static final BiConsumer LAYOUT_VERTEX = SourceChecks.checkFunctionArity("flw_layoutVertex", 0); - public static final BiConsumer INSTANCE_VERTEX = SourceChecks.checkFunctionArity("flw_instanceVertex", 0); + public static final BiConsumer LAYOUT_VERTEX = SourceChecks.checkFunctionArity("flw_layoutVertex", 0) + .andThen(SourceChecks.checkDefine("FLW_INSTANCE_BASE_INDEX")); + public static final BiConsumer INSTANCE_VERTEX = SourceChecks.checkFunctionParameterTypeExists("flw_instanceVertex", 1, 0) + .andThen(SourceChecks.checkDefine("FLW_INSTANCE_STRUCT")); public static final BiConsumer MATERIAL_VERTEX = SourceChecks.checkFunctionArity("flw_materialVertex", 0); public static final BiConsumer MATERIAL_FRAGMENT = SourceChecks.checkFunctionArity("flw_materialFragment", 0); public static final BiConsumer CONTEXT_VERTEX = SourceChecks.checkFunctionArity("flw_contextVertex", 0); public static final BiConsumer CONTEXT_FRAGMENT = SourceChecks.checkFunctionArity("flw_contextFragment", 0).andThen(SourceChecks.checkFunctionArity("flw_initFragment", 0)); + + public static final BiConsumer PIPELINE = SourceChecks.checkFunctionArity("main", 0); } public static class Names { diff --git a/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java b/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java index 8d704ab55..ea4ca0d43 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java @@ -162,4 +162,25 @@ public class FileResolution { public String toString() { return "FileResolution[" + fileLoc + "]"; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + FileResolution that = (FileResolution) o; + + return fileLoc.equals(that.fileLoc); + } + + @Override + public int hashCode() { + // FileResolutions are interned and therefore can be hashed based on object identity. + // Overriding this to make it explicit. + return System.identityHashCode(this); + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/source/SourceChecks.java b/src/main/java/com/jozufozu/flywheel/core/source/SourceChecks.java index a8247a33e..1d4023705 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/SourceChecks.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/SourceChecks.java @@ -54,4 +54,12 @@ public class SourceChecks { return func; } + + public static BiConsumer checkDefine(String define) { + return (errorReporter, file) -> { +// if (!file.hasDefine(define)) { +// errorReporter.generateMissingDefine(file, define, "\"" + define + "\" define not defined"); +// } + }; + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java index 2f799677b..faeb46acb 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java @@ -185,10 +185,7 @@ public class SourceFile { } public String generateFinalSource(CompilationContext context) { - return generateFinalSource(context, Collections.emptyList()); - } - - public String generateFinalSource(CompilationContext context, List> replacements) { + List> replacements = Collections.emptyList(); var out = new StringBuilder(); for (Import include : flattenedImports) { SourceFile file = include.getFile(); diff --git a/src/main/resources/assets/flywheel/flywheel/instance/oriented.vert b/src/main/resources/assets/flywheel/flywheel/instance/oriented.vert index 93a50ddee..880d55de4 100644 --- a/src/main/resources/assets/flywheel/flywheel/instance/oriented.vert +++ b/src/main/resources/assets/flywheel/flywheel/instance/oriented.vert @@ -1,11 +1,11 @@ #use "flywheel:api/vertex.glsl" #use "flywheel:util/quaternion.glsl" -layout(location = 0) in ivec2 oriented_light; -layout(location = 1) in vec4 oriented_color; -layout(location = 2) in vec3 oriented_pos; -layout(location = 3) in vec3 oriented_pivot; -layout(location = 4) in vec4 oriented_rotation; +layout(location = FLW_INSTANCE_BASE_INDEX + 0) in ivec2 oriented_light; +layout(location = FLW_INSTANCE_BASE_INDEX + 1) in vec4 oriented_color; +layout(location = FLW_INSTANCE_BASE_INDEX + 2) in vec3 oriented_pos; +layout(location = FLW_INSTANCE_BASE_INDEX + 3) in vec3 oriented_pivot; +layout(location = FLW_INSTANCE_BASE_INDEX + 4) in vec4 oriented_rotation; void flw_instanceVertex() { flw_vertexPos = vec4(rotateVertexByQuat(flw_vertexPos.xyz - oriented_pivot, oriented_rotation) + oriented_pivot + oriented_pos, 1.0); diff --git a/src/main/resources/assets/flywheel/flywheel/instance/oriented_indirect.glsl b/src/main/resources/assets/flywheel/flywheel/instance/oriented_indirect.glsl index c02c57bfc..fbf76667c 100644 --- a/src/main/resources/assets/flywheel/flywheel/instance/oriented_indirect.glsl +++ b/src/main/resources/assets/flywheel/flywheel/instance/oriented_indirect.glsl @@ -1,7 +1,7 @@ #use "flywheel:api/vertex.glsl" #use "flywheel:util/quaternion.glsl" -#define FLW_INSTANCE_STRUCT Instance +#define FLW_INSTANCE_STRUCT Instance struct Instance { vec4 rotation; vec3 pos; diff --git a/src/main/resources/assets/flywheel/flywheel/instance/transformed.vert b/src/main/resources/assets/flywheel/flywheel/instance/transformed.vert index e2ea23ef4..2c6161d18 100644 --- a/src/main/resources/assets/flywheel/flywheel/instance/transformed.vert +++ b/src/main/resources/assets/flywheel/flywheel/instance/transformed.vert @@ -1,9 +1,9 @@ #use "flywheel:api/vertex.glsl" -layout(location = 0) in ivec2 transformed_light; -layout(location = 1) in vec4 transformed_color; -layout(location = 2) in mat4 transformed_pose; -layout(location = 6) in mat3 transformed_normal; +layout(location = FLW_INSTANCE_BASE_INDEX + 0) in ivec2 transformed_light; +layout(location = FLW_INSTANCE_BASE_INDEX + 1) in vec4 transformed_color; +layout(location = FLW_INSTANCE_BASE_INDEX + 2) in mat4 transformed_pose; +layout(location = FLW_INSTANCE_BASE_INDEX + 6) in mat3 transformed_normal; void flw_instanceVertex() { flw_vertexPos = transformed_pose * flw_vertexPos; diff --git a/src/main/resources/assets/flywheel/flywheel/layout/block.vert b/src/main/resources/assets/flywheel/flywheel/layout/block.vert index a3af3b16d..4123724aa 100644 --- a/src/main/resources/assets/flywheel/flywheel/layout/block.vert +++ b/src/main/resources/assets/flywheel/flywheel/layout/block.vert @@ -5,6 +5,7 @@ layout(location = 1) in vec4 _flw_v_color; layout(location = 2) in vec2 _flw_v_texCoord; layout(location = 3) in ivec2 _flw_v_light; layout(location = 4) in vec3 _flw_v_normal; +#define FLW_INSTANCE_BASE_INDEX 5 void flw_layoutVertex() { flw_vertexPos = vec4(_flw_v_pos, 1.0); diff --git a/src/main/resources/assets/flywheel/flywheel/layout/pos_tex_normal.vert b/src/main/resources/assets/flywheel/flywheel/layout/pos_tex_normal.vert index 4ecfb2c3c..80b02f8bc 100644 --- a/src/main/resources/assets/flywheel/flywheel/layout/pos_tex_normal.vert +++ b/src/main/resources/assets/flywheel/flywheel/layout/pos_tex_normal.vert @@ -3,6 +3,7 @@ layout(location = 0) in vec3 _flw_v_pos; layout(location = 1) in vec2 _flw_v_texCoord; layout(location = 2) in vec3 _flw_v_normal; +#define FLW_INSTANCE_BASE_INDEX 3 void flw_layoutVertex() { flw_vertexPos = vec4(_flw_v_pos, 1.0); diff --git a/src/main/resources/assets/flywheel/flywheel/compute/draw_instances.frag b/src/main/resources/assets/flywheel/flywheel/pipeline/draw.frag similarity index 64% rename from src/main/resources/assets/flywheel/flywheel/compute/draw_instances.frag rename to src/main/resources/assets/flywheel/flywheel/pipeline/draw.frag index 6591bea51..f57dd9a87 100644 --- a/src/main/resources/assets/flywheel/flywheel/compute/draw_instances.frag +++ b/src/main/resources/assets/flywheel/flywheel/pipeline/draw.frag @@ -1,6 +1,4 @@ #use "flywheel:api/fragment.glsl" -#use "flywheel:context/world.frag" -#use "flywheel:material/default.frag" void main() { flw_initFragment(); diff --git a/src/main/resources/assets/flywheel/flywheel/compute/cull_instances.glsl b/src/main/resources/assets/flywheel/flywheel/pipeline/indirect_cull.glsl similarity index 90% rename from src/main/resources/assets/flywheel/flywheel/compute/cull_instances.glsl rename to src/main/resources/assets/flywheel/flywheel/pipeline/indirect_cull.glsl index 705b379c2..170df512a 100644 --- a/src/main/resources/assets/flywheel/flywheel/compute/cull_instances.glsl +++ b/src/main/resources/assets/flywheel/flywheel/pipeline/indirect_cull.glsl @@ -1,9 +1,8 @@ #define FLW_SUBGROUP_SIZE 32 layout(local_size_x = FLW_SUBGROUP_SIZE) in; #use "flywheel:api/cull.glsl" -#use "flywheel:util/quaternion.glsl" #use "flywheel:uniform/frustum.glsl" -#use "flywheel:instance/oriented_indirect.glsl" +#use "flywheel:util/types.glsl" struct MeshDrawCommand { uint indexCount; @@ -12,7 +11,7 @@ struct MeshDrawCommand { uint vertexOffset; uint baseInstance; - vec4 boundingSphere; + BoundingSphere boundingSphere; }; // populated by instancers @@ -54,10 +53,11 @@ bool testSphere(vec3 center, float radius) { } bool isVisible() { - vec4 sphere = drawCommands[flw_batchID].boundingSphere; + BoundingSphere sphere = drawCommands[flw_batchID].boundingSphere; - vec3 center = sphere.xyz; - float radius = sphere.r; + vec3 center; + float radius; + unpackBoundingSphere(sphere, center, radius); flw_transformBoundingSphere(objects[flw_objectID], center, radius); return testSphere(center, radius); diff --git a/src/main/resources/assets/flywheel/flywheel/compute/draw_instances.vert b/src/main/resources/assets/flywheel/flywheel/pipeline/indirect_draw.vert similarity index 64% rename from src/main/resources/assets/flywheel/flywheel/compute/draw_instances.vert rename to src/main/resources/assets/flywheel/flywheel/pipeline/indirect_draw.vert index 66fea9dae..7583ebbd6 100644 --- a/src/main/resources/assets/flywheel/flywheel/compute/draw_instances.vert +++ b/src/main/resources/assets/flywheel/flywheel/pipeline/indirect_draw.vert @@ -1,10 +1,5 @@ #use "flywheel:api/vertex.glsl" -#use "flywheel:layout/block.vert" -#use "flywheel:context/world.vert" -#use "flywheel:util/quaternion.glsl" -#use "flywheel:instance/oriented_indirect.glsl" -// populated by instancers layout(std430, binding = 0) restrict readonly buffer ObjectBuffer { FLW_INSTANCE_STRUCT objects[]; }; @@ -16,7 +11,8 @@ layout(std430, binding = 1) restrict readonly buffer TargetBuffer { void main() { uint instanceIndex = objectIDs[gl_BaseInstance + gl_InstanceID]; flw_layoutVertex(); - Instance i = objects[instanceIndex]; + FLW_INSTANCE_STRUCT i = objects[instanceIndex]; flw_instanceVertex(i); + flw_materialVertex(); flw_contextVertex(); } diff --git a/src/main/resources/assets/flywheel/flywheel/pipeline/instanced_arrays_draw.vert b/src/main/resources/assets/flywheel/flywheel/pipeline/instanced_arrays_draw.vert new file mode 100644 index 000000000..0b75edde3 --- /dev/null +++ b/src/main/resources/assets/flywheel/flywheel/pipeline/instanced_arrays_draw.vert @@ -0,0 +1,8 @@ +#use "flywheel:api/vertex.glsl" + +void main() { + flw_layoutVertex(); + flw_instanceVertex(); + flw_materialVertex(); + flw_contextVertex(); +} diff --git a/src/main/resources/assets/flywheel/flywheel/util/types.glsl b/src/main/resources/assets/flywheel/flywheel/util/types.glsl new file mode 100644 index 000000000..a6f58174b --- /dev/null +++ b/src/main/resources/assets/flywheel/flywheel/util/types.glsl @@ -0,0 +1,17 @@ + +struct Vec3F { + float x; + float y; + float z; +}; + +// 4-aligned instead of a 16-aligned vec4 +struct BoundingSphere { + Vec3F center; + float radius; +}; + +void unpackBoundingSphere(in BoundingSphere sphere, out vec3 center, out float radius) { + center = vec3(sphere.center.x, sphere.center.y, sphere.center.z); + radius = sphere.radius; +}