From 9d1a9eb9f3c192d3e21d758fcb407f8ab832b629 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 10 Oct 2021 14:01:13 -0500 Subject: [PATCH] Remove the memory estimation code. Buffers will now be purposely created smaller than expected and then expanded to fit the need. --- .../bufferBuilding/LodBufferBuilder.java | 18 +++-- .../lodTemplates/AbstractLodTemplate.java | 20 ++--- .../lodTemplates/CubicLodTemplate.java | 9 +-- .../lodTemplates/DynamicLodTemplate.java | 10 +-- .../lodTemplates/TriangularLodTemplate.java | 10 +-- .../com/seibel/lod/enums/LodTemplate.java | 7 +- .../com/seibel/lod/objects/LodDimension.java | 40 +++------- .../com/seibel/lod/objects/LodRegion.java | 17 +--- .../com/seibel/lod/render/RenderUtil.java | 26 +----- .../java/com/seibel/lod/util/LodUtil.java | 80 ++----------------- 10 files changed, 46 insertions(+), 191 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java index 40a40804b..0995a4b60 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java @@ -62,7 +62,7 @@ import net.minecraft.util.math.ChunkPos; * This object is used to create NearFarBuffer objects. * * @author James Seibel - * @version 10-9-2021 + * @version 10-10-2021 */ public class LodBufferBuilder { @@ -77,6 +77,13 @@ public class LodBufferBuilder */ public static final double BUFFER_EXPANSION_MULTIPLIER = 1.5; + /** + * When buffers are first created they are allocated to this size (in Bytes). + * This size will be too small, more than likely. The buffers will be expanded + * when need be to fit the larger sizes. + */ + public static final int DEFAULT_MEMORY_ALLOCATION = 1024; + /** This boolean matrix indicate the buffer builder in that position has to be regenerated */ public volatile boolean[][] regenPos; @@ -464,7 +471,7 @@ public class LodBufferBuilder { for (int z = 0; z < numbRegionsWide; z++) { - regionMemoryRequired = LodUtil.calculateMaximumRegionGpuMemoryUse(x, z, LodConfig.CLIENT.graphics.lodTemplate.get()); + regionMemoryRequired = DEFAULT_MEMORY_ALLOCATION; // if the memory required is greater than the max buffer // capacity, divide the memory across multiple buffers @@ -507,6 +514,7 @@ public class LodBufferBuilder buildableVbos[x][z][i] = new VertexBuffer(LodUtil.LOD_VERTEX_FORMAT); drawableVbos[x][z][i] = new VertexBuffer(LodUtil.LOD_VERTEX_FORMAT); + // create the initial mapped buffers (system memory) GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buildableVbos[x][z][i].id); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL45.GL_DYNAMIC_DRAW); @@ -517,9 +525,7 @@ public class LodBufferBuilder GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); - // create the buffer storage (GPU memory) - buildableStorageBufferIds[x][z][i] = GL45.glGenBuffers(); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buildableStorageBufferIds[x][z][i]); GL45.glBufferStorage(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, 0); // the 0 flag means to create the storage in the GPU's memory @@ -680,8 +686,8 @@ public class LodBufferBuilder { for (int i = 0; i < buildableBuffers[x][z].length; i++) { - ByteBuffer builderBuffer = buildableBuffers[x][z][i].popNextBuffer().getSecond(); - vboUpload(buildableVbos[x][z][i], buildableStorageBufferIds[x][z][i], builderBuffer, x,z,i, true); + ByteBuffer uploadBuffer = buildableBuffers[x][z][i].popNextBuffer().getSecond(); + vboUpload(buildableVbos[x][z][i], buildableStorageBufferIds[x][z][i], uploadBuffer, x,z,i, true); lodDim.setRegenRegionBufferByArrayIndex(x, z, false); } } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java index 42ab5583e..bb102c8b1 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java @@ -18,34 +18,31 @@ package com.seibel.lod.builders.bufferBuilding.lodTemplates; +import java.util.Map; + import com.seibel.lod.enums.DebugMode; import com.seibel.lod.util.ColorUtil; + import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import java.util.Map; - /** * This is the abstract class used to create different * BufferBuilders. * * @author James Seibel - * @version 8-8-2021 + * @version 10-10-2021 */ public abstract class AbstractLodTemplate { - /** - * Uploads the given LOD to the buffer. - */ + /** Uploads the given LOD to the buffer. */ public abstract void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled); - /** - * add the given position and color to the buffer - */ + /** add the given position and color to the buffer */ protected void addPosAndColor(BufferBuilder buffer, double x, double y, double z, int color) @@ -54,9 +51,4 @@ public abstract class AbstractLodTemplate buffer.vertex(x, y, z).color(ColorUtil.getRed(color), ColorUtil.getGreen(color), ColorUtil.getBlue(color), 255).endVertex(); } - /** - * Returns in bytes how much buffer memory is required - * for one LOD object - */ - public abstract int getBufferMemoryForSingleNode(int maxVerticalData); } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java index 648dea691..c14a941b1 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java @@ -33,7 +33,7 @@ import net.minecraft.util.math.BlockPos; * Builds LODs as rectangular prisms. * * @author James Seibel - * @version 9-25-2021 + * @version 10-10-2021 */ public class CubicLodTemplate extends AbstractLodTemplate { @@ -127,11 +127,4 @@ public class CubicLodTemplate extends AbstractLodTemplate } } - @Override - public int getBufferMemoryForSingleNode(int maxVerticalData) - { - // TODO, what do these magic numbers mean - return 2 * 4 * (3 + 4) + 4 * 4 * Math.max((maxVerticalData + 1) / 2, 1) * (3 + 4); - } - } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java index 0713d9fae..5afde314d 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java @@ -18,15 +18,16 @@ package com.seibel.lod.builders.bufferBuilding.lodTemplates; +import java.util.Map; + import com.seibel.lod.enums.DebugMode; import com.seibel.lod.proxy.ClientProxy; + import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import java.util.Map; - /** * TODO DynamicLodTemplate * Chunks smoothly transition between @@ -45,9 +46,4 @@ public class DynamicLodTemplate extends AbstractLodTemplate ClientProxy.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!"); } - @Override - public int getBufferMemoryForSingleNode(int maxVerticalData) - { - return 0; - } } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java index 7fa70cf61..2442cd998 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java @@ -18,15 +18,16 @@ package com.seibel.lod.builders.bufferBuilding.lodTemplates; +import java.util.Map; + import com.seibel.lod.enums.DebugMode; import com.seibel.lod.proxy.ClientProxy; + import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import java.util.Map; - /** * TODO #21 TriangularLodTemplate * Builds each LOD chunk as a singular rectangular prism. @@ -43,9 +44,4 @@ public class TriangularLodTemplate extends AbstractLodTemplate ClientProxy.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!"); } - @Override - public int getBufferMemoryForSingleNode(int maxVerticalData) - { - return 0; - } } diff --git a/src/main/java/com/seibel/lod/enums/LodTemplate.java b/src/main/java/com/seibel/lod/enums/LodTemplate.java index 180008dc2..f62a0ddff 100644 --- a/src/main/java/com/seibel/lod/enums/LodTemplate.java +++ b/src/main/java/com/seibel/lod/enums/LodTemplate.java @@ -26,7 +26,7 @@ import com.seibel.lod.builders.bufferBuilding.lodTemplates.TriangularLodTemplate * Cubic, Triangular, Dynamic * * @author James Seibel - * @version 8-4-2021 + * @version 10-10-2021 */ public enum LodTemplate { @@ -51,9 +51,4 @@ public enum LodTemplate template = newTemplate; } - - public int getBufferMemoryForSingleLod(int maxVerticalData) - { - return template.getBufferMemoryForSingleNode(maxVerticalData); - } } diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 2cbf2f8a1..2d0702f25 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -18,23 +18,28 @@ package com.seibel.lod.objects; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.enums.GenerationPriority; import com.seibel.lod.enums.VerticalQuality; import com.seibel.lod.handlers.LodDimensionFileHandler; -import com.seibel.lod.util.*; +import com.seibel.lod.util.DataPointUtil; +import com.seibel.lod.util.DetailDistanceUtil; +import com.seibel.lod.util.LevelPosUtil; +import com.seibel.lod.util.LodThreadFactory; +import com.seibel.lod.util.LodUtil; import com.seibel.lod.wrappers.MinecraftWrapper; + import net.minecraft.util.math.ChunkPos; import net.minecraft.world.DimensionType; import net.minecraft.world.server.ServerChunkProvider; import net.minecraft.world.server.ServerWorld; -import java.io.File; -import java.io.IOException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - /** * This object holds all loaded LOD regions @@ -46,7 +51,7 @@ import java.util.concurrent.Executors; * * @author Leonardo Amato * @author James Seibel - * @version 9-27-2021 + * @version 10-10-2021 */ public class LodDimension { @@ -238,27 +243,6 @@ public class LodDimension } - /** - * return the minimum needed memory in bytes - */ - public int getMinMemoryNeeded() - { - int count = 0; - LodRegion region; - - for (LodRegion[] lodRegions : regions) - { - for (int z = 0; z < regions.length; z++) - { - region = lodRegions[z]; - if (region != null) - count += region.getMinMemoryNeeded(LodConfig.CLIENT.graphics.lodTemplate.get()); - } - } - return count; - } - - /** * Gets the region at the given LevelPos *
diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index 0f8f9890b..94ac415d2 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -3,7 +3,6 @@ package com.seibel.lod.objects; import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; -import com.seibel.lod.enums.LodTemplate; import com.seibel.lod.enums.VerticalQuality; import com.seibel.lod.util.DataPointUtil; import com.seibel.lod.util.DetailDistanceUtil; @@ -19,7 +18,7 @@ import com.seibel.lod.util.LodUtil; * unless stated otherwise.
* * @author Leonardo Amato - * @version 9-27-2021 + * @version 10-10-2021 */ public class LodRegion { @@ -517,20 +516,6 @@ public class LodRegion return new RegionPos(regionPosX, regionPosZ); } - /** - * Returns the minimum memory needed in bytes - */ - public int getMinMemoryNeeded(LodTemplate template) - { - int memory = 0; - for (byte detailLevelIndex = LodUtil.REGION_DETAIL_LEVEL; detailLevelIndex > minDetailLevel; detailLevelIndex--) - { - // TODO why are we multiplying the dataContainer's memory by the template's memory? - memory += dataContainer[detailLevelIndex].getMaxMemoryUse() * template.getBufferMemoryForSingleLod(dataContainer[detailLevelIndex].getMaxVerticalData()); - } - return memory; - } - /** * Returns how many LODs are in this region */ diff --git a/src/main/java/com/seibel/lod/render/RenderUtil.java b/src/main/java/com/seibel/lod/render/RenderUtil.java index 148f9dc58..c571d2bda 100644 --- a/src/main/java/com/seibel/lod/render/RenderUtil.java +++ b/src/main/java/com/seibel/lod/render/RenderUtil.java @@ -18,8 +18,6 @@ package com.seibel.lod.render; -import com.seibel.lod.config.LodConfig; -import com.seibel.lod.objects.LodRegion; import com.seibel.lod.util.LodUtil; import com.seibel.lod.wrappers.MinecraftWrapper; @@ -32,7 +30,7 @@ import net.minecraft.util.math.vector.Vector3d; * to be used in the rendering process. * * @author James Seibel - * @version 8-21-2021 + * @version 10-10-2021 */ public class RenderUtil { @@ -82,28 +80,6 @@ public class RenderUtil } - /** - * Get how much buffer memory would be required for the given radius multiplier - */ - public static int getBufferMemoryForRegion(LodRegion region) - { - // calculate the max amount of buffer memory needed (in bytes) - return region.getMinMemoryNeeded(LodConfig.CLIENT.graphics.lodTemplate.get()); - } - - ///** - // * Returns the maxViewDistanceMultiplier for the given LodTemplate - // * at the given LodDetail level. - // */ - /*public static int getMaxRadiusMultiplierWithAvailableMemory(LodTemplate lodTemplate, int detailLevel) - { - int maxNumberOfLods = LodRenderer.MAX_ALLOCATABLE_DIRECT_MEMORY / lodTemplate.getBufferMemoryForSingleLod(); - int numbLodsWide = (int) Math.sqrt(maxNumberOfLods); - - return numbLodsWide / (2 * mc.getRenderDistance()); - }*/ - - /** * Returns true if one of the region's 4 corners is in front * of the camera. diff --git a/src/main/java/com/seibel/lod/util/LodUtil.java b/src/main/java/com/seibel/lod/util/LodUtil.java index a3f203bd6..d993804f8 100644 --- a/src/main/java/com/seibel/lod/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/util/LodUtil.java @@ -18,11 +18,15 @@ package com.seibel.lod.util; +import java.awt.Color; +import java.io.File; +import java.util.HashSet; + import com.seibel.lod.builders.bufferBuilding.lodTemplates.Box; -import com.seibel.lod.enums.LodTemplate; import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.RegionPos; import com.seibel.lod.wrappers.MinecraftWrapper; + import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher.CompiledChunk; @@ -40,15 +44,11 @@ import net.minecraft.world.gen.Heightmap; import net.minecraft.world.server.ServerChunkProvider; import net.minecraft.world.server.ServerWorld; -import java.awt.*; -import java.io.File; -import java.util.HashSet; - /** * This class holds methods and constants that may be used in multiple places. * * @author James Seibel - * @version 10-7-2021 + * @version 10-10-2021 */ public class LodUtil { @@ -350,74 +350,6 @@ public class LodUtil return Math.min(max, Math.max(value, min)); } - /** - * Returns the GPU memory needed if all LODs in - * the given region are rendered. - * - * @param regionPosX x region position to check - * @param regionPosZ z region position to check - * @return number of lods in the region - */ - public static long calculateMaximumRegionGpuMemoryUse(int regionPosX, int regionPosZ, LodTemplate template) - { - int xRegionSign = (int) Math.signum(regionPosX); - int zRegionSign = (int) Math.signum(regionPosZ); - - // we first find the center of the circle which is one of the following X position in the center region - /* - X - X - X - | | - X X X - | | - X - X - X - */ - int circleCenterX = 256 + 256 * xRegionSign; - int circleCenterZ = 256 + 256 * zRegionSign; - - - int innerRadius; - int outerRadius; - int size; - int count; - int minDistance; - int maxDistance; - long memoryUse = 0; - for (byte detailLevel = BLOCK_DETAIL_LEVEL; detailLevel <= REGION_DETAIL_LEVEL; detailLevel++) - { - // Find the inner and outer detail of this area - innerRadius = DetailDistanceUtil.getDrawDistanceFromDetail(detailLevel); - outerRadius = DetailDistanceUtil.getDrawDistanceFromDetail(detailLevel + 1); - - // skip this region if it does not intersect the two circles. - minDistance = LevelPosUtil.minDistance(REGION_DETAIL_LEVEL, regionPosX, regionPosZ, circleCenterX, circleCenterZ); - maxDistance = LevelPosUtil.maxDistance(REGION_DETAIL_LEVEL, regionPosX, regionPosZ, circleCenterX, circleCenterZ); - if (innerRadius > maxDistance || minDistance > outerRadius) - continue; - - // count every position in the region that falls between the two circles - size = 1 << (REGION_DETAIL_LEVEL - detailLevel); - count = 0; - for (int x = 0; x < size; x++) - { - for (int z = 0; z < size; z++) - { - minDistance = LevelPosUtil.minDistance(detailLevel, x, z, circleCenterX, circleCenterZ, regionPosX, regionPosZ); - if (innerRadius < minDistance && minDistance < outerRadius) - count++; - } - } - - // we multiply the data with the max vertical data of this detail level - int maxVerticalData = DetailDistanceUtil.getMaxVerticalData(detailLevel); - - count *= maxVerticalData; - memoryUse += (long) template.getBufferMemoryForSingleLod(maxVerticalData) * count; - } - - return memoryUse; - } - - /** * Get a HashSet of all ChunkPos within the normal render distance * that should not be rendered.