More node

This commit is contained in:
mcrcortex
2024-09-22 11:09:25 +10:00
parent b875d5fc25
commit 78d5c224a8
5 changed files with 88 additions and 35 deletions

View File

@@ -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);
}
}
}

View File

@@ -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<SingleNodeRequest> singleRequests = new ExpandingObjectAllocationList<>(SingleNodeRequest[]::new);
private final ExpandingObjectAllocationList<NodeChildRequest> 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

View File

@@ -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;

View File

@@ -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; \
};

View File

@@ -20,15 +20,15 @@ layout(binding = SCENE_UNIFORM_BINDING, std140) uniform SceneUniform {
#import <voxy:lod/hierarchical/node.glsl>
#import <voxy:lod/hierarchical/screenspace.glsl>
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);
}
}