Make it even shadier

- Reorganize internal package based on backend.
- Add api redefinitions in separate files.
- When compiling, insert pipeline api impls at the top.
This commit is contained in:
Jozufozu 2023-12-01 13:18:05 -08:00
parent ade814140e
commit 31ee65de30
16 changed files with 203 additions and 86 deletions

View file

@ -10,7 +10,6 @@ import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.backend.Backends; import com.jozufozu.flywheel.backend.Backends;
import com.jozufozu.flywheel.backend.MaterialShaderIndices; import com.jozufozu.flywheel.backend.MaterialShaderIndices;
import com.jozufozu.flywheel.backend.compile.FlwPrograms; import com.jozufozu.flywheel.backend.compile.FlwPrograms;
import com.jozufozu.flywheel.backend.compile.Pipelines;
import com.jozufozu.flywheel.backend.engine.UniformBuffer; import com.jozufozu.flywheel.backend.engine.UniformBuffer;
import com.jozufozu.flywheel.backend.engine.batching.DrawBuffer; import com.jozufozu.flywheel.backend.engine.batching.DrawBuffer;
import com.jozufozu.flywheel.config.BackendArgument; import com.jozufozu.flywheel.config.BackendArgument;
@ -120,7 +119,6 @@ public class Flywheel {
ShadersModHandler.init(); ShadersModHandler.init();
Pipelines.init();
Backends.init(); Backends.init();
} }

View file

@ -104,6 +104,6 @@ public class IndirectPrograms {
} }
private static final class Files { private static final class Files {
public static final ResourceLocation INDIRECT_CULL = Flywheel.rl("internal/indirect_cull.glsl"); public static final ResourceLocation INDIRECT_CULL = Flywheel.rl("internal/indirect/cull.glsl");
} }
} }

View file

@ -1,5 +1,7 @@
package com.jozufozu.flywheel.backend.compile; package com.jozufozu.flywheel.backend.compile;
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.api.vertex.VertexType;
import com.jozufozu.flywheel.glsl.GLSLVersion; import com.jozufozu.flywheel.glsl.GLSLVersion;
@ -7,8 +9,8 @@ import com.jozufozu.flywheel.glsl.SourceComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
// TODO: move shader api redefinition to a separate file? public record Pipeline(GLSLVersion glslVersion, ResourceLocation vertexShader, ResourceLocation fragmentShader,
public record Pipeline(GLSLVersion glslVersion, ResourceLocation vertexShader, ResourceLocation fragmentShader, InstanceAssembler assembler) { ResourceLocation vertexAPI, ResourceLocation fragmentAPI, InstanceAssembler assembler) {
@FunctionalInterface @FunctionalInterface
public interface InstanceAssembler { public interface InstanceAssembler {
/** /**
@ -30,6 +32,8 @@ public record Pipeline(GLSLVersion glslVersion, ResourceLocation vertexShader, R
private GLSLVersion glslVersion; private GLSLVersion glslVersion;
private ResourceLocation vertex; private ResourceLocation vertex;
private ResourceLocation fragment; private ResourceLocation fragment;
private ResourceLocation vertexAPI;
private ResourceLocation fragmentAPI;
private InstanceAssembler assembler; private InstanceAssembler assembler;
public Builder glslVersion(GLSLVersion glslVersion) { public Builder glslVersion(GLSLVersion glslVersion) {
@ -47,13 +51,29 @@ public record Pipeline(GLSLVersion glslVersion, ResourceLocation vertexShader, R
return this; return this;
} }
public Builder vertexAPI(ResourceLocation vertex) {
this.vertexAPI = vertex;
return this;
}
public Builder fragmentAPI(ResourceLocation fragment) {
this.fragmentAPI = fragment;
return this;
}
public Builder assembler(InstanceAssembler assembler) { public Builder assembler(InstanceAssembler assembler) {
this.assembler = assembler; this.assembler = assembler;
return this; return this;
} }
public Pipeline build() { public Pipeline build() {
return new Pipeline(glslVersion, vertex, fragment, assembler); Objects.requireNonNull(glslVersion);
Objects.requireNonNull(vertex);
Objects.requireNonNull(fragment);
Objects.requireNonNull(vertexAPI);
Objects.requireNonNull(fragmentAPI);
Objects.requireNonNull(assembler);
return new Pipeline(glslVersion, vertex, fragment, vertexAPI, fragmentAPI, assembler);
} }
} }
} }

View file

@ -17,21 +17,23 @@ public class PipelineCompiler {
.withComponent(uniformComponent) .withComponent(uniformComponent)
.withComponent(key -> pipeline.assembler() .withComponent(key -> pipeline.assembler()
.assemble(new Pipeline.InstanceAssemblerContext(key.vertexType(), key.instanceType()))) .assemble(new Pipeline.InstanceAssemblerContext(key.vertexType(), key.instanceType())))
.withResource(pipeline.vertexShader()) .withResource(pipeline.vertexAPI())
.withComponent(vertexMaterialComponent) .withComponent(vertexMaterialComponent)
.withResource(key -> key.vertexType() .withResource(key -> key.vertexType()
.layoutShader()) .layoutShader())
.withResource(key -> key.instanceType() .withResource(key -> key.instanceType()
.instanceShader()) .instanceShader())
.withResource(key -> key.contextShader() .withResource(key -> key.contextShader()
.vertexShader())) .vertexShader())
.withResource(pipeline.vertexShader()))
.link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.FRAGMENT) .link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.FRAGMENT)
.enableExtension("GL_ARB_conservative_depth") .enableExtension("GL_ARB_conservative_depth")
.withComponent(uniformComponent) .withComponent(uniformComponent)
.withResource(pipeline.fragmentShader()) .withResource(pipeline.fragmentAPI())
.withComponent(fragmentMaterialComponent) .withComponent(fragmentMaterialComponent)
.withResource(key -> key.contextShader() .withResource(key -> key.contextShader()
.fragmentShader())) .fragmentShader())
.withResource(pipeline.fragmentShader()))
.then((key, program) -> { .then((key, program) -> {
key.contextShader() key.contextShader()
.onProgramLink(program); .onProgramLink(program);

View file

@ -5,28 +5,21 @@ import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
import com.jozufozu.flywheel.backend.compile.component.InstancedArraysComponent; import com.jozufozu.flywheel.backend.compile.component.InstancedArraysComponent;
import com.jozufozu.flywheel.glsl.GLSLVersion; import com.jozufozu.flywheel.glsl.GLSLVersion;
import net.minecraft.resources.ResourceLocation;
public final class Pipelines { public final class Pipelines {
public static final Pipeline INSTANCED_ARRAYS = Pipeline.builder() public static final Pipeline INSTANCED_ARRAYS = Pipeline.builder()
.glslVersion(GLSLVersion.V330) .glslVersion(GLSLVersion.V330)
.vertex(Files.INSTANCED_ARRAYS_DRAW) .vertex(Flywheel.rl("internal/instancing/draw.vert"))
.fragment(Files.DRAW_FRAGMENT) .fragment(Flywheel.rl("internal/instancing/draw.frag"))
.vertexAPI(Flywheel.rl("internal/instancing/api/vertex.glsl"))
.fragmentAPI(Flywheel.rl("internal/instancing/api/fragment.glsl"))
.assembler(InstancedArraysComponent::new) .assembler(InstancedArraysComponent::new)
.build(); .build();
public static final Pipeline INDIRECT = Pipeline.builder() public static final Pipeline INDIRECT = Pipeline.builder()
.glslVersion(GLSLVersion.V460) .glslVersion(GLSLVersion.V460)
.vertex(Files.INDIRECT_DRAW) .vertex(Flywheel.rl("internal/indirect/draw.vert"))
.fragment(Files.DRAW_FRAGMENT) .fragment(Flywheel.rl("internal/indirect/draw.frag"))
.vertexAPI(Flywheel.rl("internal/indirect/api/vertex.glsl"))
.fragmentAPI(Flywheel.rl("internal/indirect/api/fragment.glsl"))
.assembler(IndirectComponent::create) .assembler(IndirectComponent::create)
.build(); .build();
public static void init() {
}
public static final class Files {
public static final ResourceLocation INSTANCED_ARRAYS_DRAW = Flywheel.rl("internal/instanced_arrays_draw.vert");
public static final ResourceLocation INDIRECT_DRAW = Flywheel.rl("internal/indirect_draw.vert");
public static final ResourceLocation DRAW_FRAGMENT = Flywheel.rl("internal/draw.frag");
}
} }

View file

@ -29,7 +29,7 @@ public class IndirectBuffers {
public static final long PTR_SIZE = Pointer.POINTER_SIZE; public static final long PTR_SIZE = Pointer.POINTER_SIZE;
// DRAW COMMAND // DRAW COMMAND
public static final long DRAW_COMMAND_STRIDE = 44; public static final long DRAW_COMMAND_STRIDE = 48;
public static final long DRAW_COMMAND_OFFSET = 0; public static final long DRAW_COMMAND_OFFSET = 0;
// BITS // BITS
@ -39,6 +39,9 @@ public class IndirectBuffers {
private static final int GPU_ONLY_BITS = 0; private static final int GPU_ONLY_BITS = 0;
// OFFSETS // OFFSETS
private static final long OBJECT_OFFSET = 0;
private static final long TARGET_OFFSET = INT_SIZE;
private static final long DRAW_OFFSET = INT_SIZE * 2;
private static final long OFFSET_OFFSET = BUFFER_COUNT * INT_SIZE; private static final long OFFSET_OFFSET = BUFFER_COUNT * INT_SIZE;
private static final long SIZE_OFFSET = OFFSET_OFFSET + BUFFER_COUNT * PTR_SIZE; private static final long SIZE_OFFSET = OFFSET_OFFSET + BUFFER_COUNT * PTR_SIZE;
private static final long BUFFERS_SIZE_BYTES = SIZE_OFFSET + BUFFER_COUNT * PTR_SIZE; private static final long BUFFERS_SIZE_BYTES = SIZE_OFFSET + BUFFER_COUNT * PTR_SIZE;
@ -47,6 +50,18 @@ public class IndirectBuffers {
private static final long TARGET_SIZE_OFFSET = OBJECT_SIZE_OFFSET + PTR_SIZE; private static final long TARGET_SIZE_OFFSET = OBJECT_SIZE_OFFSET + PTR_SIZE;
private static final long DRAW_SIZE_OFFSET = TARGET_SIZE_OFFSET + PTR_SIZE; private static final long DRAW_SIZE_OFFSET = TARGET_SIZE_OFFSET + PTR_SIZE;
/**
* A small block of memory divided into 3 contiguous segments:
* <br>
* {@code buffers}: an array of {@link IndirectBuffers#INT_SIZE} buffer handles.
* <br>
* {@code offsets}: an array of {@link IndirectBuffers#PTR_SIZE} offsets into the buffers, currently just zeroed.
* <br>
* {@code sizes}: an array of {@link IndirectBuffers#PTR_SIZE} byte lengths of the buffers.
* <br>
* Each segment stores {@link IndirectBuffers#BUFFER_COUNT} elements,
* one for the object buffer, one for the target buffer, and one for the draw buffer.
*/
private final MemoryBlock buffers; private final MemoryBlock buffers;
private final long objectStride; private final long objectStride;
private int object; private int object;
@ -70,9 +85,9 @@ public class IndirectBuffers {
void createBuffers() { void createBuffers() {
final long ptr = buffers.ptr(); final long ptr = buffers.ptr();
nglCreateBuffers(BUFFER_COUNT, ptr); nglCreateBuffers(BUFFER_COUNT, ptr);
object = MemoryUtil.memGetInt(ptr); object = MemoryUtil.memGetInt(ptr + OBJECT_OFFSET);
target = MemoryUtil.memGetInt(ptr + 4); target = MemoryUtil.memGetInt(ptr + TARGET_OFFSET);
draw = MemoryUtil.memGetInt(ptr + 8); draw = MemoryUtil.memGetInt(ptr + DRAW_OFFSET);
} }
void updateCounts(int objectCount, int drawCount) { void updateCounts(int objectCount, int drawCount) {
@ -102,8 +117,8 @@ public class IndirectBuffers {
final long ptr = buffers.ptr(); final long ptr = buffers.ptr();
nglCreateBuffers(BUFFER_COUNT - 1, ptr); nglCreateBuffers(BUFFER_COUNT - 1, ptr);
int objectNew = MemoryUtil.memGetInt(ptr); int objectNew = MemoryUtil.memGetInt(ptr + OBJECT_OFFSET);
int targetNew = MemoryUtil.memGetInt(ptr + 4); int targetNew = MemoryUtil.memGetInt(ptr + TARGET_OFFSET);
glNamedBufferStorage(objectNew, objectSize, PERSISTENT_BITS); glNamedBufferStorage(objectNew, objectSize, PERSISTENT_BITS);
glNamedBufferStorage(targetNew, targetSize, GPU_ONLY_BITS); glNamedBufferStorage(targetNew, targetSize, GPU_ONLY_BITS);
@ -138,7 +153,7 @@ public class IndirectBuffers {
glDeleteBuffers(draw); glDeleteBuffers(draw);
MemoryUtil.memPutInt(buffers.ptr() + INT_SIZE * 2, drawNew); MemoryUtil.memPutInt(buffers.ptr() + DRAW_OFFSET, drawNew);
draw = drawNew; draw = drawNew;
drawPtr = MemoryUtil.nmemRealloc(drawPtr, drawSize); drawPtr = MemoryUtil.nmemRealloc(drawPtr, drawSize);
} else { } else {

View file

@ -1,3 +1,6 @@
// API
// ------------------------------------------
in vec4 flw_vertexPos; in vec4 flw_vertexPos;
in vec4 flw_vertexColor; in vec4 flw_vertexColor;
in vec2 flw_vertexTexCoord; in vec2 flw_vertexTexCoord;
@ -12,9 +15,6 @@ in vec4 flw_var1;
in vec4 flw_var2; in vec4 flw_var2;
in vec4 flw_var3; in vec4 flw_var3;
flat in uint _flw_materialFragmentID;
flat in uint _flw_packedMaterialProperties;
vec4 flw_sampleColor; vec4 flw_sampleColor;
vec4 flw_fragColor; vec4 flw_fragColor;
@ -29,8 +29,11 @@ void flw_initFragment();
void flw_materialFragment(); void flw_materialFragment();
void flw_contextFragment(); void flw_contextFragment();
void main() { // ------------------------------------------
flw_initFragment(); // INTERNAL
flw_materialFragment(); // ------------------------------------------
flw_contextFragment();
} uint _flw_materialFragmentID;
uint _flw_packedMaterialProperties;
// ------------------------------------------

View file

@ -0,0 +1,34 @@
// API
// ------------------------------------------
out vec4 flw_vertexPos;
out vec4 flw_vertexColor;
out vec2 flw_vertexTexCoord;
flat out ivec2 flw_vertexOverlay;
out vec2 flw_vertexLight;
out vec3 flw_vertexNormal;
out float flw_distance;
out vec4 flw_var0;
out vec4 flw_var1;
out vec4 flw_var2;
out vec4 flw_var3;
void flw_layoutVertex();
void flw_initVertex();
void flw_instanceVertex(FlwInstance i);
void flw_materialVertex();
void flw_contextVertex();
// ------------------------------------------
// INTERNAL
// ------------------------------------------
uint _flw_materialVertexID;
uint _flw_materialFragmentID;
uint _flw_packedMaterialProperties;
FlwInstance _flw_unpackInstance(FlwPackedInstance i);
// ------------------------------------------

View file

@ -1,6 +1,6 @@
layout(local_size_x = FLW_SUBGROUP_SIZE) in; layout(local_size_x = FLW_SUBGROUP_SIZE) in;
#include "flywheel:internal/indirect_draw_command.glsl" #include "flywheel:internal/indirect/mesh.glsl"
// need to add stubs so the instance shader compiles. // need to add stubs so the instance shader compiles.
vec4 flw_vertexPos; vec4 flw_vertexPos;

View file

@ -0,0 +1,12 @@
#include "flywheel:internal/indirect/api/fragment.glsl"
flat in uvec2 _flw_material;
void main() {
_flw_materialFragmentID = _flw_material.x;
_flw_packedMaterialProperties = _flw_material.y;
flw_initFragment();
flw_materialFragment();
flw_contextFragment();
}

View file

@ -1,29 +1,13 @@
#include "flywheel:internal/indirect_draw_command.glsl" #include "flywheel:internal/indirect/api/vertex.glsl"
#include "flywheel:internal/indirect/mesh.glsl"
out vec4 flw_vertexPos; flat out uvec2 _flw_material;
out vec4 flw_vertexColor;
out vec2 flw_vertexTexCoord;
flat out ivec2 flw_vertexOverlay;
out vec2 flw_vertexLight;
out vec3 flw_vertexNormal;
out float flw_distance;
out vec4 flw_var0;
out vec4 flw_var1;
out vec4 flw_var2;
out vec4 flw_var3;
uint _flw_materialVertexID;
flat out uint _flw_materialFragmentID;
flat out uint _flw_packedMaterialProperties;
struct Object { struct Object {
uint batchID; uint batchID;
FlwPackedInstance instance; FlwPackedInstance instance;
}; };
layout(std430, binding = 0) restrict readonly buffer ObjectBuffer { layout(std430, binding = 0) restrict readonly buffer ObjectBuffer {
Object objects[]; Object objects[];
}; };
@ -36,14 +20,6 @@ layout(std430, binding = 2) restrict readonly buffer DrawCommands {
MeshDrawCommand drawCommands[]; MeshDrawCommand drawCommands[];
}; };
FlwInstance _flw_unpackInstance(FlwPackedInstance i);
void flw_layoutVertex();
void flw_initVertex();
void flw_instanceVertex(FlwInstance i);
void flw_materialVertex();
void flw_contextVertex();
void main() { void main() {
uint instanceIndex = objectIDs[gl_BaseInstance + gl_InstanceID]; uint instanceIndex = objectIDs[gl_BaseInstance + gl_InstanceID];
uint batchID = objects[instanceIndex].batchID; uint batchID = objects[instanceIndex].batchID;
@ -53,6 +29,8 @@ void main() {
_flw_materialFragmentID = drawCommands[batchID].fragmentMaterialID; _flw_materialFragmentID = drawCommands[batchID].fragmentMaterialID;
_flw_packedMaterialProperties = drawCommands[batchID].packedMaterialProperties; _flw_packedMaterialProperties = drawCommands[batchID].packedMaterialProperties;
_flw_material = uvec2(_flw_materialFragmentID, _flw_packedMaterialProperties);
flw_layoutVertex(); flw_layoutVertex();
flw_initVertex(); flw_initVertex();
flw_instanceVertex(i); flw_instanceVertex(i);

View file

@ -0,0 +1,41 @@
// API
// -----------------------------------------
in vec4 flw_vertexPos;
in vec4 flw_vertexColor;
in vec2 flw_vertexTexCoord;
flat in ivec2 flw_vertexOverlay;
in vec2 flw_vertexLight;
in vec3 flw_vertexNormal;
in float flw_distance;
in vec4 flw_var0;
in vec4 flw_var1;
in vec4 flw_var2;
in vec4 flw_var3;
vec4 flw_sampleColor;
vec4 flw_fragColor;
ivec2 flw_fragOverlay;
vec2 flw_fragLight;
vec4 flw_fogFilter(vec4 color);
bool flw_discardPredicate(vec4 finalColor);
void flw_initFragment();
void flw_materialFragment();
void flw_contextFragment();
// -----------------------------------------
// INTERNAL
// -----------------------------------------
uint _flw_materialVertexID;
uint _flw_materialFragmentID;
uint _flw_packedMaterialProperties;
uniform uvec3 _flw_material_instancing;
// -----------------------------------------

View file

@ -1,3 +1,5 @@
// API
// ------------------------------------
out vec4 flw_vertexPos; out vec4 flw_vertexPos;
out vec4 flw_vertexColor; out vec4 flw_vertexColor;
out vec2 flw_vertexTexCoord; out vec2 flw_vertexTexCoord;
@ -12,29 +14,22 @@ out vec4 flw_var1;
out vec4 flw_var2; out vec4 flw_var2;
out vec4 flw_var3; out vec4 flw_var3;
uint _flw_materialVertexID;
flat out uint _flw_materialFragmentID;
flat out uint _flw_packedMaterialProperties;
uniform uvec3 _flw_material_instancing;
void flw_layoutVertex(); void flw_layoutVertex();
void flw_initVertex(); void flw_initVertex();
void flw_instanceVertex(FlwInstance i); void flw_instanceVertex(FlwInstance i);
void flw_materialVertex(); void flw_materialVertex();
void flw_contextVertex(); void flw_contextVertex();
void main() { // ------------------------------------
_flw_materialVertexID = _flw_material_instancing.x; // INTERNAL
_flw_materialFragmentID = _flw_material_instancing.y; // ------------------------------------
_flw_packedMaterialProperties = _flw_material_instancing.z;
FlwInstance i = _flw_unpackInstance(); uint _flw_materialVertexID;
uint _flw_materialFragmentID;
uint _flw_packedMaterialProperties;
flw_layoutVertex(); FlwInstance _flw_unpackInstance();
flw_initVertex();
flw_instanceVertex(i); uniform uvec3 _flw_material_instancing;
flw_materialVertex();
flw_contextVertex(); // ------------------------------------
}

View file

@ -0,0 +1,11 @@
#include "flywheel:internal/instancing/api/fragment.glsl"
void main() {
_flw_materialVertexID = _flw_material_instancing.x;
_flw_materialFragmentID = _flw_material_instancing.y;
_flw_packedMaterialProperties = _flw_material_instancing.z;
flw_initFragment();
flw_materialFragment();
flw_contextFragment();
}

View file

@ -0,0 +1,15 @@
#include "flywheel:internal/instancing/api/vertex.glsl"
void main() {
_flw_materialVertexID = _flw_material_instancing.x;
_flw_materialFragmentID = _flw_material_instancing.y;
_flw_packedMaterialProperties = _flw_material_instancing.z;
FlwInstance i = _flw_unpackInstance();
flw_layoutVertex();
flw_initVertex();
flw_instanceVertex(i);
flw_materialVertex();
flw_contextVertex();
}