Sorting works

This commit is contained in:
mcrcortex
2025-01-27 07:28:08 +10:00
parent d0e969dcf6
commit 9ded4d4b13
4 changed files with 60 additions and 9 deletions

View File

@@ -53,7 +53,7 @@ public class GlBuffer extends TrackedObject {
glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0);
glClearNamedBufferData(this.id, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, new int[]{data}); glClearNamedBufferData(this.id, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, new int[]{data});
return this; return this;
} }

View File

@@ -49,7 +49,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
//Max sections: ~500k //Max sections: ~500k
//Max geometry: 1 gb //Max geometry: 1 gb
this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<20, (1L<<31)-1024); this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<20, (1L<<32)-1024);
//Do something incredibly hacky, we dont need to keep the reference to this around, so just connect and discard //Do something incredibly hacky, we dont need to keep the reference to this around, so just connect and discard
var router = new SectionUpdateRouter(); var router = new SectionUpdateRouter();
@@ -188,7 +188,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
if (true /* firstInvocationThisFrame */) { if (true /* firstInvocationThisFrame */) {
DownloadStream.INSTANCE.tick(); DownloadStream.INSTANCE.tick();
this.nodeCleaner.tick();//Probably do this here?? this.nodeCleaner.tick(this.traversal.getNodeBuffer());//Probably do this here??
this.sectionUpdateQueue.consume(); this.sectionUpdateQueue.consume();
this.geometryUpdateQueue.consume(); this.geometryUpdateQueue.consume();

View File

@@ -7,10 +7,13 @@ import me.cortex.voxy.client.core.gl.shader.Shader;
import me.cortex.voxy.client.core.gl.shader.ShaderType; import me.cortex.voxy.client.core.gl.shader.ShaderType;
import me.cortex.voxy.client.core.rendering.util.DownloadStream; import me.cortex.voxy.client.core.rendering.util.DownloadStream;
import me.cortex.voxy.client.core.rendering.util.UploadStream; import me.cortex.voxy.client.core.rendering.util.UploadStream;
import me.cortex.voxy.common.world.WorldEngine;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import static org.lwjgl.opengl.GL20.glUniform1i; import static org.lwjgl.opengl.GL20.glUniform1i;
import static org.lwjgl.opengl.GL43C.glDispatchCompute; import static org.lwjgl.opengl.GL30C.glBindBufferRange;
import static org.lwjgl.opengl.GL42C.glMemoryBarrier;
import static org.lwjgl.opengl.GL43C.*;
//Uses compute shaders to compute the last 256 rendered section (64x64 workgroup size maybe) //Uses compute shaders to compute the last 256 rendered section (64x64 workgroup size maybe)
// done via warp level sort, then workgroup sort (shared memory), (/w sorting network) // done via warp level sort, then workgroup sort (shared memory), (/w sorting network)
@@ -34,14 +37,24 @@ public class NodeCleaner {
.add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/sort_visibility.comp") .add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/sort_visibility.comp")
.compile(); .compile();
private final AutoBindingShader resultTransformer = Shader.makeAuto()
.define("OUTPUT_SIZE", OUTPUT_COUNT)
.define("MIN_ID_BUFFER_BINDING", 0)
.define("NODE_BUFFER_BINDING", 1)
.define("OUTPUT_BUFFER_BINDING", 2)
.define("QQQQQQ", 3)
.add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/result_transformer.comp")
.compile();
private final AutoBindingShader batchClear = Shader.makeAuto() private final AutoBindingShader batchClear = Shader.makeAuto()
.define("VISIBILITY_BUFFER_BINDING", 0) .define("VISIBILITY_BUFFER_BINDING", 0)
.define("LIST_BUFFER_BINDING", 1) .define("LIST_BUFFER_BINDING", 1)
.add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/batch_visibility_set.comp") .add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/batch_visibility_set.comp")
.compile(); .compile();
final GlBuffer visibilityBuffer; final GlBuffer visibilityBuffer;
private final GlBuffer outputBuffer = new GlBuffer(OUTPUT_COUNT*4); private final GlBuffer outputBuffer = new GlBuffer(OUTPUT_COUNT*4+OUTPUT_COUNT*8);//Scratch + output
private final GlBuffer scratchBuffer = new GlBuffer(BATCH_SET_SIZE*4);//Scratch buffer for setting ids with private final GlBuffer scratchBuffer = new GlBuffer(BATCH_SET_SIZE*4);//Scratch buffer for setting ids with
private final IntArrayFIFOQueue idsToClear = new IntArrayFIFOQueue(); private final IntArrayFIFOQueue idsToClear = new IntArrayFIFOQueue();
@@ -53,6 +66,7 @@ public class NodeCleaner {
public NodeCleaner(NodeManager nodeManager) { public NodeCleaner(NodeManager nodeManager) {
this.nodeManager = nodeManager; this.nodeManager = nodeManager;
this.visibilityBuffer = new GlBuffer(nodeManager.maxNodeCount*4L).zero(); this.visibilityBuffer = new GlBuffer(nodeManager.maxNodeCount*4L).zero();
this.visibilityBuffer.fill(-1);
this.batchClear this.batchClear
.ssbo("VISIBILITY_BUFFER_BINDING", this.visibilityBuffer) .ssbo("VISIBILITY_BUFFER_BINDING", this.visibilityBuffer)
@@ -67,26 +81,39 @@ public class NodeCleaner {
this.idsToClear.enqueue(id); this.idsToClear.enqueue(id);
} }
public void tick() { public void tick(GlBuffer nodeDataBuffer) {
this.visibilityId++; this.visibilityId++;
this.clearIds(); this.clearIds();
if (false) { if (false) {
this.outputBuffer.zero();//TODO: maybe dont set to zero?? glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
this.outputBuffer.fill(this.nodeManager.maxNodeCount-2);//TODO: maybe dont set to zero??
this.sorter.bind(); this.sorter.bind();
//TODO: choose whether this is in nodeSpace or section/geometryId space //TODO: choose whether this is in nodeSpace or section/geometryId space
//this.nodeManager.getCurrentMaxNodeId() //this.nodeManager.getCurrentMaxNodeId()
glDispatchCompute((200_000+127)/128, 1, 1); glDispatchCompute((200_000+127)/128, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
DownloadStream.INSTANCE.download(this.outputBuffer, this::onDownload); this.resultTransformer.bind();
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, this.outputBuffer.id, 0, 4*OUTPUT_COUNT);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, nodeDataBuffer.id);
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 2, this.outputBuffer.id, 4*OUTPUT_COUNT, 8*OUTPUT_COUNT);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, this.visibilityBuffer.id);
//this.outputBuffer.fill(0);//TODO: maybe dont set to zero??
glDispatchCompute(1,1,1);
DownloadStream.INSTANCE.download(this.outputBuffer, 4*OUTPUT_COUNT, 8*OUTPUT_COUNT, this::onDownload);
} }
} }
private void onDownload(long ptr, long size) { private void onDownload(long ptr, long size) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
b.append(", ").append(MemoryUtil.memGetInt(ptr + 4 * i)); long pos = Integer.toUnsignedLong(MemoryUtil.memGetInt(ptr + 8 * i))<<32;
pos |= Integer.toUnsignedLong(MemoryUtil.memGetInt(ptr + 8 * i + 4));
b.append(", ").append(WorldEngine.pprintPos(pos));//.append(((int)((pos>>32)&0xFFFFFFFFL)));//
} }
System.out.println(b); System.out.println(b);
} }
@@ -114,5 +141,6 @@ public class NodeCleaner {
this.outputBuffer.free(); this.outputBuffer.free();
this.scratchBuffer.free(); this.scratchBuffer.free();
this.batchClear.free(); this.batchClear.free();
this.resultTransformer.free();
} }
} }

View File

@@ -0,0 +1,23 @@
#version 460 core
layout(local_size_x=OUTPUT_SIZE) in;
layout(binding = MIN_ID_BUFFER_BINDING, std430) restrict readonly buffer VisibilityDataBuffer {
uint minVisIds[OUTPUT_SIZE];
};
layout(binding = NODE_BUFFER_BINDING, std430) restrict readonly buffer NodeData {
uvec4[] nodes;
};
layout(binding = OUTPUT_BUFFER_BINDING, std430) restrict writeonly buffer OutputBuffer {
uvec2 outputBuffer[OUTPUT_SIZE];
};
layout(binding = QQQQQQ, std430) restrict buffer QQQ {
uint[] qq;
};
void main() {
outputBuffer[gl_LocalInvocationID.x] = nodes[minVisIds[gl_LocalInvocationID.x]].xy;//Move the position of the node id into the output buffer
//outputBuffer[gl_LocalInvocationID.x].x = qq[minVisIds[gl_LocalInvocationID.x]];//
}