node clean something, its still broken mode
This commit is contained in:
@@ -49,7 +49,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
|
||||
|
||||
//Max sections: ~500k
|
||||
//Max geometry: 1 gb
|
||||
this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<20, (1L<<30)-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();
|
||||
|
||||
@@ -3,8 +3,10 @@ package me.cortex.voxy.client.core.rendering.hierachical;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayFIFOQueue;
|
||||
import me.cortex.voxy.client.core.gl.GlBuffer;
|
||||
import me.cortex.voxy.client.core.gl.shader.AutoBindingShader;
|
||||
import me.cortex.voxy.client.core.gl.shader.PrintfInjector;
|
||||
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.PrintfDebugUtil;
|
||||
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;
|
||||
@@ -30,10 +32,11 @@ public class NodeCleaner {
|
||||
|
||||
private static final int BATCH_SET_SIZE = 2048;
|
||||
|
||||
private final AutoBindingShader sorter = Shader.makeAuto()
|
||||
private final AutoBindingShader sorter = Shader.makeAuto(PrintfDebugUtil.PRINTF_processor)
|
||||
.define("OUTPUT_SIZE", OUTPUT_COUNT)
|
||||
.define("VISIBILITY_BUFFER_BINDING", 1)
|
||||
.define("OUTPUT_BUFFER_BINDING", 2)
|
||||
.define("NODE_DATA_BINDING", 3)
|
||||
.add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/sort_visibility.comp")
|
||||
.compile();
|
||||
|
||||
@@ -75,6 +78,8 @@ public class NodeCleaner {
|
||||
this.sorter
|
||||
.ssbo("VISIBILITY_BUFFER_BINDING", this.visibilityBuffer)
|
||||
.ssbo("OUTPUT_BUFFER_BINDING", this.outputBuffer);
|
||||
|
||||
this.nodeManager.setClearIdCallback(this::clearId);
|
||||
}
|
||||
|
||||
public void clearId(int id) {
|
||||
@@ -90,6 +95,8 @@ public class NodeCleaner {
|
||||
this.outputBuffer.fill(this.nodeManager.maxNodeCount-2);//TODO: maybe dont set to zero??
|
||||
|
||||
this.sorter.bind();
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, nodeDataBuffer.id);
|
||||
|
||||
//TODO: choose whether this is in nodeSpace or section/geometryId space
|
||||
//this.nodeManager.getCurrentMaxNodeId()
|
||||
glDispatchCompute((200_000+127)/128, 1, 1);
|
||||
@@ -105,16 +112,12 @@ public class NodeCleaner {
|
||||
glDispatchCompute(1,1,1);
|
||||
|
||||
DownloadStream.INSTANCE.download(this.outputBuffer, 4*OUTPUT_COUNT, 8*OUTPUT_COUNT, this::onDownload);
|
||||
|
||||
|
||||
this.visibilityBuffer.fill(-1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldCleanGeometry() {
|
||||
// if there is less than 200mb of space, clean
|
||||
return this.nodeManager.getGeometryManager().getRemainingCapacity() < 200_000_000L;
|
||||
return this.nodeManager.getGeometryManager().getRemainingCapacity() < 500_000_000L;
|
||||
}
|
||||
|
||||
private void onDownload(long ptr, long size) {
|
||||
@@ -122,6 +125,10 @@ public class NodeCleaner {
|
||||
for (int i = 0; i < 64; i++) {
|
||||
long pos = Integer.toUnsignedLong(MemoryUtil.memGetInt(ptr + 8 * i))<<32;
|
||||
pos |= Integer.toUnsignedLong(MemoryUtil.memGetInt(ptr + 8 * i + 4));
|
||||
if (pos == 0) {
|
||||
//TODO: investigate how or what this happens
|
||||
continue;
|
||||
}
|
||||
this.nodeManager.removeNodeGeometry(pos);
|
||||
//b.append(", ").append(WorldEngine.pprintPos(pos));//.append(((int)((pos>>32)&0xFFFFFFFFL)));//
|
||||
}
|
||||
@@ -139,7 +146,8 @@ public class NodeCleaner {
|
||||
MemoryUtil.memPutInt(ptr + cnt * 4, this.idsToClear.dequeueInt());
|
||||
}
|
||||
UploadStream.INSTANCE.commit();
|
||||
glUniform1i(0, cnt);
|
||||
glUniform1ui(0, cnt);
|
||||
glUniform1ui(1, this.visibilityId);
|
||||
glDispatchCompute((cnt+127)/128, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,11 @@ public class NodeManager {
|
||||
private final IntArrayList topLevelNodeIds = new IntArrayList();
|
||||
private int activeNodeRequestCount;
|
||||
|
||||
public interface ClearIdCallback {void clearId(int id);}
|
||||
private ClearIdCallback clearIdCallback;
|
||||
public void setClearIdCallback(ClearIdCallback callback) {this.clearIdCallback = callback;}
|
||||
private void clearId(int id) { if (this.clearIdCallback != null) this.clearIdCallback.clearId(id); }
|
||||
|
||||
public NodeManager(int maxNodeCount, AbstractSectionGeometryManager geometryManager, SectionUpdateRouter updateRouter) {
|
||||
if (!MathUtil.isPowerOfTwo(maxNodeCount)) {
|
||||
throw new IllegalArgumentException("Max node count must be a power of 2");
|
||||
@@ -222,7 +227,6 @@ public class NodeManager {
|
||||
}
|
||||
//==================================================================================================================
|
||||
|
||||
//TODO: cleanup this code shitshow and extract common operations to reduce code duplication
|
||||
public void processChildChange(long pos, byte childExistence) {
|
||||
int nodeId = this.activeSectionMap.get(pos);
|
||||
if (nodeId == -1) {
|
||||
@@ -460,13 +464,13 @@ public class NodeManager {
|
||||
Logger.error("UNFINISHED OPERATION TODO: FIXME2");
|
||||
|
||||
//Free geometry and related memory for this node
|
||||
|
||||
this.nodeData.free(nodeId);
|
||||
this.clearId(nodeId);
|
||||
|
||||
//Unwatch geometry
|
||||
if (!this.updateRouter.unwatch(pos, WorldEngine.UPDATE_FLAGS)) {
|
||||
throw new IllegalStateException("Pos was not being watched");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
Logger.error("UNFINISHED OPERATION TODO: FIXME3");
|
||||
@@ -522,6 +526,8 @@ public class NodeManager {
|
||||
this.nodeData.setNodeGeometry(childNodeId, request.getChildMesh(childIdx));
|
||||
//Mark for update
|
||||
this.invalidateNode(childNodeId);
|
||||
this.clearId(childNodeId);//Clear the id
|
||||
|
||||
//Put in map
|
||||
int pid = this.activeSectionMap.put(childPos, childNodeId|NODE_TYPE_LEAF);
|
||||
if ((pid&NODE_TYPE_MSK) != NODE_TYPE_REQUEST) {
|
||||
@@ -780,6 +786,9 @@ public class NodeManager {
|
||||
return;
|
||||
}
|
||||
|
||||
//Reset/clear the id
|
||||
this.clearId(nodeId);
|
||||
|
||||
if (nodeType == NODE_TYPE_LEAF) {
|
||||
//If it is a leaf node, check that the parent has geometry, if it doesnt, request geometry for that parent
|
||||
// if it DOES tho, remove all the children and make the parent a leaf node
|
||||
@@ -791,7 +800,10 @@ public class NodeManager {
|
||||
|
||||
if (WorldEngine.getLevel(pos) == MAX_LOD_LAYERS-1) {
|
||||
//Cannot remove top level nodes
|
||||
Logger.info("Tried cleaning top level node " + WorldEngine.pprintPos(pos));
|
||||
|
||||
//Logger.info("Tried cleaning top level node " + WorldEngine.pprintPos(pos));
|
||||
|
||||
this.removeGeometryInternal(pos, nodeId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -804,15 +816,19 @@ public class NodeManager {
|
||||
if (this.nodeData.getNodeGeometry(pId) == NULL_GEOMETRY_ID) {
|
||||
//If the parent has null geometry we must first fill it before we can remove it
|
||||
|
||||
//Logger.error("TODO: THIS");
|
||||
Logger.error("TODO: THIS");
|
||||
} else {
|
||||
//Else make the parent node a leaf node and remove all the children
|
||||
|
||||
//Logger.error("TODO: THIS 2");
|
||||
Logger.error("TODO: THIS 2");
|
||||
}
|
||||
//this.removeGeometryInternal(pos, nodeId);
|
||||
return;
|
||||
}
|
||||
this.removeGeometryInternal(pos, nodeId);
|
||||
}
|
||||
|
||||
private void removeGeometryInternal(long pos, int nodeId) {
|
||||
int geometryId = this.nodeData.getNodeGeometry(nodeId);
|
||||
if (geometryId != NULL_GEOMETRY_ID && geometryId != EMPTY_GEOMETRY_ID) {
|
||||
//Unwatch geometry updates
|
||||
@@ -826,7 +842,6 @@ public class NodeManager {
|
||||
//this.cleaner
|
||||
}
|
||||
this.invalidateNode(nodeId);
|
||||
|
||||
}
|
||||
|
||||
//==================================================================================================================
|
||||
|
||||
@@ -66,7 +66,7 @@ public final class NodeStore {
|
||||
}
|
||||
}
|
||||
|
||||
private void free(int nodeId) {
|
||||
public void free(int nodeId) {
|
||||
this.free(nodeId, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@ layout(binding = LIST_BUFFER_BINDING, std430) restrict readonly buffer SetListBu
|
||||
};
|
||||
|
||||
layout(location=0) uniform uint count;
|
||||
#define SET_TO uint(-1)
|
||||
layout(location=1) uniform uint setTo;
|
||||
void main() {
|
||||
uint id = gl_GlobalInvocationID.x;
|
||||
if (count <= id) {
|
||||
return;
|
||||
}
|
||||
visiblity[ids[id]] = SET_TO;
|
||||
visiblity[ids[id]] = setTo;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
layout(local_size_x=128, local_size_y=1) in;
|
||||
//256 workgroup
|
||||
|
||||
#import <voxy:lod/hierarchical/node.glsl>
|
||||
|
||||
layout(binding = VISIBILITY_BUFFER_BINDING, std430) restrict readonly buffer VisibilityDataBuffer {
|
||||
uint[] visiblity;
|
||||
@@ -54,5 +55,10 @@ void main() {
|
||||
if (visiblity[minVisIds[OUTPUT_SIZE-1]] <= vis) {
|
||||
return;
|
||||
}
|
||||
UnpackedNode node;
|
||||
unpackNode(node, gl_GlobalInvocationID.x);
|
||||
if (isEmptyMesh(node) || !hasMesh(node)) {
|
||||
return;
|
||||
}
|
||||
bubbleSort(0, gl_GlobalInvocationID.x, vis);
|
||||
}
|
||||
@@ -61,15 +61,14 @@ void enqueueChildren(in UnpackedNode node) {
|
||||
|
||||
void enqueueSelfForRender(in UnpackedNode node) {
|
||||
//printf("render %d@[%d,%d,%d]", node.lodLevel, node.pos.x, node.pos.y, node.pos.z);
|
||||
if ((!isEmptyMesh(node)) && renderQueueIndex < renderQueueMaxSize) {
|
||||
renderQueue[atomicAdd(renderQueueIndex, 1)] = getMesh(node);
|
||||
#ifdef IS_DEBUG
|
||||
debugRenderNodeQueue[atomicAdd(debugRenderNodeQueueIndex, 1)] = node.nodeId;
|
||||
#endif
|
||||
|
||||
//TODO: decide if it should be this node id, or the mesh id
|
||||
// for now do node id... think
|
||||
if (renderQueueIndex < renderQueueMaxSize) {
|
||||
lastRenderFrame[getId(node)] = frameId;
|
||||
if (!isEmptyMesh(node)) {
|
||||
renderQueue[atomicAdd(renderQueueIndex, 1)] = getMesh(node);
|
||||
#ifdef IS_DEBUG
|
||||
debugRenderNodeQueue[atomicAdd(debugRenderNodeQueueIndex, 1)] = node.nodeId;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user