Probably not rendering

- Flesh out two pass pipeline
- Shove everything into one visual type for now
This commit is contained in:
Jozufozu 2024-09-08 11:28:41 -05:00
parent 1edb72ac19
commit b6ed3cefda
7 changed files with 110 additions and 45 deletions

View File

@ -33,7 +33,8 @@ public class IndirectPrograms extends AtomicReferenceCounted {
private static final ResourceLocation SCATTER_SHADER_MAIN = Flywheel.rl("internal/indirect/scatter.glsl");
private static final ResourceLocation DEPTH_REDUCE_SHADER_MAIN = Flywheel.rl("internal/indirect/depth_reduce.glsl");
private static final ResourceLocation READ_VISIBILITY_SHADER_MAIN = Flywheel.rl("internal/indirect/read_visibility.glsl");
public static final List<ResourceLocation> UTIL_SHADERS = List.of(APPLY_SHADER_MAIN, SCATTER_SHADER_MAIN, DEPTH_REDUCE_SHADER_MAIN, READ_VISIBILITY_SHADER_MAIN);
private static final ResourceLocation ZERO_MODELS_SHADER_MAIN = Flywheel.rl("internal/indirect/zero_models.glsl");
public static final List<ResourceLocation> UTIL_SHADERS = List.of(APPLY_SHADER_MAIN, SCATTER_SHADER_MAIN, DEPTH_REDUCE_SHADER_MAIN, READ_VISIBILITY_SHADER_MAIN, ZERO_MODELS_SHADER_MAIN);
private static final Compile<InstanceType<?>> CULL = new Compile<>();
private static final Compile<ResourceLocation> UTIL = new Compile<>();
@ -47,19 +48,13 @@ public class IndirectPrograms extends AtomicReferenceCounted {
private final Map<PipelineProgramKey, GlProgram> pipeline;
private final Map<InstanceType<?>, GlProgram> culling;
private final Map<InstanceType<?>, GlProgram> cullPassTwo;
private final GlProgram apply;
private final GlProgram scatter;
private final GlProgram depthReduce;
private final GlProgram readVisibility;
private final Map<ResourceLocation, GlProgram> utils;
private IndirectPrograms(Map<PipelineProgramKey, GlProgram> pipeline, Map<InstanceType<?>, GlProgram> culling, Map<InstanceType<?>, GlProgram> cullPassTwo, GlProgram apply, GlProgram scatter, GlProgram depthReduce, GlProgram readVisibility) {
private IndirectPrograms(Map<PipelineProgramKey, GlProgram> pipeline, Map<InstanceType<?>, GlProgram> culling, Map<InstanceType<?>, GlProgram> cullPassTwo, Map<ResourceLocation, GlProgram> utils) {
this.pipeline = pipeline;
this.culling = culling;
this.cullPassTwo = cullPassTwo;
this.apply = apply;
this.scatter = scatter;
this.depthReduce = depthReduce;
this.readVisibility = readVisibility;
this.utils = utils;
}
private static List<String> getExtensions(GlslVersion glslVersion) {
@ -110,7 +105,7 @@ public class IndirectPrograms extends AtomicReferenceCounted {
var utils = utilCompiler.compileAndReportErrors(UTIL_SHADERS);
if (pipelineResult != null && pass1Result != null && pass2Result != null && utils != null) {
newInstance = new IndirectPrograms(pipelineResult, pass1Result, pass2Result, utils.get(APPLY_SHADER_MAIN), utils.get(SCATTER_SHADER_MAIN), utils.get(DEPTH_REDUCE_SHADER_MAIN), utils.get(READ_VISIBILITY_SHADER_MAIN));
newInstance = new IndirectPrograms(pipelineResult, pass1Result, pass2Result, utils);
}
} catch (Throwable t) {
FlwPrograms.LOGGER.error("Failed to compile indirect programs", t);
@ -195,19 +190,23 @@ public class IndirectPrograms extends AtomicReferenceCounted {
}
public GlProgram getApplyProgram() {
return apply;
return utils.get(APPLY_SHADER_MAIN);
}
public GlProgram getZeroModelProgram() {
return utils.get(ZERO_MODELS_SHADER_MAIN);
}
public GlProgram getScatterProgram() {
return scatter;
return utils.get(SCATTER_SHADER_MAIN);
}
public GlProgram getDepthReduceProgram() {
return depthReduce;
return utils.get(DEPTH_REDUCE_SHADER_MAIN);
}
public GlProgram getReadVisibilityProgram() {
return readVisibility;
return utils.get(READ_VISIBILITY_SHADER_MAIN);
}
@Override
@ -216,6 +215,7 @@ public class IndirectPrograms extends AtomicReferenceCounted {
.forEach(GlProgram::delete);
culling.values()
.forEach(GlProgram::delete);
apply.delete();
utils.values()
.forEach(GlProgram::delete);
}
}

View File

@ -35,6 +35,7 @@ public final class MaterialRenderState {
setupBackfaceCulling(material.backfaceCulling());
setupPolygonOffset(material.polygonOffset());
setupDepthTest(material.depthTest());
// setupDepthTest(DepthTest.OFF);
setupTransparency(material.transparency());
setupWriteMask(material.writeMask());
}

View File

@ -126,6 +126,10 @@ public class IndirectBuffers {
multiBind(5, 2);
}
public void bindForModelReset() {
multiBind(5, 1);
}
public void bindForDraw() {
multiBind(3, 4);
GlBufferType.DRAW_INDIRECT_BUFFER.bind(draw.handle());

View File

@ -165,6 +165,15 @@ public class IndirectCullingGroup<I extends Instance> {
glDispatchCompute(GlCompat.getComputeGroupCount(indirectDraws.size()), 1, 1);
}
public void dispatchModelReset() {
if (nothingToDo()) {
return;
}
buffers.bindForModelReset();
glDispatchCompute(GlCompat.getComputeGroupCount(instancers.size()), 1, 1);
}
private boolean nothingToDo() {
return indirectDraws.isEmpty() || instanceCountThisFrame == 0;
}

View File

@ -93,7 +93,8 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
}
public void render(VisualType visualType) {
if (!hasVisualType(visualType)) {
// FIXME: Two pass occlusion prefers to render everything at once
if (visualType != VisualType.BLOCK_ENTITY) {
return;
}
@ -105,17 +106,50 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
matrixBuffer.bind();
Uniforms.bindAll();
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
visibilityBuffer.bind();
for (var group1 : cullingGroups.values()) {
group1.dispatchCull();
}
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
dispatchApply();
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
visibilityBuffer.attach();
if (needsBarrier) {
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
needsBarrier = false;
}
submitDraws();
depthPyramid.generate();
programs.getZeroModelProgram()
.bind();
for (var group : cullingGroups.values()) {
group.submit(visualType);
group.dispatchModelReset();
}
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
GlTextureUnit.T0.makeActive();
GlStateManager._bindTexture(depthPyramid.pyramidTextureId);
for (var group1 : cullingGroups.values()) {
group1.dispatchCullPassTwo();
}
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
dispatchApply();
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
submitDraws();
MaterialRenderState.reset();
TextureBinder.resetLightAndOverlay();
@ -123,6 +157,23 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
}
}
private void dispatchApply() {
programs.getApplyProgram()
.bind();
for (var group1 : cullingGroups.values()) {
group1.dispatchApply();
}
}
private void submitDraws() {
for (var group : cullingGroups.values()) {
group.submit(VisualType.BLOCK_ENTITY);
group.submit(VisualType.ENTITY);
group.submit(VisualType.EFFECT);
}
}
@Override
public void flush(LightStorage lightStorage, EnvironmentStorage environmentStorage) {
super.flush(lightStorage, environmentStorage);
@ -159,31 +210,9 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
stagingBuffer.flush();
depthPyramid.generate();
// We could probably save some driver calls here when there are
// actually zero instances, but that feels like a very rare case
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
matrixBuffer.bind();
GlTextureUnit.T0.makeActive();
GlStateManager._bindTexture(depthPyramid.pyramidTextureId);
for (var group : cullingGroups.values()) {
group.dispatchCull();
}
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
programs.getApplyProgram()
.bind();
for (var group : cullingGroups.values()) {
group.dispatchApply();
}
needsBarrier = true;
totalPagesLastFrame = totalPagesThisFrame;

View File

@ -54,7 +54,7 @@ public class VisibilityBuffer {
}
readVisibilityProgram.bind();
GL46.glBindBufferBase(GL46.GL_SHADER_STORAGE_BUFFER, BufferBindings.LAST_FRAME_VISIBILITY, lastFrameVisibility.handle());
bind();
GlTextureUnit.T0.makeActive();
GlStateManager._bindTexture(textureId);
@ -62,6 +62,10 @@ public class VisibilityBuffer {
GL46.glDispatchCompute(MoreMath.ceilingDiv(lastWidth, READ_GROUP_SIZE), MoreMath.ceilingDiv(lastHeight, READ_GROUP_SIZE), 1);
}
public void bind() {
GL46.glBindBufferBase(GL46.GL_SHADER_STORAGE_BUFFER, BufferBindings.LAST_FRAME_VISIBILITY, lastFrameVisibility.handle());
}
public void attach() {
var mainRenderTarget = Minecraft.getInstance()
.getMainRenderTarget();

View File

@ -0,0 +1,18 @@
#include "flywheel:internal/indirect/buffer_bindings.glsl"
#include "flywheel:internal/indirect/model_descriptor.glsl"
layout(local_size_x = _FLW_SUBGROUP_SIZE) in;
layout(std430, binding = _FLW_MODEL_BUFFER_BINDING) restrict writeonly buffer ModelBuffer {
ModelDescriptor models[];
};
void main() {
uint modelIndex = gl_GlobalInvocationID.x;
if (modelIndex >= models.length()) {
return;
}
models[modelIndex].instanceCount = 0;
}