Merge branch 'mc_1215' into mc_1216
This commit is contained in:
@@ -48,9 +48,10 @@ public class VoxyRenderSystem {
|
|||||||
//Keep the world loaded, NOTE: this is done FIRST, to keep and ensure that even if the rest of loading takes more
|
//Keep the world loaded, NOTE: this is done FIRST, to keep and ensure that even if the rest of loading takes more
|
||||||
// than timeout, we keep the world acquired
|
// than timeout, we keep the world acquired
|
||||||
world.acquireRef();
|
world.acquireRef();
|
||||||
|
try {
|
||||||
//wait for opengl to be finished, this should hopefully ensure all memory allocations are free
|
//wait for opengl to be finished, this should hopefully ensure all memory allocations are free
|
||||||
glFinish();glFinish();
|
glFinish();
|
||||||
|
glFinish();
|
||||||
|
|
||||||
//Trigger the shared index buffer loading
|
//Trigger the shared index buffer loading
|
||||||
SharedIndexBuffer.INSTANCE.id();
|
SharedIndexBuffer.INSTANCE.id();
|
||||||
@@ -59,8 +60,8 @@ public class VoxyRenderSystem {
|
|||||||
this.worldIn = world;
|
this.worldIn = world;
|
||||||
this.renderer = new RenderService(world, threadPool);
|
this.renderer = new RenderService(world, threadPool);
|
||||||
this.postProcessing = new PostProcessing();
|
this.postProcessing = new PostProcessing();
|
||||||
int minSec = MinecraftClient.getInstance().world.getBottomSectionCoord()>>5;
|
int minSec = MinecraftClient.getInstance().world.getBottomSectionCoord() >> 5;
|
||||||
int maxSec = (MinecraftClient.getInstance().world.getTopSectionCoord()-1)>>5;
|
int maxSec = (MinecraftClient.getInstance().world.getTopSectionCoord() - 1) >> 5;
|
||||||
|
|
||||||
//Do some very cheeky stuff for MiB
|
//Do some very cheeky stuff for MiB
|
||||||
if (false) {
|
if (false) {
|
||||||
@@ -77,6 +78,10 @@ public class VoxyRenderSystem {
|
|||||||
this.renderDistanceTracker.setRenderDistance(VoxyConfig.CONFIG.sectionRenderDistance);
|
this.renderDistanceTracker.setRenderDistance(VoxyConfig.CONFIG.sectionRenderDistance);
|
||||||
|
|
||||||
this.chunkBoundRenderer = new ChunkBoundRenderer();
|
this.chunkBoundRenderer = new ChunkBoundRenderer();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
world.releaseRef();//If something goes wrong, we must release the world first
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRenderDistance(int renderDistance) {
|
public void setRenderDistance(int renderDistance) {
|
||||||
@@ -84,40 +89,6 @@ public class VoxyRenderSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//private static final ModelTextureBakery mtb = new ModelTextureBakery(16, 16);
|
|
||||||
//private static final RawDownloadStream downstream = new RawDownloadStream(1<<20);
|
|
||||||
public void renderSetup(Frustum frustum, Camera camera) {
|
|
||||||
TimingStatistics.resetSamplers();
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (false) {
|
|
||||||
int allocation = downstream.download(2 * 4 * 6 * 16 * 16, ptr -> {
|
|
||||||
ColourDepthTextureData[] textureData = new ColourDepthTextureData[6];
|
|
||||||
final int FACE_SIZE = 16 * 16;
|
|
||||||
for (int face = 0; face < 6; face++) {
|
|
||||||
long faceDataPtr = ptr + (FACE_SIZE * 4) * face * 2;
|
|
||||||
int[] colour = new int[FACE_SIZE];
|
|
||||||
int[] depth = new int[FACE_SIZE];
|
|
||||||
|
|
||||||
//Copy out colour
|
|
||||||
for (int i = 0; i < FACE_SIZE; i++) {
|
|
||||||
//De-interpolate results
|
|
||||||
colour[i] = MemoryUtil.memGetInt(faceDataPtr + (i * 4 * 2));
|
|
||||||
depth[i] = MemoryUtil.memGetInt(faceDataPtr + (i * 4 * 2) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
textureData[face] = new ColourDepthTextureData(colour, depth, 16, 16);
|
|
||||||
}
|
|
||||||
if (textureData[0].colour()[0] == 0) {
|
|
||||||
int a = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mtb.renderFacesToStream(Blocks.AIR.getDefaultState(), 123456, false, downstream.getBufferId(), allocation);
|
|
||||||
downstream.submit();
|
|
||||||
downstream.tick();
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
private void autoBalanceSubDivSize() {
|
private void autoBalanceSubDivSize() {
|
||||||
//only increase quality while there are very few mesh queues, this stops,
|
//only increase quality while there are very few mesh queues, this stops,
|
||||||
// e.g. while flying and is rendering alot of low quality chunks
|
// e.g. while flying and is rendering alot of low quality chunks
|
||||||
@@ -160,6 +131,9 @@ public class VoxyRenderSystem {
|
|||||||
if (IrisUtil.irisShadowActive()) {
|
if (IrisUtil.irisShadowActive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
TimingStatistics.resetSamplers();
|
||||||
|
|
||||||
|
|
||||||
//Do some very cheeky stuff for MiB
|
//Do some very cheeky stuff for MiB
|
||||||
if (false) {
|
if (false) {
|
||||||
int sector = (((int)Math.floor(cameraX)>>4)+512)>>10;
|
int sector = (((int)Math.floor(cameraX)>>4)+512)>>10;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
|
|
||||||
geometryCapacity = Math.min(geometryCapacity, limit);
|
geometryCapacity = Math.min(geometryCapacity, limit);
|
||||||
}
|
}
|
||||||
//geometryCapacity = 1<<24;
|
//geometryCapacity = 1<<28;
|
||||||
//geometryCapacity = 1<<30;//1GB test
|
//geometryCapacity = 1<<30;//1GB test
|
||||||
return geometryCapacity;
|
return geometryCapacity;
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
this.nodeManager = new AsyncNodeManager(1<<21, this.geometryData, this.renderGen);
|
this.nodeManager = new AsyncNodeManager(1<<21, this.geometryData, this.renderGen);
|
||||||
this.nodeCleaner = new NodeCleaner(this.nodeManager);
|
this.nodeCleaner = new NodeCleaner(this.nodeManager);
|
||||||
|
|
||||||
this.traversal = new HierarchicalOcclusionTraverser(this.nodeManager, this.nodeCleaner);
|
this.traversal = new HierarchicalOcclusionTraverser(this.nodeManager, this.nodeCleaner, this.renderGen);
|
||||||
|
|
||||||
world.setDirtyCallback(this.nodeManager::worldEvent);
|
world.setDirtyCallback(this.nodeManager::worldEvent);
|
||||||
|
|
||||||
@@ -106,6 +106,18 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
this.modelService.tick(budget);
|
this.modelService.tick(budget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean frexStillHasWork() {
|
||||||
|
if (!VoxyClient.isFrexActive()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//If frex is running we must tick everything to ensure correctness
|
||||||
|
UploadStream.INSTANCE.tick();
|
||||||
|
//Done here as is allows less gl state resetup
|
||||||
|
this.modelService.tick(100_000_000);
|
||||||
|
glFinish();
|
||||||
|
return this.nodeManager.hasWork() || this.renderGen.getTaskCount()!=0 || !this.modelService.areQueuesEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public void renderFarAwayOpaque(J viewport, GlTexture depthBoundTexture) {
|
public void renderFarAwayOpaque(J viewport, GlTexture depthBoundTexture) {
|
||||||
//LightMapHelper.tickLightmap();
|
//LightMapHelper.tickLightmap();
|
||||||
|
|
||||||
@@ -121,6 +133,13 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
this.sectionRenderer.renderOpaque(viewport, depthBoundTexture);
|
this.sectionRenderer.renderOpaque(viewport, depthBoundTexture);
|
||||||
TimingStatistics.G.stop();
|
TimingStatistics.G.stop();
|
||||||
|
|
||||||
|
{
|
||||||
|
int depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||||
|
|
||||||
|
//Compute the mip chain
|
||||||
|
viewport.hiZBuffer.buildMipChain(depthBuffer, viewport.width, viewport.height);
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
//NOTE: need to do the upload and download tick here, after the section renderer renders the world, to ensure "stable"
|
//NOTE: need to do the upload and download tick here, after the section renderer renders the world, to ensure "stable"
|
||||||
// sections
|
// sections
|
||||||
@@ -157,23 +176,11 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
|
|
||||||
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT);
|
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT);
|
||||||
|
|
||||||
int depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
|
||||||
//if (depthBuffer == 0) {
|
|
||||||
// depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
|
||||||
//}
|
|
||||||
|
|
||||||
TimingStatistics.I.start();
|
TimingStatistics.I.start();
|
||||||
this.traversal.doTraversal(viewport, depthBuffer);
|
this.traversal.doTraversal(viewport);
|
||||||
TimingStatistics.I.stop();
|
TimingStatistics.I.stop();
|
||||||
|
|
||||||
|
} while (this.frexStillHasWork());
|
||||||
if (VoxyClient.isFrexActive()) {//If frex is running we must tick everything to ensure correctness
|
|
||||||
UploadStream.INSTANCE.tick();
|
|
||||||
//Done here as is allows less gl state resetup
|
|
||||||
this.tickModelService(100_000_000);
|
|
||||||
glFinish();
|
|
||||||
}
|
|
||||||
} while (VoxyClient.isFrexActive() && (this.nodeManager.hasWork() || this.renderGen.getTaskCount()!=0 || !this.modelService.areQueuesEmpty()));
|
|
||||||
|
|
||||||
|
|
||||||
TimingStatistics.H.start();
|
TimingStatistics.H.start();
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ public class AsyncNodeManager {
|
|||||||
|
|
||||||
private void run() {
|
private void run() {
|
||||||
if (this.workCounter.get() <= 0) {
|
if (this.workCounter.get() <= 0) {
|
||||||
|
//TODO: here, instead of parking, we can do more work on other sub-tasks such as filtering the mesh build queue
|
||||||
LockSupport.park();
|
LockSupport.park();
|
||||||
if (this.workCounter.get() <= 0 || !this.running) {//No work
|
if (this.workCounter.get() <= 0 || !this.running) {//No work
|
||||||
return;
|
return;
|
||||||
@@ -753,7 +754,7 @@ public class AsyncNodeManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasWork() {
|
public boolean hasWork() {
|
||||||
return this.workCounter.get()!=0 && RESULT_HANDLE.get(this) != null;
|
return this.workCounter.get()!=0 || RESULT_HANDLE.get(this) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void worldEvent(WorldSection section, int flags) {
|
public void worldEvent(WorldSection section, int flags) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ 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.AutoBindingShader;
|
||||||
import me.cortex.voxy.client.core.gl.shader.Shader;
|
import me.cortex.voxy.client.core.gl.shader.Shader;
|
||||||
import me.cortex.voxy.client.core.gl.shader.ShaderType;
|
import me.cortex.voxy.client.core.gl.shader.ShaderType;
|
||||||
|
import me.cortex.voxy.client.core.rendering.building.RenderGenerationService;
|
||||||
import me.cortex.voxy.client.core.rendering.util.PrintfDebugUtil;
|
import me.cortex.voxy.client.core.rendering.util.PrintfDebugUtil;
|
||||||
import me.cortex.voxy.client.core.rendering.util.HiZBuffer;
|
import me.cortex.voxy.client.core.rendering.util.HiZBuffer;
|
||||||
import me.cortex.voxy.client.core.rendering.Viewport;
|
import me.cortex.voxy.client.core.rendering.Viewport;
|
||||||
@@ -30,7 +31,7 @@ import static org.lwjgl.opengl.GL45.*;
|
|||||||
public class HierarchicalOcclusionTraverser {
|
public class HierarchicalOcclusionTraverser {
|
||||||
public static final boolean HIERARCHICAL_SHADER_DEBUG = System.getProperty("voxy.hierarchicalShaderDebug", "false").equals("true");
|
public static final boolean HIERARCHICAL_SHADER_DEBUG = System.getProperty("voxy.hierarchicalShaderDebug", "false").equals("true");
|
||||||
|
|
||||||
public static final int REQUEST_QUEUE_SIZE = 50;
|
public static final int MAX_REQUEST_QUEUE_SIZE = 50;
|
||||||
public static final int MAX_QUEUE_SIZE = 200_000;
|
public static final int MAX_QUEUE_SIZE = 200_000;
|
||||||
|
|
||||||
|
|
||||||
@@ -39,6 +40,7 @@ public class HierarchicalOcclusionTraverser {
|
|||||||
|
|
||||||
private final AsyncNodeManager nodeManager;
|
private final AsyncNodeManager nodeManager;
|
||||||
private final NodeCleaner nodeCleaner;
|
private final NodeCleaner nodeCleaner;
|
||||||
|
private final RenderGenerationService meshGen;
|
||||||
|
|
||||||
private final GlBuffer requestBuffer;
|
private final GlBuffer requestBuffer;
|
||||||
|
|
||||||
@@ -73,7 +75,7 @@ public class HierarchicalOcclusionTraverser {
|
|||||||
.defineIf("DEBUG", HIERARCHICAL_SHADER_DEBUG)
|
.defineIf("DEBUG", HIERARCHICAL_SHADER_DEBUG)
|
||||||
.define("MAX_ITERATIONS", MAX_ITERATIONS)
|
.define("MAX_ITERATIONS", MAX_ITERATIONS)
|
||||||
.define("LOCAL_SIZE_BITS", LOCAL_WORK_SIZE_BITS)
|
.define("LOCAL_SIZE_BITS", LOCAL_WORK_SIZE_BITS)
|
||||||
.define("REQUEST_QUEUE_SIZE", REQUEST_QUEUE_SIZE)
|
.define("MAX_REQUEST_QUEUE_SIZE", MAX_REQUEST_QUEUE_SIZE)
|
||||||
|
|
||||||
.define("HIZ_BINDING", 0)
|
.define("HIZ_BINDING", 0)
|
||||||
|
|
||||||
@@ -96,19 +98,18 @@ public class HierarchicalOcclusionTraverser {
|
|||||||
.compile();
|
.compile();
|
||||||
|
|
||||||
|
|
||||||
public HierarchicalOcclusionTraverser(AsyncNodeManager nodeManager, NodeCleaner nodeCleaner) {
|
public HierarchicalOcclusionTraverser(AsyncNodeManager nodeManager, NodeCleaner nodeCleaner, RenderGenerationService meshGen) {
|
||||||
this.nodeCleaner = nodeCleaner;
|
this.nodeCleaner = nodeCleaner;
|
||||||
this.nodeManager = nodeManager;
|
this.nodeManager = nodeManager;
|
||||||
this.requestBuffer = new GlBuffer(REQUEST_QUEUE_SIZE*8L+8).zero();
|
this.meshGen = meshGen;
|
||||||
|
this.requestBuffer = new GlBuffer(MAX_REQUEST_QUEUE_SIZE*8L+8).zero();
|
||||||
this.nodeBuffer = new GlBuffer(nodeManager.maxNodeCount*16L).fill(-1);
|
this.nodeBuffer = new GlBuffer(nodeManager.maxNodeCount*16L).fill(-1);
|
||||||
|
|
||||||
|
|
||||||
glSamplerParameteri(this.hizSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
glSamplerParameteri(this.hizSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||||
glSamplerParameteri(this.hizSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glSamplerParameteri(this.hizSampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glSamplerParameteri(this.hizSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(this.hizSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glSamplerParameteri(this.hizSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(this.hizSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glSamplerParameteri(this.hizSampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
|
||||||
glSamplerParameteri(this.hizSampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
|
||||||
|
|
||||||
this.traversal
|
this.traversal
|
||||||
.ubo("SCENE_UNIFORM_BINDING", this.uniformBuffer)
|
.ubo("SCENE_UNIFORM_BINDING", this.uniformBuffer)
|
||||||
@@ -175,23 +176,31 @@ public class HierarchicalOcclusionTraverser {
|
|||||||
|
|
||||||
viewport.section.getToAddress(ptr); ptr += 4*3;
|
viewport.section.getToAddress(ptr); ptr += 4*3;
|
||||||
|
|
||||||
MemoryUtil.memPutFloat(ptr, viewport.width); ptr += 4;
|
//MemoryUtil.memPutFloat(ptr, viewport.width); ptr += 4;
|
||||||
|
MemoryUtil.memPutInt(ptr, viewport.hiZBuffer.getPackedLevels()); ptr += 4;
|
||||||
|
|
||||||
viewport.innerTranslation.getToAddress(ptr); ptr += 4*3;
|
viewport.innerTranslation.getToAddress(ptr); ptr += 4*3;
|
||||||
|
|
||||||
MemoryUtil.memPutFloat(ptr, viewport.height); ptr += 4;
|
//MemoryUtil.memPutFloat(ptr, viewport.height); ptr += 4;
|
||||||
|
|
||||||
setFrustum(viewport, ptr); ptr += 4*4*6;
|
|
||||||
|
|
||||||
MemoryUtil.memPutInt(ptr, (int) (viewport.getRenderList().size()/4-1)); ptr += 4;
|
|
||||||
|
|
||||||
|
|
||||||
final float screenspaceAreaDecreasingSize = VoxyConfig.CONFIG.subDivisionSize*VoxyConfig.CONFIG.subDivisionSize;
|
final float screenspaceAreaDecreasingSize = VoxyConfig.CONFIG.subDivisionSize*VoxyConfig.CONFIG.subDivisionSize;
|
||||||
//Screen space size for descending
|
//Screen space size for descending
|
||||||
MemoryUtil.memPutFloat(ptr, (float) (screenspaceAreaDecreasingSize) /(viewport.width*viewport.height)); ptr += 4;
|
MemoryUtil.memPutFloat(ptr, (float) (screenspaceAreaDecreasingSize) /(viewport.width*viewport.height)); ptr += 4;
|
||||||
|
|
||||||
|
setFrustum(viewport, ptr); ptr += 4*4*6;
|
||||||
|
|
||||||
|
MemoryUtil.memPutInt(ptr, (int) (viewport.getRenderList().size()/4-1)); ptr += 4;
|
||||||
|
|
||||||
//VisibilityId
|
//VisibilityId
|
||||||
MemoryUtil.memPutInt(ptr, this.nodeCleaner.visibilityId); ptr += 4;
|
MemoryUtil.memPutInt(ptr, this.nodeCleaner.visibilityId); ptr += 4;
|
||||||
|
|
||||||
|
{
|
||||||
|
final double TARGET_COUNT = 4000;//TODO: make this configurable, or at least dynamically computed based on throughput rate of mesh gen
|
||||||
|
double iFillness = Math.max(0, (TARGET_COUNT - this.meshGen.getTaskCount()) / TARGET_COUNT);
|
||||||
|
iFillness = Math.pow(iFillness, 2);
|
||||||
|
final int requestSize = (int) Math.ceil(iFillness * MAX_REQUEST_QUEUE_SIZE);
|
||||||
|
MemoryUtil.memPutInt(ptr, Math.max(0, Math.min(MAX_REQUEST_QUEUE_SIZE, requestSize)));ptr += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindings(Viewport<?> viewport) {
|
private void bindings(Viewport<?> viewport) {
|
||||||
@@ -203,10 +212,7 @@ public class HierarchicalOcclusionTraverser {
|
|||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, RENDER_QUEUE_BINDING, viewport.getRenderList().id);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, RENDER_QUEUE_BINDING, viewport.getRenderList().id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doTraversal(Viewport<?> viewport, int depthBuffer) {
|
public void doTraversal(Viewport<?> viewport) {
|
||||||
//Compute the mip chain
|
|
||||||
viewport.hiZBuffer.buildMipChain(depthBuffer, viewport.width, viewport.height);
|
|
||||||
|
|
||||||
this.uploadUniform(viewport);
|
this.uploadUniform(viewport);
|
||||||
//UploadStream.INSTANCE.commit(); //Done inside traversal
|
//UploadStream.INSTANCE.commit(); //Done inside traversal
|
||||||
|
|
||||||
|
|||||||
@@ -1213,7 +1213,8 @@ public class NodeManager {
|
|||||||
|
|
||||||
if (!this.nodeData.isNodeGeometryInFlight(nodeId)) {
|
if (!this.nodeData.isNodeGeometryInFlight(nodeId)) {
|
||||||
if (!this.watcher.watch(pos, WorldEngine.UPDATE_TYPE_BLOCK_BIT)) {
|
if (!this.watcher.watch(pos, WorldEngine.UPDATE_TYPE_BLOCK_BIT)) {
|
||||||
Logger.info("Node: " + nodeId + " at pos: " + WorldEngine.pprintPos(pos) + " got update request, but geometry was already being watched");
|
//Logger.info("Node: " + nodeId + " at pos: " + WorldEngine.pprintPos(pos) + " got update request, but geometry was already being watched");
|
||||||
|
this.invalidateNode(nodeId);//Who knows why but just invalidate the data just to keep in sync
|
||||||
} else {
|
} else {
|
||||||
this.nodeData.markNodeGeometryInFlight(nodeId);
|
this.nodeData.markNodeGeometryInFlight(nodeId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ public class MDICSectionRenderer extends AbstractSectionRenderer<MDICViewport, B
|
|||||||
glBindVertexArray(RenderService.STATIC_VAO);//Needs to be before binding
|
glBindVertexArray(RenderService.STATIC_VAO);//Needs to be before binding
|
||||||
this.bindRenderingBuffers(viewport, depthBoundTexture);
|
this.bindRenderingBuffers(viewport, depthBoundTexture);
|
||||||
|
|
||||||
|
glMemoryBarrier(GL_COMMAND_BARRIER_BIT|GL_SHADER_STORAGE_BARRIER_BIT);//Barrier everything is needed
|
||||||
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
|
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
|
||||||
glMultiDrawElementsIndirectCountARB(GL_TRIANGLES, GL_UNSIGNED_SHORT, TRANSLUCENT_OFFSET*5*4, 4*4, Math.min(this.geometryManager.getSectionCount(), 100_000), 0);
|
glMultiDrawElementsIndirectCountARB(GL_TRIANGLES, GL_UNSIGNED_SHORT, TRANSLUCENT_OFFSET*5*4, 4*4, Math.min(this.geometryManager.getSectionCount(), 100_000), 0);
|
||||||
|
|
||||||
|
|||||||
@@ -69,12 +69,12 @@ public class HiZBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void buildMipChain(int srcDepthTex, int width, int height) {
|
public void buildMipChain(int srcDepthTex, int width, int height) {
|
||||||
if (this.width != width || this.height != height) {
|
if (this.width != Integer.highestOneBit(width) || this.height != Integer.highestOneBit(height)) {
|
||||||
if (this.texture != null) {
|
if (this.texture != null) {
|
||||||
this.texture.free();
|
this.texture.free();
|
||||||
this.texture = null;
|
this.texture = null;
|
||||||
}
|
}
|
||||||
this.alloc(width, height);
|
this.alloc(Integer.highestOneBit(width), Integer.highestOneBit(height));
|
||||||
}
|
}
|
||||||
glBindVertexArray(RenderService.STATIC_VAO);
|
glBindVertexArray(RenderService.STATIC_VAO);
|
||||||
int boundFB = GL11.glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING);
|
int boundFB = GL11.glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING);
|
||||||
@@ -86,26 +86,22 @@ public class HiZBuffer {
|
|||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
|
||||||
//System.err.println("SRC: " + GlTexture.getRawTextureType(srcDepthTex) + " DST: " + this.texture.id);
|
glBindTextureUnit(0, srcDepthTex);
|
||||||
glCopyImageSubData(srcDepthTex, GL_TEXTURE_2D, 0,0,0,0,
|
|
||||||
this.texture.id, GL_TEXTURE_2D, 0,0,0,0,
|
|
||||||
width, height, 1);
|
|
||||||
|
|
||||||
|
|
||||||
glBindTextureUnit(0, this.texture.id);
|
|
||||||
glBindSampler(0, this.sampler);
|
glBindSampler(0, this.sampler);
|
||||||
glUniform1i(0, 0);
|
glUniform1i(0, 0);
|
||||||
int cw = this.width;
|
int cw = this.width;
|
||||||
int ch = this.height;
|
int ch = this.height;
|
||||||
glViewport(0, 0, cw, ch);
|
for (int i = 0; i < this.levels; i++) {
|
||||||
for (int i = 0; i < this.levels-1; i++) {
|
this.fb.bind(GL_DEPTH_ATTACHMENT, this.texture, i);
|
||||||
glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, i);
|
glViewport(0, 0, cw, ch); cw = Math.max(cw/2, 1); ch = Math.max(ch/2, 1);
|
||||||
glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, i);
|
|
||||||
this.fb.bind(GL_DEPTH_ATTACHMENT, this.texture, i+1);
|
|
||||||
cw = Math.max(cw/2, 1); ch = Math.max(ch/2, 1); glViewport(0, 0, cw, ch);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
glTextureBarrier();
|
glTextureBarrier();
|
||||||
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT|GL_TEXTURE_FETCH_BARRIER_BIT);
|
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT|GL_TEXTURE_FETCH_BARRIER_BIT);
|
||||||
|
glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, i);
|
||||||
|
glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, i);
|
||||||
|
if (i==0) {
|
||||||
|
glBindTextureUnit(0, this.texture.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, 0);
|
glTextureParameteri(this.texture.id, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, 1000);//TODO: CHECK IF ITS -1 or -0
|
glTextureParameteri(this.texture.id, GL_TEXTURE_MAX_LEVEL, 1000);//TODO: CHECK IF ITS -1 or -0
|
||||||
@@ -130,4 +126,8 @@ public class HiZBuffer {
|
|||||||
public int getHizTextureId() {
|
public int getHizTextureId() {
|
||||||
return this.texture.id;
|
return this.texture.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPackedLevels() {
|
||||||
|
return ((Integer.numberOfTrailingZeros(this.width))<<16)|(Integer.numberOfTrailingZeros(this.height));//+1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,6 @@ public abstract class MixinWorldRenderer implements IGetVoxyRenderSystem {
|
|||||||
@Shadow private @Nullable ClientWorld world;
|
@Shadow private @Nullable ClientWorld world;
|
||||||
@Unique private VoxyRenderSystem renderer;
|
@Unique private VoxyRenderSystem renderer;
|
||||||
|
|
||||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;setupTerrain(Lnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/Frustum;ZZ)V", shift = At.Shift.AFTER))
|
|
||||||
private void injectSetup(ObjectAllocator allocator, RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, Matrix4f positionMatrix, Matrix4f projectionMatrix, CallbackInfo ci) {
|
|
||||||
if (this.renderer != null) {
|
|
||||||
this.renderer.renderSetup(this.frustum, camera);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxyRenderSystem getVoxyRenderSystem() {
|
public VoxyRenderSystem getVoxyRenderSystem() {
|
||||||
return this.renderer;
|
return this.renderer;
|
||||||
|
|||||||
@@ -14,6 +14,30 @@ public class Logger {
|
|||||||
public static boolean SHUTUP = false;
|
public static boolean SHUTUP = false;
|
||||||
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger("Voxy");
|
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger("Voxy");
|
||||||
|
|
||||||
|
|
||||||
|
private static String callClsName() {
|
||||||
|
String className = "";
|
||||||
|
if (INSERT_CLASS) {
|
||||||
|
var stackEntry = new Throwable().getStackTrace()[2];
|
||||||
|
className = stackEntry.getClassName();
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
var parts = className.split("\\.");
|
||||||
|
for (int i = 0; i < parts.length; i++) {
|
||||||
|
var part = parts[i];
|
||||||
|
if (i < parts.length-1) {//-2
|
||||||
|
builder.append(part.charAt(0)).append(part.charAt(part.length()-1));
|
||||||
|
} else {
|
||||||
|
builder.append(part);
|
||||||
|
}
|
||||||
|
if (i!=parts.length-1) {
|
||||||
|
builder.append(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
className = builder.toString();
|
||||||
|
}
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
public static void error(Object... args) {
|
public static void error(Object... args) {
|
||||||
if (SHUTUP) {
|
if (SHUTUP) {
|
||||||
return;
|
return;
|
||||||
@@ -24,8 +48,8 @@ public class Logger {
|
|||||||
throwable = (Throwable) i;
|
throwable = (Throwable) i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stackEntry = new Throwable().getStackTrace()[1];
|
|
||||||
String error = (INSERT_CLASS?("["+stackEntry.getClassName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" "));
|
String error = (INSERT_CLASS?("["+callClsName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" "));
|
||||||
LOGGER.error(error, throwable);
|
LOGGER.error(error, throwable);
|
||||||
if (VoxyCommon.IS_IN_MINECRAFT && !VoxyCommon.IS_DEDICATED_SERVER) {
|
if (VoxyCommon.IS_IN_MINECRAFT && !VoxyCommon.IS_DEDICATED_SERVER) {
|
||||||
var instance = MinecraftClient.getInstance();
|
var instance = MinecraftClient.getInstance();
|
||||||
@@ -48,8 +72,7 @@ public class Logger {
|
|||||||
throwable = (Throwable) i;
|
throwable = (Throwable) i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stackEntry = new Throwable().getStackTrace()[1];
|
LOGGER.warn((INSERT_CLASS?("["+callClsName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")), throwable);
|
||||||
LOGGER.warn((INSERT_CLASS?("["+stackEntry.getClassName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")), throwable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(Object... args) {
|
public static void info(Object... args) {
|
||||||
@@ -62,8 +85,7 @@ public class Logger {
|
|||||||
throwable = (Throwable) i;
|
throwable = (Throwable) i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stackEntry = new Throwable().getStackTrace()[1];
|
LOGGER.info((INSERT_CLASS?("["+callClsName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")), throwable);
|
||||||
LOGGER.info((INSERT_CLASS?("["+stackEntry.getClassName()+"]: "):"") + Stream.of(args).map(Logger::objToString).collect(Collectors.joining(" ")), throwable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String objToString(Object obj) {
|
private static String objToString(Object obj) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ layout(binding = 0) uniform sampler2D depthTex;
|
|||||||
void main() {
|
void main() {
|
||||||
vec4 depths = textureGather(depthTex, uv, 0); // Get depth values from all surrounding texels.
|
vec4 depths = textureGather(depthTex, uv, 0); // Get depth values from all surrounding texels.
|
||||||
|
|
||||||
bvec4 cv = lessThanEqual(vec4(0.999999f), depths);
|
bvec4 cv = lessThanEqual(vec4(0.999999999f), depths);
|
||||||
if (any(cv)) {//Patch holes (its very dodgy but should work :tm:, should clamp it to the first 3 levels)
|
if (any(cv)) {//Patch holes (its very dodgy but should work :tm:, should clamp it to the first 3 levels)
|
||||||
depths = mix(vec4(0.0f), depths, cv);
|
depths = mix(vec4(0.0f), depths, cv);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,10 +93,9 @@ void bubbleSortInital(uint vis, uint id) {
|
|||||||
|
|
||||||
bool shouldSortId(uint id) {
|
bool shouldSortId(uint id) {
|
||||||
UnpackedNode node;
|
UnpackedNode node;
|
||||||
if (unpackNode(node, gl_GlobalInvocationID.x)==uvec4(-1)) {
|
if (unpackNode(node, id)==uvec4(-1)) {
|
||||||
return false;//Unallocated node
|
return false;//Unallocated node
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEmptyMesh(node) || (!hasMesh(node))) {//|| (!hasChildren(node))
|
if (isEmptyMesh(node) || (!hasMesh(node))) {//|| (!hasChildren(node))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -105,6 +104,9 @@ bool shouldSortId(uint id) {
|
|||||||
return false;//Cannot remove geometry from top level node
|
return false;//Cannot remove geometry from top level node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasRequested(node)) {//If a node has a request its not valid to remove
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*THIS IS COMPLETLY WRONG, we need to check if all the children of the parent of the child are leaf nodes
|
/*THIS IS COMPLETLY WRONG, we need to check if all the children of the parent of the child are leaf nodes
|
||||||
// not this node
|
// not this node
|
||||||
@@ -130,7 +132,7 @@ void main() {
|
|||||||
// this means that insertion into the local buffer can be accelerated W.R.T global
|
// this means that insertion into the local buffer can be accelerated W.R.T global
|
||||||
for (uint i = 0; i < OPS_PER_THREAD; i++) {
|
for (uint i = 0; i < OPS_PER_THREAD; i++) {
|
||||||
//Copy in with warp size batch fetch
|
//Copy in with warp size batch fetch
|
||||||
uint id = gl_LocalInvocationID.x + (i*WORK_SIZE);
|
uint id = (gl_LocalInvocationID.x*OPS_PER_THREAD) + i;
|
||||||
initalSort[id] = minVisIds[id]|(1u<<31);//Flag the id as being external
|
initalSort[id] = minVisIds[id]|(1u<<31);//Flag the id as being external
|
||||||
}
|
}
|
||||||
barrier();
|
barrier();
|
||||||
@@ -158,7 +160,7 @@ void main() {
|
|||||||
//Work size batching
|
//Work size batching
|
||||||
for (uint i = 0; i < OPS_PER_THREAD; i++) {
|
for (uint i = 0; i < OPS_PER_THREAD; i++) {
|
||||||
barrier();//Probably unneeded, was just to keep warp coheriancy
|
barrier();//Probably unneeded, was just to keep warp coheriancy
|
||||||
uint id = gl_LocalInvocationID.x+(i*WORK_SIZE);
|
uint id = (gl_LocalInvocationID.x*OPS_PER_THREAD)+i;
|
||||||
uint sid = initalSort[id];
|
uint sid = initalSort[id];
|
||||||
if ((sid&(1u<<31)) != 0) {
|
if ((sid&(1u<<31)) != 0) {
|
||||||
//The flag being external was set, meaning we should NOT insert this element
|
//The flag being external was set, meaning we should NOT insert this element
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// substantually for performance (for both persistent threads and incremental)
|
// substantually for performance (for both persistent threads and incremental)
|
||||||
|
|
||||||
|
|
||||||
layout(binding = HIZ_BINDING) uniform sampler2DShadow hizDepthSampler;
|
layout(binding = HIZ_BINDING) uniform sampler2D hizDepthSampler;
|
||||||
|
|
||||||
//TODO: maybe do spher bounds aswell? cause they have different accuracies but are both over estimates (liberals (non conservative xD))
|
//TODO: maybe do spher bounds aswell? cause they have different accuracies but are both over estimates (liberals (non conservative xD))
|
||||||
// so can do &&
|
// so can do &&
|
||||||
@@ -39,7 +39,6 @@ bool checkPointInView(vec4 point) {
|
|||||||
|
|
||||||
vec3 minBB = vec3(0.0f);
|
vec3 minBB = vec3(0.0f);
|
||||||
vec3 maxBB = vec3(0.0f);
|
vec3 maxBB = vec3(0.0f);
|
||||||
vec2 size = vec2(0.0f);
|
|
||||||
bool insideFrustum = false;
|
bool insideFrustum = false;
|
||||||
|
|
||||||
float screenSize = 0.0f;
|
float screenSize = 0.0f;
|
||||||
@@ -117,7 +116,8 @@ void setupScreenspace(in UnpackedNode node) {
|
|||||||
minBB = min(min(min(p000, p100), min(p001, p101)), min(min(p010, p110), min(p011, p111)));
|
minBB = min(min(min(p000, p100), min(p001, p101)), min(min(p010, p110), min(p011, p111)));
|
||||||
maxBB = max(max(max(p000, p100), max(p001, p101)), max(max(p010, p110), max(p011, p111)));
|
maxBB = max(max(max(p000, p100), max(p001, p101)), max(max(p010, p110), max(p011, p111)));
|
||||||
|
|
||||||
size = clamp(maxBB.xy - minBB.xy, vec2(0), vec2(1));
|
minBB = clamp(minBB, vec3(0), vec3(1));
|
||||||
|
maxBB = clamp(maxBB, vec3(0), vec3(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Checks if the node is implicitly culled (outside frustum)
|
//Checks if the node is implicitly culled (outside frustum)
|
||||||
@@ -128,32 +128,31 @@ bool outsideFrustum() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isCulledByHiz() {
|
bool isCulledByHiz() {
|
||||||
vec2 ssize = size * vec2(screenW, screenH);
|
ivec2 ssize = ivec2(1)<<ivec2((packedHizSize>>16)&0xFFFF,packedHizSize&0xFFFF);
|
||||||
float miplevel = log2(max(max(ssize.x, ssize.y),1));
|
vec2 size = (maxBB.xy-minBB.xy)*ssize;
|
||||||
|
float miplevel = log2(max(max(size.x, size.y),1));
|
||||||
|
|
||||||
//TODO: make a path for if the miplevel would result in the textureSampler sampling a size of 1
|
miplevel = floor(miplevel)-1;
|
||||||
|
miplevel = clamp(miplevel, 0, textureQueryLevels(hizDepthSampler)-1);
|
||||||
|
|
||||||
|
int ml = int(miplevel);
|
||||||
|
ssize = max(ivec2(1), ssize>>ml);
|
||||||
|
ivec2 mxbb = ivec2(maxBB.xy*ssize);
|
||||||
|
ivec2 mnbb = ivec2(minBB.xy*ssize);
|
||||||
|
|
||||||
miplevel = ceil(miplevel);
|
float pointSample = -1.0f;
|
||||||
miplevel = clamp(miplevel, 0, 20);
|
//float pointSample2 = 0.0f;
|
||||||
|
for (int x = mnbb.x; x<=mxbb.x; x++) {
|
||||||
if (miplevel >= 10.0f) {//Level 9 or 10// TODO: FIX THIS JANK SHIT
|
for (int y = mnbb.y; y<=mxbb.y; y++) {
|
||||||
//return false;
|
float sp = texelFetch(hizDepthSampler, ivec2(x, y), ml).r;
|
||||||
|
//pointSample2 = max(sp, pointSample2);
|
||||||
|
//sp = mix(sp, pointSample, 0.9999999f<=sp);
|
||||||
|
pointSample = max(sp, pointSample);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
//pointSample = mix(pointSample, pointSample2, pointSample<=0.000001f);
|
||||||
|
|
||||||
vec2 midpoint = (maxBB.xy + minBB.xy)*0.5f;
|
return pointSample<=minBB.z;
|
||||||
|
|
||||||
float testAgainst = minBB.z;
|
|
||||||
//the *2.0f-1.0f converts from the 0->1 range to -1->1 range that depth is in (not having this causes tighter bounds, but causes culling issues in caves)
|
|
||||||
testAgainst = testAgainst*2.0f-1.0f;
|
|
||||||
|
|
||||||
bool culled = textureLod(hizDepthSampler, clamp(vec3(midpoint, testAgainst), vec3(0), vec3(1)), miplevel) < 0.0001f;
|
|
||||||
|
|
||||||
//printf("HiZ sample point: (%f,%f)@%f against %f", midpoint.x, midpoint.y, miplevel, minBB.z);
|
|
||||||
//if ((culled) && node22.lodLevel == 0) {
|
|
||||||
// printf("HiZ sample point: (%f,%f)@%f against %f, value %f", midpoint.x, midpoint.y, miplevel, minBB.z, textureLod(hizDepthSampler, vec3(0.5f,0.5f, 0.000000001f), 9.0f));
|
|
||||||
//}
|
|
||||||
return culled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ layout(local_size_x=LOCAL_SIZE) in;//, local_size_y=1
|
|||||||
layout(binding = SCENE_UNIFORM_BINDING, std140) uniform SceneUniform {
|
layout(binding = SCENE_UNIFORM_BINDING, std140) uniform SceneUniform {
|
||||||
mat4 VP;
|
mat4 VP;
|
||||||
ivec3 camSecPos;
|
ivec3 camSecPos;
|
||||||
float screenW;
|
int packedHizSize;
|
||||||
vec3 camSubSecPos;
|
vec3 camSubSecPos;
|
||||||
float screenH;
|
float minSSS;
|
||||||
Frustum frustum;
|
Frustum frustum;
|
||||||
uint renderQueueMaxSize;
|
uint renderQueueMaxSize;
|
||||||
float minSSS;
|
|
||||||
uint frameId;
|
uint frameId;
|
||||||
|
uint requestQueueSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#import <voxy:lod/hierarchical/queue.glsl>
|
#import <voxy:lod/hierarchical/queue.glsl>
|
||||||
@@ -49,9 +49,9 @@ layout(binding = STATISTICS_BUFFER_BINDING, std430) restrict buffer statisticsBu
|
|||||||
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.x < REQUEST_QUEUE_SIZE) {
|
if (requestQueueIndex.x < requestQueueSize) {//Soft limit
|
||||||
uint atomRes = atomicAdd(requestQueueIndex.x, 1);
|
uint atomRes = atomicAdd(requestQueueIndex.x, 1);
|
||||||
if (atomRes < REQUEST_QUEUE_SIZE) {
|
if (atomRes < MAX_REQUEST_QUEUE_SIZE) {//Hard limit
|
||||||
//Mark node as having a request submitted to prevent duplicate submissions
|
//Mark node as having a request submitted to prevent duplicate submissions
|
||||||
requestQueue[atomRes] = getRawPos(node);
|
requestQueue[atomRes] = getRawPos(node);
|
||||||
markRequested(node);
|
markRequested(node);
|
||||||
|
|||||||
Reference in New Issue
Block a user