Blocks all the way down

- Instancing and indirect backends use the block format internally.
- Remove layout shaders.
- Do not compile against VertexType.
- Do not sort draw calls by VertexType.
- Remove VertexType#REGISTRY.
This commit is contained in:
Jozufozu 2023-12-03 16:27:18 -08:00
parent 473e5e852f
commit 0e5617219b
25 changed files with 59 additions and 139 deletions

View file

@ -28,8 +28,7 @@ public interface Mesh {
* The size in bytes that this mesh's data takes up. * The size in bytes that this mesh's data takes up.
*/ */
default int size() { default int size() {
return vertexType().getLayout() return vertexType().getStride() * vertexCount();
.getStride() * vertexCount();
} }
/** /**

View file

@ -1,24 +1,16 @@
package com.jozufozu.flywheel.api.vertex; package com.jozufozu.flywheel.api.vertex;
import com.jozufozu.flywheel.api.layout.BufferLayout; import com.jozufozu.flywheel.api.layout.BufferLayout;
import com.jozufozu.flywheel.api.registry.Registry;
import com.jozufozu.flywheel.impl.RegistryImpl;
import net.minecraft.resources.ResourceLocation;
/** /**
* A vertex type containing metadata about a specific vertex layout. * A vertex type containing metadata about a specific vertex layout.
*/ */
public interface VertexType extends VertexListProvider { public interface VertexType extends VertexListProvider {
static Registry<VertexType> REGISTRY = RegistryImpl.create();
/** /**
* The layout of this type of vertex when buffered. * The layout of this type of vertex when buffered.
*/ */
BufferLayout getLayout(); BufferLayout getLayout();
ResourceLocation layoutShader();
default int getStride() { default int getStride() {
return getLayout().getStride(); return getLayout().getStride();
} }

View file

@ -7,7 +7,6 @@ import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.uniform.ShaderUniforms; import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.ShaderIndices; import com.jozufozu.flywheel.backend.ShaderIndices;
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent; import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
@ -99,12 +98,9 @@ public class FlwPrograms {
private static ImmutableList<PipelineProgramKey> createPipelineKeys() { private static ImmutableList<PipelineProgramKey> createPipelineKeys() {
ImmutableList.Builder<PipelineProgramKey> builder = ImmutableList.builder(); ImmutableList.Builder<PipelineProgramKey> builder = ImmutableList.builder();
// TODO: ubershader'd contexts?
for (Context context : Context.REGISTRY) { for (Context context : Context.REGISTRY) {
for (InstanceType<?> instanceType : InstanceType.REGISTRY) { for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
for (VertexType vertexType : VertexType.REGISTRY) { builder.add(new PipelineProgramKey(instanceType, context));
builder.add(new PipelineProgramKey(vertexType, instanceType, context));
}
} }
} }
return builder.build(); return builder.build();

View file

@ -9,7 +9,6 @@ import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent; import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.gl.GlCompat; import com.jozufozu.flywheel.gl.GlCompat;
@ -89,8 +88,8 @@ public class IndirectPrograms {
.build(); .build();
} }
public GlProgram getIndirectProgram(VertexType vertexType, InstanceType<?> instanceType, Context contextShader) { public GlProgram getIndirectProgram(InstanceType<?> instanceType, Context contextShader) {
return pipeline.get(new PipelineProgramKey(vertexType, instanceType, contextShader)); return pipeline.get(new PipelineProgramKey(instanceType, contextShader));
} }
public GlProgram getCullingProgram(InstanceType<?> instanceType) { public GlProgram getCullingProgram(InstanceType<?> instanceType) {

View file

@ -9,7 +9,6 @@ import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.gl.shader.GlProgram; import com.jozufozu.flywheel.gl.shader.GlProgram;
import com.jozufozu.flywheel.glsl.ShaderSources; import com.jozufozu.flywheel.glsl.ShaderSources;
@ -55,8 +54,8 @@ public class InstancingPrograms {
} }
} }
public GlProgram get(VertexType vertexType, InstanceType<?> instanceType, Context contextShader) { public GlProgram get(InstanceType<?> instanceType, Context contextShader) {
return pipeline.get(new PipelineProgramKey(vertexType, instanceType, contextShader)); return pipeline.get(new PipelineProgramKey(instanceType, contextShader));
} }
public void delete() { public void delete() {

View file

@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.compile;
import java.util.Objects; import java.util.Objects;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.glsl.GLSLVersion; import com.jozufozu.flywheel.glsl.GLSLVersion;
import com.jozufozu.flywheel.glsl.SourceComponent; import com.jozufozu.flywheel.glsl.SourceComponent;
@ -21,7 +20,7 @@ public record Pipeline(GLSLVersion glslVersion, ResourceLocation vertexShader, R
SourceComponent assemble(InstanceAssemblerContext context); SourceComponent assemble(InstanceAssemblerContext context);
} }
public record InstanceAssemblerContext(VertexType vertexType, InstanceType<?> instanceType) { public record InstanceAssemblerContext(int baseAttribute, InstanceType<?> instanceType) {
} }
public static Builder builder() { public static Builder builder() {

View file

@ -7,6 +7,7 @@ import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.gl.shader.ShaderType; import com.jozufozu.flywheel.gl.shader.ShaderType;
import com.jozufozu.flywheel.glsl.ShaderSources; import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.SourceComponent; import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.lib.vertex.BlockVertex;
public class PipelineCompiler { public class PipelineCompiler {
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>(); private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
@ -18,11 +19,9 @@ public class PipelineCompiler {
.link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.VERTEX) .link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.VERTEX)
.withComponent(uniformComponent) .withComponent(uniformComponent)
.withComponent(key -> pipeline.assembler() .withComponent(key -> pipeline.assembler()
.assemble(new Pipeline.InstanceAssemblerContext(key.vertexType(), key.instanceType()))) .assemble(new Pipeline.InstanceAssemblerContext(BlockVertex.FORMAT.getAttributeCount(), key.instanceType())))
.withResource(pipeline.vertexAPI()) .withResource(pipeline.vertexAPI())
.withComponents(vertexComponents) .withComponents(vertexComponents)
.withResource(key -> key.vertexType()
.layoutShader())
.withResource(key -> key.instanceType() .withResource(key -> key.instanceType()
.instanceShader()) .instanceShader())
.withResource(key -> key.contextShader() .withResource(key -> key.contextShader()

View file

@ -2,14 +2,12 @@ package com.jozufozu.flywheel.backend.compile;
import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType;
/** /**
* Represents the entire context of a program's usage. * Represents the entire context of a program's usage.
* *
* @param vertexType The vertex type the program should be adapted for.
* @param instanceType The instance shader to use. * @param instanceType The instance shader to use.
* @param contextShader The context shader to use. * @param contextShader The context shader to use.
*/ */
public record PipelineProgramKey(VertexType vertexType, InstanceType<?> instanceType, Context contextShader) { public record PipelineProgramKey(InstanceType<?> instanceType, Context contextShader) {
} }

View file

@ -26,9 +26,7 @@ public class InstancedArraysComponent implements SourceComponent {
public InstancedArraysComponent(Pipeline.InstanceAssemblerContext ctx) { public InstancedArraysComponent(Pipeline.InstanceAssemblerContext ctx) {
this.layoutItems = ctx.instanceType() this.layoutItems = ctx.instanceType()
.getLayout().layoutItems; .getLayout().layoutItems;
this.baseIndex = ctx.vertexType() this.baseIndex = ctx.baseAttribute();
.getLayout()
.getAttributeCount();
} }
@Override @Override

View file

@ -10,7 +10,6 @@ import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.model.Mesh; import com.jozufozu.flywheel.api.model.Mesh;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.compile.IndirectPrograms; import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
import com.jozufozu.flywheel.backend.engine.UniformBuffer; import com.jozufozu.flywheel.backend.engine.UniformBuffer;
import com.jozufozu.flywheel.gl.shader.GlProgram; import com.jozufozu.flywheel.gl.shader.GlProgram;
@ -29,7 +28,7 @@ public class IndirectCullingGroup<I extends Instance> {
private boolean needsMemoryBarrier; private boolean needsMemoryBarrier;
private int instanceCountThisFrame; private int instanceCountThisFrame;
IndirectCullingGroup(InstanceType<I> instanceType, VertexType vertexType) { IndirectCullingGroup(InstanceType<I> instanceType) {
objectStride = instanceType.getLayout() objectStride = instanceType.getLayout()
.getStride() + IndirectBuffers.INT_SIZE; .getStride() + IndirectBuffers.INT_SIZE;
@ -38,11 +37,11 @@ public class IndirectCullingGroup<I extends Instance> {
buffers.createObjectStorage(128); buffers.createObjectStorage(128);
buffers.createDrawStorage(2); buffers.createDrawStorage(2);
meshPool = new IndirectMeshPool(vertexType); meshPool = new IndirectMeshPool();
var indirectPrograms = IndirectPrograms.get(); var indirectPrograms = IndirectPrograms.get();
compute = indirectPrograms.getCullingProgram(instanceType); compute = indirectPrograms.getCullingProgram(instanceType);
draw = indirectPrograms.getIndirectProgram(vertexType, instanceType, Contexts.WORLD); draw = indirectPrograms.getIndirectProgram(instanceType, Contexts.WORLD);
} }
public void add(IndirectInstancer<I> instancer, RenderStage stage, Material material, Mesh mesh) { public void add(IndirectInstancer<I> instancer, RenderStage stage, Material material, Mesh mesh) {

View file

@ -7,13 +7,11 @@ import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.engine.InstancerKey; import com.jozufozu.flywheel.backend.engine.InstancerKey;
import com.jozufozu.flywheel.backend.engine.InstancerStorage; import com.jozufozu.flywheel.backend.engine.InstancerStorage;
import com.jozufozu.flywheel.lib.util.Pair;
public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>> { public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>> {
public final Map<Pair<InstanceType<?>, VertexType>, IndirectCullingGroup<?>> renderLists = new HashMap<>(); public final Map<InstanceType<?>, IndirectCullingGroup<?>> renderLists = new HashMap<>();
@Override @Override
protected <I extends Instance> IndirectInstancer<?> create(InstanceType<I> type) { protected <I extends Instance> IndirectInstancer<?> create(InstanceType<I> type) {
@ -27,7 +25,7 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
var material = entry.getKey(); var material = entry.getKey();
var mesh = entry.getValue(); var mesh = entry.getValue();
var indirectList = (IndirectCullingGroup<I>) renderLists.computeIfAbsent(Pair.of(key.type(), mesh.vertexType()), p -> new IndirectCullingGroup<>(p.first(), p.second())); var indirectList = (IndirectCullingGroup<I>) renderLists.computeIfAbsent(key.type(), IndirectCullingGroup::new);
indirectList.add((IndirectInstancer<I>) instancer, stage, material, mesh); indirectList.add((IndirectInstancer<I>) instancer, stage, material, mesh);

View file

@ -16,9 +16,11 @@ import com.jozufozu.flywheel.gl.array.GlVertexArray;
import com.jozufozu.flywheel.gl.buffer.GlBuffer; import com.jozufozu.flywheel.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.lib.memory.MemoryBlock; import com.jozufozu.flywheel.lib.memory.MemoryBlock;
import com.jozufozu.flywheel.lib.model.QuadIndexSequence; import com.jozufozu.flywheel.lib.model.QuadIndexSequence;
import com.jozufozu.flywheel.lib.vertex.BlockVertexList;
import com.jozufozu.flywheel.lib.vertex.VertexTypes;
public class IndirectMeshPool { public class IndirectMeshPool {
private final VertexType vertexType; private static final VertexType VERTEX_TYPE = VertexTypes.BLOCK;
private final Map<Mesh, BufferedMesh> meshes = new HashMap<>(); private final Map<Mesh, BufferedMesh> meshes = new HashMap<>();
private final List<BufferedMesh> meshList = new ArrayList<>(); private final List<BufferedMesh> meshList = new ArrayList<>();
@ -32,20 +34,19 @@ public class IndirectMeshPool {
/** /**
* Create a new mesh pool. * Create a new mesh pool.
*/ */
public IndirectMeshPool(VertexType type) { public IndirectMeshPool() {
vertexType = type;
vbo = new GlBuffer(); vbo = new GlBuffer();
ebo = new GlBuffer(); ebo = new GlBuffer();
vertexArray = GlVertexArray.create(); vertexArray = GlVertexArray.create();
vertexArray.setElementBuffer(ebo.handle()); vertexArray.setElementBuffer(ebo.handle());
BufferLayout layout = vertexType.getLayout(); BufferLayout layout = VERTEX_TYPE.getLayout();
vertexArray.bindVertexBuffer(0, vbo.handle(), 0, layout.getStride()); vertexArray.bindVertexBuffer(0, vbo.handle(), 0, layout.getStride());
vertexArray.bindAttributes(0, 0, layout.attributes()); vertexArray.bindAttributes(0, 0, layout.attributes());
} }
public VertexType getVertexType() { public VertexType getVertexType() {
return vertexType; return VERTEX_TYPE;
} }
/** /**
@ -98,6 +99,8 @@ public class IndirectMeshPool {
final long vertexPtr = vertexBlock.ptr(); final long vertexPtr = vertexBlock.ptr();
final long indexPtr = indexBlock.ptr(); final long indexPtr = indexBlock.ptr();
var target = new BlockVertexList();
int byteIndex = 0; int byteIndex = 0;
int baseVertex = 0; int baseVertex = 0;
int firstIndex = maxQuadIndexCount; int firstIndex = maxQuadIndexCount;
@ -105,7 +108,8 @@ public class IndirectMeshPool {
mesh.byteIndex = byteIndex; mesh.byteIndex = byteIndex;
mesh.baseVertex = baseVertex; mesh.baseVertex = baseVertex;
mesh.buffer(vertexPtr); target.ptr(vertexPtr + mesh.byteIndex);
mesh.mesh.write(target);
byteIndex += mesh.size(); byteIndex += mesh.size();
baseVertex += mesh.mesh.vertexCount(); baseVertex += mesh.mesh.vertexCount();
@ -156,17 +160,13 @@ public class IndirectMeshPool {
} }
public int size() { public int size() {
return mesh.size(); return mesh.vertexCount() * VERTEX_TYPE.getStride();
} }
public int indexCount() { public int indexCount() {
return mesh.indexCount(); return mesh.indexCount();
} }
private void buffer(long ptr) {
mesh.write(ptr + byteIndex);
}
public Vector4fc boundingSphere() { public Vector4fc boundingSphere() {
return mesh.boundingSphere(); return mesh.boundingSphere();
} }

View file

@ -57,7 +57,7 @@ public class InstancedCrumbling {
.cutout(CutoutShaders.OFF); .cutout(CutoutShaders.OFF);
var program = InstancingPrograms.get() var program = InstancingPrograms.get()
.get(shader.vertexType(), shader.instanceType(), Contexts.CRUMBLING); .get(shader.instanceType(), Contexts.CRUMBLING);
UniformBuffer.syncAndBind(program); UniformBuffer.syncAndBind(program);
InstancingEngine.uploadMaterialIDUniform(program, crumblingMaterial); InstancingEngine.uploadMaterialIDUniform(program, crumblingMaterial);

View file

@ -2,7 +2,6 @@ package com.jozufozu.flywheel.backend.engine.instancing;
import java.util.Collection; import java.util.Collection;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -16,7 +15,6 @@ import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.model.Mesh; import com.jozufozu.flywheel.api.model.Mesh;
import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.engine.InstancerKey; import com.jozufozu.flywheel.backend.engine.InstancerKey;
import com.jozufozu.flywheel.backend.engine.InstancerStorage; import com.jozufozu.flywheel.backend.engine.InstancerStorage;
@ -28,7 +26,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
/** /**
* A map of vertex types to their mesh pools. * A map of vertex types to their mesh pools.
*/ */
private final Map<VertexType, InstancedMeshPool> meshPools = new HashMap<>(); private final InstancedMeshPool meshPool = new InstancedMeshPool();
private final EBOCache eboCache = new EBOCache(); private final EBOCache eboCache = new EBOCache();
public DrawSet get(RenderStage stage) { public DrawSet get(RenderStage stage) {
@ -38,17 +36,13 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
public void flush() { public void flush() {
super.flush(); super.flush();
for (var pool : meshPools.values()) { meshPool.flush();
pool.flush();
}
} }
public void invalidate() { public void invalidate() {
super.invalidate(); super.invalidate();
meshPools.values() meshPool.delete();
.forEach(InstancedMeshPool::delete);
meshPools.clear();
drawSets.values() drawSets.values()
.forEach(DrawSet::delete); .forEach(DrawSet::delete);
@ -58,8 +52,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
} }
private InstancedMeshPool.BufferedMesh alloc(Mesh mesh) { private InstancedMeshPool.BufferedMesh alloc(Mesh mesh) {
return meshPools.computeIfAbsent(mesh.vertexType(), InstancedMeshPool::new) return meshPool.alloc(mesh, eboCache);
.alloc(mesh, eboCache);
} }
@Override @Override
@ -77,7 +70,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
for (var entry : meshes.entrySet()) { for (var entry : meshes.entrySet()) {
var mesh = alloc(entry.getValue()); var mesh = alloc(entry.getValue());
ShaderState shaderState = new ShaderState(entry.getKey(), mesh.getVertexType(), instancer.type); ShaderState shaderState = new ShaderState(entry.getKey(), instancer.type);
DrawCall drawCall = new DrawCall(instancer, mesh, shaderState); DrawCall drawCall = new DrawCall(instancer, mesh, shaderState);
drawSet.put(shaderState, drawCall); drawSet.put(shaderState, drawCall);

View file

@ -18,9 +18,10 @@ import com.jozufozu.flywheel.gl.GlPrimitive;
import com.jozufozu.flywheel.gl.array.GlVertexArray; import com.jozufozu.flywheel.gl.array.GlVertexArray;
import com.jozufozu.flywheel.gl.buffer.GlBuffer; import com.jozufozu.flywheel.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.lib.vertex.VertexTypes;
public class InstancedMeshPool { public class InstancedMeshPool {
private final VertexType vertexType; private static final VertexType VERTEX_TYPE = VertexTypes.BLOCK;
private final Map<Mesh, BufferedMesh> meshes = new HashMap<>(); private final Map<Mesh, BufferedMesh> meshes = new HashMap<>();
private final List<BufferedMesh> allBuffered = new ArrayList<>(); private final List<BufferedMesh> allBuffered = new ArrayList<>();
@ -35,15 +36,15 @@ public class InstancedMeshPool {
/** /**
* Create a new mesh pool. * Create a new mesh pool.
*/ */
public InstancedMeshPool(VertexType vertexType) { public InstancedMeshPool() {
this.vertexType = vertexType; int stride = VERTEX_TYPE.getLayout()
int stride = vertexType.getLayout().getStride(); .getStride();
vbo = new GlBuffer(); vbo = new GlBuffer();
vbo.growthFunction(l -> Math.max(l + stride * 128L, (long) (l * 1.6))); vbo.growthFunction(l -> Math.max(l + stride * 128L, (long) (l * 1.6)));
} }
public VertexType getVertexType() { public VertexType getVertexType() {
return vertexType; return VERTEX_TYPE;
} }
/** /**
@ -55,10 +56,6 @@ public class InstancedMeshPool {
*/ */
public BufferedMesh alloc(Mesh mesh, EBOCache eboCache) { public BufferedMesh alloc(Mesh mesh, EBOCache eboCache) {
return meshes.computeIfAbsent(mesh, m -> { return meshes.computeIfAbsent(mesh, m -> {
if (m.vertexType() != vertexType) {
throw new IllegalArgumentException("Mesh has wrong vertex type");
}
BufferedMesh bufferedMesh = new BufferedMesh(m, byteSize, eboCache); BufferedMesh bufferedMesh = new BufferedMesh(m, byteSize, eboCache);
byteSize += bufferedMesh.size(); byteSize += bufferedMesh.size();
allBuffered.add(bufferedMesh); allBuffered.add(bufferedMesh);
@ -121,8 +118,12 @@ public class InstancedMeshPool {
try (MappedBuffer mapped = vbo.map()) { try (MappedBuffer mapped = vbo.map()) {
long ptr = mapped.ptr(); long ptr = mapped.ptr();
var vertexList = VERTEX_TYPE.createVertexList();
for (BufferedMesh mesh : pendingUpload) { for (BufferedMesh mesh : pendingUpload) {
mesh.buffer(ptr); vertexList.ptr(ptr + mesh.byteIndex);
mesh.mesh.write(vertexList);
mesh.boundTo.clear();
} }
pendingUpload.clear(); pendingUpload.clear();
@ -140,7 +141,7 @@ public class InstancedMeshPool {
@Override @Override
public String toString() { public String toString() {
return "InstancedMeshPool{" + "vertexType=" + vertexType + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}'; return "InstancedMeshPool{" + "vertexType=" + VERTEX_TYPE + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
} }
public class BufferedMesh { public class BufferedMesh {
@ -158,15 +159,16 @@ public class InstancedMeshPool {
} }
public int size() { public int size() {
return mesh.size(); return mesh.vertexCount() * VERTEX_TYPE.getStride();
} }
public VertexType getVertexType() { public VertexType getVertexType() {
return vertexType; return VERTEX_TYPE;
} }
public int getAttributeCount() { public int getAttributeCount() {
return vertexType.getLayout().getAttributeCount(); return VERTEX_TYPE.getLayout()
.getAttributeCount();
} }
public boolean isDeleted() { public boolean isDeleted() {
@ -177,15 +179,9 @@ public class InstancedMeshPool {
return mesh.isEmpty() || isDeleted(); return mesh.isEmpty() || isDeleted();
} }
private void buffer(long ptr) {
mesh.write(ptr + byteIndex);
boundTo.clear();
}
public void setup(GlVertexArray vao) { public void setup(GlVertexArray vao) {
if (boundTo.add(vao)) { if (boundTo.add(vao)) {
BufferLayout type = vertexType.getLayout(); BufferLayout type = VERTEX_TYPE.getLayout();
vao.bindVertexBuffer(0, InstancedMeshPool.this.vbo.handle(), byteIndex, type.getStride()); vao.bindVertexBuffer(0, InstancedMeshPool.this.vbo.handle(), byteIndex, type.getStride());
vao.bindAttributes(0, 0, type.attributes()); vao.bindAttributes(0, 0, type.attributes());
vao.setElementBuffer(ebo); vao.setElementBuffer(ebo);

View file

@ -109,7 +109,7 @@ public class InstancingEngine extends AbstractEngine {
} }
var program = InstancingPrograms.get() var program = InstancingPrograms.get()
.get(shader.vertexType(), shader.instanceType(), Contexts.WORLD); .get(shader.instanceType(), Contexts.WORLD);
UniformBuffer.syncAndBind(program); UniformBuffer.syncAndBind(program);
uploadMaterialIDUniform(program, shader.material()); uploadMaterialIDUniform(program, shader.material());

View file

@ -2,7 +2,6 @@ package com.jozufozu.flywheel.backend.engine.instancing;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.vertex.VertexType;
public record ShaderState(Material material, VertexType vertexType, InstanceType<?> instanceType) { public record ShaderState(Material material, InstanceType<?> instanceType) {
} }

View file

@ -4,8 +4,6 @@ import com.jozufozu.flywheel.api.layout.BufferLayout;
import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.lib.layout.CommonItems; import com.jozufozu.flywheel.lib.layout.CommonItems;
import net.minecraft.resources.ResourceLocation;
public class BlockVertex implements VertexType { public class BlockVertex implements VertexType {
public static final BufferLayout FORMAT = BufferLayout.builder() public static final BufferLayout FORMAT = BufferLayout.builder()
.addItem(CommonItems.VEC3, "position") .addItem(CommonItems.VEC3, "position")
@ -21,11 +19,6 @@ public class BlockVertex implements VertexType {
return FORMAT; return FORMAT;
} }
@Override
public ResourceLocation layoutShader() {
return VertexTypes.Files.BLOCK_LAYOUT;
}
@Override @Override
public BlockVertexList createVertexList() { public BlockVertexList createVertexList() {
return new BlockVertexList(); return new BlockVertexList();

View file

@ -4,8 +4,6 @@ import com.jozufozu.flywheel.api.layout.BufferLayout;
import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.lib.layout.CommonItems; import com.jozufozu.flywheel.lib.layout.CommonItems;
import net.minecraft.resources.ResourceLocation;
public class PosTexNormalVertex implements VertexType { public class PosTexNormalVertex implements VertexType {
public static final BufferLayout FORMAT = BufferLayout.builder() public static final BufferLayout FORMAT = BufferLayout.builder()
.addItem(CommonItems.VEC3, "position") .addItem(CommonItems.VEC3, "position")
@ -18,11 +16,6 @@ public class PosTexNormalVertex implements VertexType {
return FORMAT; return FORMAT;
} }
@Override
public ResourceLocation layoutShader() {
return VertexTypes.Files.POS_TEX_NORMAL_LAYOUT;
}
@Override @Override
public PosTexNormalVertexList createVertexList() { public PosTexNormalVertexList createVertexList() {
return new PosTexNormalVertexList(); return new PosTexNormalVertexList();

View file

@ -2,14 +2,9 @@ package com.jozufozu.flywheel.lib.vertex;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.vertex.VertexType;
import net.minecraft.resources.ResourceLocation;
public final class VertexTypes { public final class VertexTypes {
public static final BlockVertex BLOCK = VertexType.REGISTRY.registerAndGet(new BlockVertex()); public static final BlockVertex BLOCK = new BlockVertex();
public static final PosTexNormalVertex POS_TEX_NORMAL = VertexType.REGISTRY.registerAndGet(new PosTexNormalVertex()); public static final PosTexNormalVertex POS_TEX_NORMAL = new PosTexNormalVertex();
private VertexTypes() { private VertexTypes() {
} }
@ -17,14 +12,4 @@ public final class VertexTypes {
@ApiStatus.Internal @ApiStatus.Internal
public static void init() { public static void init() {
} }
public static final class Files {
public static final ResourceLocation BLOCK_LAYOUT = Names.BLOCK.withSuffix(".vert");
public static final ResourceLocation POS_TEX_NORMAL_LAYOUT = Names.POS_TEX_NORMAL.withSuffix(".vert");
}
public static final class Names {
public static final ResourceLocation BLOCK = Flywheel.rl("layout/block");
public static final ResourceLocation POS_TEX_NORMAL = Flywheel.rl("layout/pos_tex_normal");
}
} }

View file

@ -16,9 +16,6 @@ vec4 flw_var3;
/*const*/ FlwMaterial flw_material; /*const*/ FlwMaterial flw_material;
// To be implemented by the layout shader.
void flw_layoutVertex();
// To be implemented by the instance shader. // To be implemented by the instance shader.
void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout float radius); void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout float radius);
void flw_instanceVertex(FlwInstance i); void flw_instanceVertex(FlwInstance i);

View file

@ -6,7 +6,7 @@ layout(location = 2) in vec2 _flw_v_texCoord;
layout(location = 3) in ivec2 _flw_v_light; layout(location = 3) in ivec2 _flw_v_light;
layout(location = 4) in vec3 _flw_v_normal; layout(location = 4) in vec3 _flw_v_normal;
void flw_layoutVertex() { void _flw_layoutVertex() {
flw_vertexPos = vec4(_flw_v_pos, 1.0); flw_vertexPos = vec4(_flw_v_pos, 1.0);
flw_vertexColor = _flw_v_color; flw_vertexColor = _flw_v_color;
flw_vertexTexCoord = _flw_v_texCoord; flw_vertexTexCoord = _flw_v_texCoord;

View file

@ -1,6 +1,7 @@
#include "flywheel:internal/indirect/api/vertex.glsl" #include "flywheel:internal/indirect/api/vertex.glsl"
#include "flywheel:internal/indirect/mesh.glsl" #include "flywheel:internal/indirect/mesh.glsl"
#include "flywheel:internal/material.glsl" #include "flywheel:internal/material.glsl"
#include "flywheel:internal/block.vert"
#include "flywheel:util/diffuse.glsl" #include "flywheel:util/diffuse.glsl"
flat out uvec3 _flw_material; flat out uvec3 _flw_material;
@ -33,7 +34,7 @@ void main() {
_flw_unpackMaterial(p, flw_material); _flw_unpackMaterial(p, flw_material);
_flw_material = uvec3(drawCommands[batchID].fragmentMaterialID, drawCommands[batchID].packedFogAndCutout, p); _flw_material = uvec3(drawCommands[batchID].fragmentMaterialID, drawCommands[batchID].packedFogAndCutout, p);
flw_layoutVertex(); _flw_layoutVertex();
flw_beginVertex(); flw_beginVertex();
flw_instanceVertex(i); flw_instanceVertex(i);
flw_materialVertex(); flw_materialVertex();

View file

@ -1,5 +1,6 @@
#include "flywheel:internal/instancing/api/vertex.glsl" #include "flywheel:internal/instancing/api/vertex.glsl"
#include "flywheel:internal/material.glsl" #include "flywheel:internal/material.glsl"
#include "flywheel:internal/block.vert"
#include "flywheel:util/diffuse.glsl" #include "flywheel:util/diffuse.glsl"
uniform uvec4 _flw_material_instancing; uniform uvec4 _flw_material_instancing;
@ -11,7 +12,7 @@ void main() {
FlwInstance i = _flw_unpackInstance(); FlwInstance i = _flw_unpackInstance();
flw_layoutVertex(); _flw_layoutVertex();
flw_beginVertex(); flw_beginVertex();
flw_instanceVertex(i); flw_instanceVertex(i);
flw_materialVertex(); flw_materialVertex();

View file

@ -1,14 +0,0 @@
#include "flywheel:api/vertex.glsl"
layout(location = 0) in vec3 _flw_v_pos;
layout(location = 1) in vec2 _flw_v_texCoord;
layout(location = 2) in vec3 _flw_v_normal;
void flw_layoutVertex() {
flw_vertexPos = vec4(_flw_v_pos, 1.0);
flw_vertexColor = vec4(1.0);
flw_vertexTexCoord = _flw_v_texCoord;
flw_vertexOverlay = ivec2(0, 10);
flw_vertexLight = vec2(1.0);
flw_vertexNormal = _flw_v_normal;
}