More node
This commit is contained in:
@@ -240,7 +240,14 @@ public class HierarchicalOcclusionTraverser {
|
|||||||
System.err.println("Count larger than 'maxRequestCount', overflow captured. Overflowed by " + (count-this.maxRequestCount));
|
System.err.println("Count larger than 'maxRequestCount', overflow captured. Overflowed by " + (count-this.maxRequestCount));
|
||||||
}
|
}
|
||||||
if (count != 0) {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,17 @@ public class NodeManager2 {
|
|||||||
// since for inner node child resize gpu could take N frames to update
|
// 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 ExpandingObjectAllocationList<NodeChildRequest> childRequests = new ExpandingObjectAllocationList<>(NodeChildRequest[]::new);
|
||||||
private final IntOpenHashSet nodeUpdates = new IntOpenHashSet();
|
private final IntOpenHashSet nodeUpdates = new IntOpenHashSet();
|
||||||
private final AbstractSectionGeometryManager geometryManager;
|
private final AbstractSectionGeometryManager geometryManager;
|
||||||
@@ -50,43 +61,74 @@ public class NodeManager2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void insertTopLevelNode(long pos) {
|
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 removeTopLevelNode(long pos) {
|
||||||
|
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!");
|
||||||
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)));
|
|
||||||
return;
|
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) {
|
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) {
|
public boolean writeChanges(GlBuffer nodeBuffer) {
|
||||||
//TODO: use like compute based copy system or something
|
//TODO: use like compute based copy system or something
|
||||||
// since microcopies are bad
|
// since microcopies are bad
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ layout(binding = NODE_DATA_BINDING, std430) restrict buffer NodeData {
|
|||||||
struct UnpackedNode {
|
struct UnpackedNode {
|
||||||
uint nodeId;
|
uint nodeId;
|
||||||
|
|
||||||
|
uvec2 rawPos;
|
||||||
|
|
||||||
ivec3 pos;
|
ivec3 pos;
|
||||||
uint lodLevel;
|
uint lodLevel;
|
||||||
|
|
||||||
@@ -32,7 +34,7 @@ void unpackNode(out UnpackedNode node, uint nodeId) {
|
|||||||
uvec4 compactedNode = nodes[nodeId];
|
uvec4 compactedNode = nodes[nodeId];
|
||||||
node.nodeId = nodeId;
|
node.nodeId = nodeId;
|
||||||
node.lodLevel = compactedNode.x >> 28;
|
node.lodLevel = compactedNode.x >> 28;
|
||||||
|
node.rawPos = compactedNode.xy;
|
||||||
{
|
{
|
||||||
int y = ((int(compactedNode.x)<<4)>>24);
|
int y = ((int(compactedNode.x)<<4)>>24);
|
||||||
int x = (int(compactedNode.y)<<4)>>8;
|
int x = (int(compactedNode.y)<<4)>>8;
|
||||||
@@ -84,6 +86,10 @@ uint getChildPtr(in UnpackedNode node) {
|
|||||||
return node.childPtr;
|
return node.childPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uvec2 getRawPos(in UnpackedNode node) {
|
||||||
|
return node.rawPos;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
uint getTransformIndex(in UnpackedNode node) {
|
uint getTransformIndex(in UnpackedNode node) {
|
||||||
return (node.flags >> 5)&31u;
|
return (node.flags >> 5)&31u;
|
||||||
|
|||||||
@@ -49,9 +49,7 @@ void pushNode(uint nodeId) {
|
|||||||
nodeQueueSink[nodePushIndex++] = nodeId;
|
nodeQueueSink[nodePushIndex++] = nodeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SIMPLE_QUEUE(type, name, bindingIndex) layout(binding = bindingIndex, std430) restrict buffer name##Struct { \
|
||||||
|
type name##Index; \
|
||||||
#define SIMPLE_QUEUE(name, bindingIndex) layout(binding = bindingIndex, std430) restrict buffer name##Struct { \
|
type##[] name; \
|
||||||
uint name##Index; \
|
|
||||||
uint[] name; \
|
|
||||||
};
|
};
|
||||||
@@ -20,15 +20,15 @@ layout(binding = SCENE_UNIFORM_BINDING, std140) uniform SceneUniform {
|
|||||||
#import <voxy:lod/hierarchical/node.glsl>
|
#import <voxy:lod/hierarchical/node.glsl>
|
||||||
#import <voxy:lod/hierarchical/screenspace.glsl>
|
#import <voxy:lod/hierarchical/screenspace.glsl>
|
||||||
|
|
||||||
SIMPLE_QUEUE(requestQueue, REQUEST_QUEUE_BINDING);
|
SIMPLE_QUEUE(uvec2, requestQueue, REQUEST_QUEUE_BINDING);
|
||||||
SIMPLE_QUEUE(renderQueue, RENDER_QUEUE_BINDING);
|
SIMPLE_QUEUE(uint, renderQueue, RENDER_QUEUE_BINDING);
|
||||||
|
|
||||||
void addRequest(inout UnpackedNode node) {
|
void addRequest(inout UnpackedNode node) {
|
||||||
printf("Put node decend request");
|
printf("Put node decend request");
|
||||||
if (!hasRequested(node)) {
|
if (!hasRequested(node)) {
|
||||||
if (requestQueueIndex < requestQueueMaxSize) {
|
if (requestQueueIndex.x < requestQueueMaxSize) {
|
||||||
//Mark node as having a request submitted to prevent duplicate submissions
|
//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);
|
markRequested(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user