From 78d5c224a878a2e9f5975d64ee794bf1f4c2282e Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Sun, 22 Sep 2024 11:09:25 +1000 Subject: [PATCH] More node --- .../HierarchicalOcclusionTraverser.java | 9 +- .../rendering/hierachical2/NodeManager2.java | 90 ++++++++++++++----- .../voxy/shaders/lod/hierarchical/node.glsl | 8 +- .../voxy/shaders/lod/hierarchical/queue.glsl | 8 +- .../lod/hierarchical/traversal_dev.comp | 8 +- 5 files changed, 88 insertions(+), 35 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/HierarchicalOcclusionTraverser.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/HierarchicalOcclusionTraverser.java index 1c8b45eb..1aa8fdf4 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/HierarchicalOcclusionTraverser.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/HierarchicalOcclusionTraverser.java @@ -240,7 +240,14 @@ public class HierarchicalOcclusionTraverser { System.err.println("Count larger than 'maxRequestCount', overflow captured. Overflowed by " + (count-this.maxRequestCount)); } if (count != 0) { - this.nodeManager.processRequestQueue(count, ptr + 4); + //this.nodeManager.processRequestQueue(count, ptr + 8); + + //It just felt more appropriate putting the loop here + for (int requestIndex = 0; requestIndex < count; requestIndex++) { + long pos = ((long)MemoryUtil.memGetInt(ptr))<<32; ptr += 4; + pos |= Integer.toUnsignedLong(MemoryUtil.memGetInt(ptr)); ptr += 4; + this.nodeManager.processRequest(pos); + } } } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/NodeManager2.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/NodeManager2.java index 9020cb79..5d8c0239 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/NodeManager2.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/NodeManager2.java @@ -28,6 +28,17 @@ public class NodeManager2 { // since for inner node child resize gpu could take N frames to update + private static final int NODE_TYPE_MSK = 0b11<<30; + private static final int NODE_TYPE_LEAF = 0b00<<30; + private static final int NODE_TYPE_INNER = 0b01<<30; + private static final int NODE_TYPE_REQUEST = 0b10<<30; + + private static final int REQUEST_TYPE_SINGLE = 0b0<<29; + private static final int REQUEST_TYPE_CHILD = 0b1<<29; + private static final int REQUEST_TYPE_MSK = 0b1<<29; + + //Single requests are basically _only_ generated by the insertion of top level nodes + private final ExpandingObjectAllocationList singleRequests = new ExpandingObjectAllocationList<>(SingleNodeRequest[]::new); private final ExpandingObjectAllocationList childRequests = new ExpandingObjectAllocationList<>(NodeChildRequest[]::new); private final IntOpenHashSet nodeUpdates = new IntOpenHashSet(); private final AbstractSectionGeometryManager geometryManager; @@ -50,43 +61,74 @@ public class NodeManager2 { } public void insertTopLevelNode(long pos) { - + if (this.activeSectionMap.containsKey(pos)) { + Logger.error("Tried inserting top level pos " + WorldEngine.pprintPos(pos) + " but it was in active map, discarding!"); + return; + } + + var request = new SingleNodeRequest(pos); + int id = this.singleRequests.put(request); + this.updateRouter.watch(pos, WorldEngine.UPDATE_FLAGS); + this.activeSectionMap.put(pos, id|NODE_TYPE_REQUEST|REQUEST_TYPE_SINGLE); } public void removeTopLevelNode(long pos) { - - } - - public void processGeometryResult(BuiltSection sectionResult) { - - } - - //============================================================================================================================================ - public void processRequestQueue(int count, long ptr) { - for (int requestIndex = 0; requestIndex < count; requestIndex++) { - int op = MemoryUtil.memGetInt(ptr + (requestIndex * 4L)); - this.processRequest(op); - } - } - - private void processRequest(int op) { - int node = op & NODE_ID_MSK; - if (!this.nodeData.nodeExists(node)) { - throw new IllegalStateException("Tried processing a node that doesnt exist: " + node); - } - if (this.nodeData.isNodeRequestInFlight(node)) { - Logger.warn("Tried processing a node that already has a request in flight: " + node + " pos: " + WorldEngine.pprintPos(this.nodeData.nodePosition(node))); + int nodeId = this.activeSectionMap.get(pos); + if (nodeId == -1) { + Logger.error("Tried removing top level pos " + WorldEngine.pprintPos(pos) + " but it was not in active map, discarding!"); return; } - this.nodeData.markRequestInFlight(node); + //TODO: assert is top level node + } + + //================================================================================================================== + + public void processGeometryResult(BuiltSection sectionResult) { + long pos = sectionResult.position; + int nodeId = this.activeSectionMap.get(pos); + if (nodeId == -1) { + Logger.error("Got geometry update for pos " + WorldEngine.pprintPos(pos) + " but it was not in active map, discarding!"); + sectionResult.free(); + return; + } + + if ((nodeId&NODE_TYPE_MSK)==NODE_TYPE_REQUEST) { + //For a request + if ((nodeId&REQUEST_TYPE_MSK)==REQUEST_TYPE_SINGLE) { + + } else if ((nodeId&REQUEST_TYPE_MSK)==REQUEST_TYPE_CHILD) { + + } else { + throw new IllegalStateException(); + } + } else if ((nodeId&NODE_TYPE_MSK)==NODE_TYPE_INNER || (nodeId&NODE_TYPE_MSK)==NODE_TYPE_LEAF) { + // Just doing a geometry update + } } + //================================================================================================================== + public void processRequest(long pos) { + int nodeId = this.activeSectionMap.get(pos); + if (nodeId == -1) { + Logger.error("Got request for pos " + WorldEngine.pprintPos(pos) + " but it was not in active map, ignoring!"); + return; + } + + } + + //================================================================================================================== public void processChildChange(long pos, byte childExistence) { + int nodeId = this.activeSectionMap.get(pos); + if (nodeId == -1) { + Logger.error("Got child change for pos " + WorldEngine.pprintPos(pos) + " but it was not in active map, ignoring!"); + return; + } } + //================================================================================================================== public boolean writeChanges(GlBuffer nodeBuffer) { //TODO: use like compute based copy system or something // since microcopies are bad diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/node.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/node.glsl index 372dc798..656d3ef9 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/node.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/node.glsl @@ -16,6 +16,8 @@ layout(binding = NODE_DATA_BINDING, std430) restrict buffer NodeData { struct UnpackedNode { uint nodeId; + uvec2 rawPos; + ivec3 pos; uint lodLevel; @@ -32,7 +34,7 @@ void unpackNode(out UnpackedNode node, uint nodeId) { uvec4 compactedNode = nodes[nodeId]; node.nodeId = nodeId; node.lodLevel = compactedNode.x >> 28; - + node.rawPos = compactedNode.xy; { int y = ((int(compactedNode.x)<<4)>>24); int x = (int(compactedNode.y)<<4)>>8; @@ -84,6 +86,10 @@ uint getChildPtr(in UnpackedNode node) { return node.childPtr; } +uvec2 getRawPos(in UnpackedNode node) { + return node.rawPos; +} + /* uint getTransformIndex(in UnpackedNode node) { return (node.flags >> 5)&31u; diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/queue.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/queue.glsl index a8724617..2b73f3ed 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/queue.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/queue.glsl @@ -49,9 +49,7 @@ void pushNode(uint nodeId) { nodeQueueSink[nodePushIndex++] = nodeId; } - - -#define SIMPLE_QUEUE(name, bindingIndex) layout(binding = bindingIndex, std430) restrict buffer name##Struct { \ - uint name##Index; \ - uint[] name; \ +#define SIMPLE_QUEUE(type, name, bindingIndex) layout(binding = bindingIndex, std430) restrict buffer name##Struct { \ + type name##Index; \ + type##[] name; \ }; \ No newline at end of file diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp index 5a53b72e..4a26eab4 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal_dev.comp @@ -20,15 +20,15 @@ layout(binding = SCENE_UNIFORM_BINDING, std140) uniform SceneUniform { #import #import -SIMPLE_QUEUE(requestQueue, REQUEST_QUEUE_BINDING); -SIMPLE_QUEUE(renderQueue, RENDER_QUEUE_BINDING); +SIMPLE_QUEUE(uvec2, requestQueue, REQUEST_QUEUE_BINDING); +SIMPLE_QUEUE(uint, renderQueue, RENDER_QUEUE_BINDING); void addRequest(inout UnpackedNode node) { printf("Put node decend request"); if (!hasRequested(node)) { - if (requestQueueIndex < requestQueueMaxSize) { + if (requestQueueIndex.x < requestQueueMaxSize) { //Mark node as having a request submitted to prevent duplicate submissions - requestQueue[atomicAdd(requestQueueIndex, 1)] = getId(node); + requestQueue[atomicAdd(requestQueueIndex.x, 1)] = getRawPos(node); markRequested(node); } }