Fix rendering performance

This commit is contained in:
James Seibel
2021-11-25 11:51:35 -06:00
parent 4316cfbfd7
commit e806098544
4 changed files with 123 additions and 23 deletions
File diff suppressed because one or more lines are too long
@@ -151,7 +151,8 @@ public class ClientApi
// CONFIG.client().worldGenerator().setDistanceGenerationMode(DistanceGenerationMode.SURFACE); // CONFIG.client().worldGenerator().setDistanceGenerationMode(DistanceGenerationMode.SURFACE);
// CONFIG.client().graphics().advancedGraphics().setGpuUploadMethod(GpuUploadMethod.BUFFER_STORAGE); // CONFIG.client().graphics().advancedGraphics().setGpuUploadMethod(GpuUploadMethod.BUFFER_STORAGE);
// CONFIG.client().graphics().quality().setLodChunkRenderDistance(64);
// CONFIG.client().advanced().buffers().setRebuildTimes(BufferRebuildTimes.FREQUENT);
CONFIG.client().advanced().debugging().setDebugKeybindingsEnabled(true); CONFIG.client().advanced().debugging().setDebugKeybindingsEnabled(true);
@@ -81,6 +81,8 @@ public class LodBufferBuilderFactory
/** The threads used to generate buffers. */ /** The threads used to generate buffers. */
public static final ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(CONFIG.client().advanced().threading().getNumberOfBufferBuilderThreads(), new ThreadFactoryBuilder().setNameFormat("Buffer-Builder-%d").build()); public static final ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(CONFIG.client().advanced().threading().getNumberOfBufferBuilderThreads(), new ThreadFactoryBuilder().setNameFormat("Buffer-Builder-%d").build());
/** /**
* When uploading to a buffer that is too small, * When uploading to a buffer that is too small,
* recreate it this many times bigger than the upload payload * recreate it this many times bigger than the upload payload
@@ -94,6 +96,8 @@ public class LodBufferBuilderFactory
*/ */
public static final int DEFAULT_MEMORY_ALLOCATION = 1024; public static final int DEFAULT_MEMORY_ALLOCATION = 1024;
public static int skyLightPlayer = 15; public static int skyLightPlayer = 15;
/** /**
@@ -595,11 +599,11 @@ public class LodBufferBuilderFactory
// create the initial mapped buffers (system memory) // create the initial mapped buffers (system memory)
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buildableVbos[x][z][i].id); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buildableVbos[x][z][i].id);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL15.GL_DYNAMIC_DRAW); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, drawableVbos[x][z][i].id); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, drawableVbos[x][z][i].id);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL15.GL_DYNAMIC_DRAW); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
@@ -780,16 +784,18 @@ public class LodBufferBuilderFactory
for (int i = 0; i < buildableBuffers[x][z].length; i++) for (int i = 0; i < buildableBuffers[x][z].length; i++)
{ {
ByteBuffer uploadBuffer = buildableBuffers[x][z][i].getCleanedByteBuffer(); ByteBuffer uploadBuffer = buildableBuffers[x][z][i].getCleanedByteBuffer();
int storageBufferId = 0; vboUpload(x,z,i, uploadBuffer, true, uploadMethod);
if (buildableStorageBufferIds != null)
storageBufferId = buildableStorageBufferIds[x][z][i];
vboUpload(buildableVbos[x][z][i], storageBufferId, uploadBuffer, true, uploadMethod);
lodDim.setRegenRegionBufferByArrayIndex(x, z, false); lodDim.setRegenRegionBufferByArrayIndex(x, z, false);
} }
} }
} }
} }
// make sure all of the uploads finish before continuing
GL45.glMemoryBarrier(GL45.GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
long fence = GL45.glFenceSync(GL45.GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
GL45.glClientWaitSync(fence, GL45.GL_SYNC_FLUSH_COMMANDS_BIT, 5 * 1000000000); // 5 seconds
GL45.glDeleteSync(fence);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -809,9 +815,19 @@ public class LodBufferBuilderFactory
} }
/** Uploads the uploadBuffer so the GPU can use it. */ /** Uploads the uploadBuffer so the GPU can use it. */
private void vboUpload(LodVertexBuffer vbo, int storageBufferId, ByteBuffer uploadBuffer, private void vboUpload(int xIndex, int zIndex, int iIndex, ByteBuffer uploadBuffer,
boolean allowBufferExpansion, GpuUploadMethod uploadMethod) boolean allowBufferExpansion, GpuUploadMethod uploadMethod)
{ {
// get the vbos, buffers, ids, etc.
int storageBufferId = 0;
if (buildableStorageBufferIds != null)
storageBufferId = buildableStorageBufferIds[xIndex][zIndex][iIndex];
LodVertexBuffer vbo = buildableVbos[xIndex][zIndex][iIndex];
// this shouldn't happen, but just to be safe // this shouldn't happen, but just to be safe
if (vbo.id != -1 && GLProxy.getInstance().getGlContext() == GLProxyContext.LOD_BUILDER) if (vbo.id != -1 && GLProxy.getInstance().getGlContext() == GLProxyContext.LOD_BUILDER)
{ {
@@ -855,7 +871,7 @@ public class LodBufferBuilderFactory
// recursively try to upload into the newly created buffer storage // recursively try to upload into the newly created buffer storage
// but don't recurse again if that fails // but don't recurse again if that fails
// (we don't want an infinitely expanding buffer!) // (we don't want an infinitely expanding buffer!)
vboUpload(vbo, storageBufferId, uploadBuffer, false, uploadMethod); vboUpload(xIndex,zIndex,iIndex, uploadBuffer, false, uploadMethod);
} }
} }
else else
@@ -868,11 +884,6 @@ public class LodBufferBuilderFactory
// (uploading into GPU memory directly can only be done // (uploading into GPU memory directly can only be done
// through the glCopyBufferSubData/glCopyNamed... methods) // through the glCopyBufferSubData/glCopyNamed... methods)
GL45.glCopyNamedBufferSubData(vbo.id, storageBufferId, 0, 0, uploadBuffer.capacity()); GL45.glCopyNamedBufferSubData(vbo.id, storageBufferId, 0, 0, uploadBuffer.capacity());
// alternative way that doesn't require GL45
// GL15.glBindBuffer(GL45.GL_COPY_WRITE_BUFFER, storageBufferId);
// GL45.glCopyBufferSubData(GL15.GL_ARRAY_BUFFER, GL45.GL_COPY_WRITE_BUFFER, 0, 0, uploadBuffer.capacity());
// GL15.glBindBuffer(GL45.GL_COPY_WRITE_BUFFER, 0);
} }
} }
else if (uploadMethod == GpuUploadMethod.BUFFER_MAPPING) else if (uploadMethod == GpuUploadMethod.BUFFER_MAPPING)
@@ -895,7 +906,7 @@ public class LodBufferBuilderFactory
if (vboBuffer == null) if (vboBuffer == null)
{ {
GL15.glBufferData(GL45.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), GL15.GL_DYNAMIC_DRAW); GL15.glBufferData(GL45.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), GL15.GL_STATIC_DRAW);
GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer); GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer);
} }
else else
@@ -909,7 +920,7 @@ public class LodBufferBuilderFactory
// high stutter, low GPU usage // high stutter, low GPU usage
// But simplest/most compatible // But simplest/most compatible
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, uploadBuffer, GL15.GL_DYNAMIC_DRAW); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, uploadBuffer, GL15.GL_STATIC_DRAW);
} }
else else
{ {
@@ -919,7 +930,7 @@ public class LodBufferBuilderFactory
long size = GL15.glGetBufferParameteri(GL15.GL_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE); long size = GL15.glGetBufferParameteri(GL15.GL_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE);
if (size < uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER) if (size < uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER)
{ {
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), GL15.GL_DYNAMIC_DRAW); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), GL15.GL_STATIC_DRAW);
} }
GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer); GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer);
} }
@@ -29,6 +29,7 @@ import org.lwjgl.opengl.NVFogDistance;
import com.seibel.lod.core.api.ApiShared; import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.builders.bufferBuilding.LodBufferBuilderFactory; import com.seibel.lod.core.builders.bufferBuilding.LodBufferBuilderFactory;
import com.seibel.lod.core.builders.bufferBuilding.LodBufferBuilderFactory.VertexBuffersAndOffset; import com.seibel.lod.core.builders.bufferBuilding.LodBufferBuilderFactory.VertexBuffersAndOffset;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
import com.seibel.lod.core.enums.rendering.DebugMode; import com.seibel.lod.core.enums.rendering.DebugMode;
import com.seibel.lod.core.enums.rendering.FogDistance; import com.seibel.lod.core.enums.rendering.FogDistance;
import com.seibel.lod.core.enums.rendering.FogDrawOverride; import com.seibel.lod.core.enums.rendering.FogDrawOverride;
@@ -286,7 +287,7 @@ public class LodRenderer
// TODO re-enable once rendering is totally working // TODO re-enable once rendering is totally working
boolean cullingDisabled = true; //LodConfig.client().graphics.advancedGraphicsOption.disableDirectionalCulling.get(); boolean cullingDisabled = true; //LodConfig.client().graphics.advancedGraphicsOption.disableDirectionalCulling.get();
// boolean renderBufferStorage = config.client().graphics().advancedGraphics().getGpuUploadMethod() == GpuUploadMethod.BUFFER_STORAGE && glProxy.bufferStorageSupported; boolean renderBufferStorage = CONFIG.client().graphics().advancedGraphics().getGpuUploadMethod() == GpuUploadMethod.BUFFER_STORAGE && glProxy.bufferStorageSupported;
// used to determine what type of fog to render // used to determine what type of fog to render
// int halfWidth = vbos.length / 2; // int halfWidth = vbos.length / 2;
@@ -339,10 +340,10 @@ public class LodRenderer
// else // else
// setupFog(fogSettings.far.distance, fogSettings.far.quality); // setupFog(fogSettings.far.distance, fogSettings.far.quality);
// if (storageBufferIds != null && renderBufferStorage) if (storageBufferIds != null && renderBufferStorage)
// for (int i = 0; i < storageBufferIds[x][z].length; i++) for (int i = 0; i < storageBufferIds[x][z].length; i++)
// drawArrays(storageBufferIds[x][z][i], vbos[x][z][i].vertexCount, posAttrib, colAttrib); drawArrays(storageBufferIds[x][z][i], vbos[x][z][i].vertexCount, posAttrib, colAttrib);
// else else
for (int i = 0; i < vbos[x][z].length; i++) for (int i = 0; i < vbos[x][z].length; i++)
drawArrays(vbos[x][z][i].id, vbos[x][z][i].vertexCount, posAttrib, colAttrib); drawArrays(vbos[x][z][i].id, vbos[x][z][i].vertexCount, posAttrib, colAttrib);
} }