diff --git a/src/main/java/me/cortex/voxy/client/RenderStatistics.java b/src/main/java/me/cortex/voxy/client/RenderStatistics.java index 2516e491..e666c016 100644 --- a/src/main/java/me/cortex/voxy/client/RenderStatistics.java +++ b/src/main/java/me/cortex/voxy/client/RenderStatistics.java @@ -3,10 +3,10 @@ package me.cortex.voxy.client; import me.cortex.voxy.common.world.WorldEngine; public class RenderStatistics { - public static boolean enabled = true; + public static boolean enabled = false; public static final int[] hierarchicalTraversalCounts = new int[WorldEngine.MAX_LOD_LAYER+1]; public static final int[] hierarchicalRenderSections = new int[WorldEngine.MAX_LOD_LAYER+1]; public static final int[] visibleSections = new int[WorldEngine.MAX_LOD_LAYER+1]; - public static int renderedQuadCount = 0; + public static final int[] quadCount = new int[WorldEngine.MAX_LOD_LAYER+1]; } diff --git a/src/main/java/me/cortex/voxy/client/config/VoxyConfig.java b/src/main/java/me/cortex/voxy/client/config/VoxyConfig.java index 3cf2a523..bb8f53da 100644 --- a/src/main/java/me/cortex/voxy/client/config/VoxyConfig.java +++ b/src/main/java/me/cortex/voxy/client/config/VoxyConfig.java @@ -29,6 +29,7 @@ public class VoxyConfig implements OptionStorage { public int serviceThreads = Math.max(Runtime.getRuntime().availableProcessors()/2, 1); public float subDivisionSize = 128; public boolean renderVanillaFog = false; + public boolean renderStatistics = false; public static VoxyConfig loadOrCreate() { var path = getConfigPath(); diff --git a/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenPages.java b/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenPages.java index 891cdadb..02bedd65 100644 --- a/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenPages.java +++ b/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenPages.java @@ -3,16 +3,14 @@ package me.cortex.voxy.client.config; import com.google.common.collect.ImmutableList; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; +import me.cortex.voxy.client.RenderStatistics; import me.cortex.voxy.client.VoxyClientInstance; import me.cortex.voxy.client.core.IGetVoxyRenderSystem; import me.cortex.voxy.common.Logger; import me.cortex.voxy.commonImpl.IVoxyWorld; import me.cortex.voxy.commonImpl.VoxyCommon; import net.caffeinemc.mods.sodium.client.gui.SodiumOptionsGUI; -import net.caffeinemc.mods.sodium.client.gui.options.OptionGroup; -import net.caffeinemc.mods.sodium.client.gui.options.OptionImpact; -import net.caffeinemc.mods.sodium.client.gui.options.OptionImpl; -import net.caffeinemc.mods.sodium.client.gui.options.OptionPage; +import net.caffeinemc.mods.sodium.client.gui.options.*; import net.caffeinemc.mods.sodium.client.gui.options.control.SliderControl; import net.caffeinemc.mods.sodium.client.gui.options.control.TickBoxControl; import net.minecraft.client.MinecraftClient; @@ -147,6 +145,13 @@ public abstract class VoxyConfigScreenPages { .setControl(TickBoxControl::new) .setBinding((s, v)-> s.renderVanillaFog = v, s -> s.renderVanillaFog) .build() + ).add(OptionImpl.createBuilder(boolean.class, storage) + .setName(Text.translatable("voxy.config.general.render_statistics")) + .setTooltip(Text.translatable("voxy.config.general.render_statistics.tooltip")) + .setControl(TickBoxControl::new) + .setBinding((s, v)-> RenderStatistics.enabled = v, s -> RenderStatistics.enabled) + .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD) + .build() ).build() ); return new OptionPage(Text.translatable("voxy.config.title"), ImmutableList.copyOf(groups)); diff --git a/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java b/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java index aa887222..74d690f8 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java +++ b/src/main/java/me/cortex/voxy/client/core/model/bakery/ModelTextureBakery.java @@ -115,7 +115,7 @@ public class ModelTextureBakery { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glEnable(GL_STENCIL_TEST); - glDepthRange(0, 1); + //glDepthRange(0, 1); glDepthMask(true); glEnable(GL_BLEND); glEnable(GL_DEPTH_TEST); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/RenderDistanceTracker.java b/src/main/java/me/cortex/voxy/client/core/rendering/RenderDistanceTracker.java index a6caeaa2..05e37967 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/RenderDistanceTracker.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/RenderDistanceTracker.java @@ -36,6 +36,12 @@ public class RenderDistanceTracker { } public void setCenterAndProcess(double x, double z) { + //Do some very cheeky stuff for MiB + if (false) { + int sector = (((int)Math.floor(x)>>4)+512)>>10; + x -= sector<<14;//10+4 + } + double dx = this.posX-x; double dz = this.posZ-z; if (CHECK_DISTANCE_BLOCKS*CHECK_DISTANCE_BLOCKS, J extends Vi this.world = world; this.modelService = new ModelBakerySubsystem(world.getMapper()); - //Max sections: ~500k //Max geometry: 1 gb - this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<20, Math.min((1L<<(64-Long.numberOfLeadingZeros(Capabilities.INSTANCE.ssboMaxSize-1)))<<1, 1L<<32)-1024/*(1L<<32)-1024*/); + long geometryCapacity = Math.min((1L<<(64-Long.numberOfLeadingZeros(Capabilities.INSTANCE.ssboMaxSize-1)))<<1, 1L<<32)-1024/*(1L<<32)-1024*/; + // geometryCapacity = 1<<24; + //Max sections: ~500k + this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<20, geometryCapacity); Logger.info("Using renderer: " + this.sectionRenderer.getClass().getSimpleName()); //Do something incredibly hacky, we dont need to keep the reference to this around, so just connect and discard @@ -157,12 +159,14 @@ public class RenderService, J extends Vi public void addDebugData(List debug) { this.modelService.addDebugData(debug); this.renderGen.addDebugData(debug); - this.sectionRenderer.addDebug(debug); + this.sectionRenderer.addDebug(debug); this.nodeManager.addDebug(debug); if (RenderStatistics.enabled) { debug.add("HTC: [" + Arrays.stream(flipCopy(RenderStatistics.hierarchicalTraversalCounts)).mapToObj(Integer::toString).collect(Collectors.joining(", "))+"]"); debug.add("HRS: [" + Arrays.stream(flipCopy(RenderStatistics.hierarchicalRenderSections)).mapToObj(Integer::toString).collect(Collectors.joining(", "))+"]"); + debug.add("VS: [" + Arrays.stream(flipCopy(RenderStatistics.visibleSections)).mapToObj(Integer::toString).collect(Collectors.joining(", "))+"]"); + debug.add("QC: [" + Arrays.stream(flipCopy(RenderStatistics.quadCount)).mapToObj(Integer::toString).collect(Collectors.joining(", "))+"]"); } } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/section/MDICSectionRenderer.java b/src/main/java/me/cortex/voxy/client/core/rendering/section/MDICSectionRenderer.java index 8cd35464..045a23a9 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/section/MDICSectionRenderer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/section/MDICSectionRenderer.java @@ -1,6 +1,7 @@ package me.cortex.voxy.client.core.rendering.section; +import me.cortex.voxy.client.RenderStatistics; import me.cortex.voxy.client.core.gl.GlBuffer; import me.cortex.voxy.client.core.gl.shader.Shader; import me.cortex.voxy.client.core.gl.shader.ShaderType; @@ -8,6 +9,7 @@ import me.cortex.voxy.client.core.model.ModelStore; import me.cortex.voxy.client.core.rendering.LightMapHelper; import me.cortex.voxy.client.core.rendering.RenderService; import me.cortex.voxy.client.core.rendering.SharedIndexBuffer; +import me.cortex.voxy.client.core.rendering.util.DownloadStream; import me.cortex.voxy.client.core.rendering.util.UploadStream; import net.minecraft.client.render.RenderLayer; import net.minecraft.util.math.MathHelper; @@ -34,6 +36,7 @@ import static org.lwjgl.opengl.GL45.glCopyNamedBufferSubData; //Uses MDIC to render the sections public class MDICSectionRenderer extends AbstractSectionRenderer { private static final int TRANSLUCENT_OFFSET = 400_000;//in draw calls + private static final int STATISTICS_BUFFER_BINDING = 7; private final Shader terrainShader = Shader.make() .defineIf("DEBUG_RENDER", false) .add(ShaderType.VERTEX, "voxy:lod/gl46/quads2.vert") @@ -42,6 +45,10 @@ public class MDICSectionRenderer extends AbstractSectionRenderer{ + for (int i = 0; i < 5; i++) { + RenderStatistics.visibleSections[i] = MemoryUtil.memGetInt(down.address+i*4L); + } + + for (int i = 0; i < 5; i++) { + RenderStatistics.quadCount[i] = MemoryUtil.memGetInt(down.address+5*4L+i*4L); + } + }); + } } } @@ -237,5 +264,6 @@ public class MDICSectionRenderer extends AbstractSectionRenderer> detail))&((1<<9)-1); - return (detail<<27)|(detla.x<<18)|(detla.y<<9)|(detla.z); -} - //Note: if i want reverse indexing i need to use the index buffer offset to offset void writeCmd(uint idx, uint instance, uint offset, uint quadCount) { @@ -69,12 +70,13 @@ void main() { //TODO: need to make it check that only if it was also in the frustum last frame does it apply the visibilityData check! // this fixes temporal coherance - //This prevents overflow of the relative position encoder - if (shouldRender) { - } if (shouldRender) { + #ifdef HAS_STATISTICS + atomicAdd(visibleSectionCounts[detail], 1); + #endif + uint ptr = extractQuadStart(meta); ivec3 relative = ipos-(baseSectionPos>>detail); uint drawId = gl_GlobalInvocationID.x; @@ -95,6 +97,9 @@ void main() { uint cmdPtr = atomicAdd(opaqueDrawCount, bitCount(msk)); + #ifdef HAS_STATISTICS + uint totalQuads = 0; + #endif uint count = 0; //Translucency @@ -102,6 +107,9 @@ void main() { if (count != 0) { uint translucentCommandPtr = atomicAdd(translucentDrawCount, 1) + TRANSLUCENT_OFFSET;//FIXME: dont hardcode this offset writeCmd(translucentCommandPtr, drawId, ptr, count); + #ifdef HAS_STATISTICS + totalQuads += count; + #endif } ptr += count; @@ -109,6 +117,9 @@ void main() { count = (meta.cntA>>16)&0xFFFF; if (count != 0) { writeCmd(cmdPtr++, drawId, ptr, count); + #ifdef HAS_STATISTICS + totalQuads += count; + #endif } ptr += count; @@ -116,6 +127,9 @@ void main() { count = (meta.cntB)&0xFFFF; if (((msk&(1u<<0))!=0)) { writeCmd(cmdPtr++, drawId, ptr, count); + #ifdef HAS_STATISTICS + totalQuads += count; + #endif } ptr += count; @@ -123,6 +137,9 @@ void main() { count = (meta.cntB>>16)&0xFFFF; if ((msk&(1u<<1))!=0) { writeCmd(cmdPtr++, drawId, ptr, count); + #ifdef HAS_STATISTICS + totalQuads += count; + #endif } ptr += count; @@ -130,6 +147,9 @@ void main() { count = (meta.cntC)&0xFFFF; if ((msk&(1u<<2))!=0) { writeCmd(cmdPtr++, drawId, ptr, count); + #ifdef HAS_STATISTICS + totalQuads += count; + #endif } ptr += count; @@ -137,6 +157,9 @@ void main() { count = (meta.cntC>>16)&0xFFFF; if ((msk&(1u<<3))!=0) { writeCmd(cmdPtr++, drawId, ptr, count); + #ifdef HAS_STATISTICS + totalQuads += count; + #endif } ptr += count; @@ -144,6 +167,9 @@ void main() { count = (meta.cntD)&0xFFFF; if ((msk&(1u<<4))!=0) { writeCmd(cmdPtr++, drawId, ptr, count); + #ifdef HAS_STATISTICS + totalQuads += count; + #endif } ptr += count; @@ -151,7 +177,14 @@ void main() { count = (meta.cntD>>16)&0xFFFF; if ((msk&(1u<<5))!=0) { writeCmd(cmdPtr++, drawId, ptr, count); + #ifdef HAS_STATISTICS + totalQuads += count; + #endif } ptr += count; + + #ifdef HAS_STATISTICS + atomicAdd(quadCounts[detail], totalQuads); + #endif } } \ No newline at end of file diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index 768bb18b..1b15fce1 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -37,12 +37,12 @@ bool checkPointInView(vec4 point) { return within(vec3(-point.w,-point.w,0.0f), point.xyz, vec3(point.w)); } -vec3 minBB; -vec3 maxBB; -vec2 size; -bool insideFrustum; +vec3 minBB = vec3(0.0f); +vec3 maxBB = vec3(0.0f); +vec2 size = vec2(0.0f); +bool insideFrustum = false; -float screenSize; +float screenSize = 0.0f; UnpackedNode node22; //Sets up screenspace with the given node id, returns true on success false on failure/should not continue