diff --git a/src/main/java/me/cortex/voxy/client/core/gl/GlBuffer.java b/src/main/java/me/cortex/voxy/client/core/gl/GlBuffer.java index 38fcc4d6..2ef05117 100644 --- a/src/main/java/me/cortex/voxy/client/core/gl/GlBuffer.java +++ b/src/main/java/me/cortex/voxy/client/core/gl/GlBuffer.java @@ -53,7 +53,7 @@ public class GlBuffer extends TrackedObject { glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 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; } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java index 4ef7c7ac..656a78fb 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java @@ -49,7 +49,7 @@ public class RenderService, J extends Vi //Max sections: ~500k //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 var router = new SectionUpdateRouter(); @@ -188,7 +188,7 @@ public class RenderService, J extends Vi if (true /* firstInvocationThisFrame */) { DownloadStream.INSTANCE.tick(); - this.nodeCleaner.tick();//Probably do this here?? + this.nodeCleaner.tick(this.traversal.getNodeBuffer());//Probably do this here?? this.sectionUpdateQueue.consume(); this.geometryUpdateQueue.consume(); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/NodeCleaner.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/NodeCleaner.java index e941847c..ed057e65 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/NodeCleaner.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/NodeCleaner.java @@ -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.rendering.util.DownloadStream; import me.cortex.voxy.client.core.rendering.util.UploadStream; +import me.cortex.voxy.common.world.WorldEngine; import org.lwjgl.system.MemoryUtil; 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) // 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") .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() .define("VISIBILITY_BUFFER_BINDING", 0) .define("LIST_BUFFER_BINDING", 1) .add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/batch_visibility_set.comp") .compile(); + 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 IntArrayFIFOQueue idsToClear = new IntArrayFIFOQueue(); @@ -53,6 +66,7 @@ public class NodeCleaner { public NodeCleaner(NodeManager nodeManager) { this.nodeManager = nodeManager; this.visibilityBuffer = new GlBuffer(nodeManager.maxNodeCount*4L).zero(); + this.visibilityBuffer.fill(-1); this.batchClear .ssbo("VISIBILITY_BUFFER_BINDING", this.visibilityBuffer) @@ -67,26 +81,39 @@ public class NodeCleaner { this.idsToClear.enqueue(id); } - public void tick() { + public void tick(GlBuffer nodeDataBuffer) { this.visibilityId++; this.clearIds(); 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(); //TODO: choose whether this is in nodeSpace or section/geometryId space //this.nodeManager.getCurrentMaxNodeId() 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) { StringBuilder b = new StringBuilder(); 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); } @@ -114,5 +141,6 @@ public class NodeCleaner { this.outputBuffer.free(); this.scratchBuffer.free(); this.batchClear.free(); + this.resultTransformer.free(); } } diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/result_transformer.comp b/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/result_transformer.comp new file mode 100644 index 00000000..aedfba09 --- /dev/null +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/result_transformer.comp @@ -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]];// +} \ No newline at end of file