things
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
package me.cortex.voxy.client.core;
|
package me.cortex.voxy.client.core;
|
||||||
|
|
||||||
import com.mojang.blaze3d.opengl.GlConst;
|
import com.mojang.blaze3d.opengl.GlConst;
|
||||||
|
import com.mojang.blaze3d.opengl.GlStateManager;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import me.cortex.voxy.client.TimingStatistics;
|
import me.cortex.voxy.client.TimingStatistics;
|
||||||
import me.cortex.voxy.client.config.VoxyConfig;
|
import me.cortex.voxy.client.config.VoxyConfig;
|
||||||
import me.cortex.voxy.client.core.gl.Capabilities;
|
import me.cortex.voxy.client.core.gl.Capabilities;
|
||||||
import me.cortex.voxy.client.core.gl.GlBuffer;
|
import me.cortex.voxy.client.core.gl.GlBuffer;
|
||||||
|
import me.cortex.voxy.client.core.gl.GlTexture;
|
||||||
import me.cortex.voxy.client.core.model.ModelBakerySubsystem;
|
import me.cortex.voxy.client.core.model.ModelBakerySubsystem;
|
||||||
import me.cortex.voxy.client.core.rendering.ChunkBoundRenderer;
|
import me.cortex.voxy.client.core.rendering.ChunkBoundRenderer;
|
||||||
import me.cortex.voxy.client.core.rendering.RenderDistanceTracker;
|
import me.cortex.voxy.client.core.rendering.RenderDistanceTracker;
|
||||||
@@ -42,6 +44,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import static org.lwjgl.opengl.GL11C.*;
|
import static org.lwjgl.opengl.GL11C.*;
|
||||||
import static org.lwjgl.opengl.GL30C.GL_DRAW_FRAMEBUFFER_BINDING;
|
import static org.lwjgl.opengl.GL30C.GL_DRAW_FRAMEBUFFER_BINDING;
|
||||||
import static org.lwjgl.opengl.GL30C.glBindFramebuffer;
|
import static org.lwjgl.opengl.GL30C.glBindFramebuffer;
|
||||||
|
import static org.lwjgl.opengl.GL33.glBindSampler;
|
||||||
|
|
||||||
public class VoxyRenderSystem {
|
public class VoxyRenderSystem {
|
||||||
private final RenderService renderer;
|
private final RenderService renderer;
|
||||||
@@ -217,11 +220,27 @@ public class VoxyRenderSystem {
|
|||||||
TimingStatistics.postDynamic.stop();
|
TimingStatistics.postDynamic.stop();
|
||||||
|
|
||||||
glBindFramebuffer(GlConst.GL_FRAMEBUFFER, oldFB);
|
glBindFramebuffer(GlConst.GL_FRAMEBUFFER, oldFB);
|
||||||
|
|
||||||
|
{//Reset state manager stuffs
|
||||||
|
GlStateManager._glBindVertexArray(0);//Clear binding
|
||||||
|
|
||||||
|
GlStateManager._activeTexture(GlConst.GL_TEXTURE0);
|
||||||
|
GlStateManager._bindTexture(0);
|
||||||
|
glBindSampler(0, 0);
|
||||||
|
|
||||||
|
GlStateManager._activeTexture(GlConst.GL_TEXTURE1);
|
||||||
|
GlStateManager._bindTexture(0);
|
||||||
|
glBindSampler(1, 0);
|
||||||
|
|
||||||
|
GlStateManager._activeTexture(GlConst.GL_TEXTURE2);
|
||||||
|
GlStateManager._bindTexture(0);
|
||||||
|
glBindSampler(2, 0);
|
||||||
|
}
|
||||||
TimingStatistics.all.stop();
|
TimingStatistics.all.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDebugInfo(List<String> debug) {
|
public void addDebugInfo(List<String> debug) {
|
||||||
debug.add("GlBuffer, Count/Size (mb): " + GlBuffer.getCount() + "/" + (GlBuffer.getTotalSize()/1_000_000));
|
debug.add("Buf/Tex [#/Mb]: [" + GlBuffer.getCount() + "/" + (GlBuffer.getTotalSize()/1_000_000) + "],[" + GlTexture.getCount() + "/" + (GlTexture.getEstimatedTotalSize()/1_000_000)+"]");
|
||||||
this.renderer.addDebugData(debug);
|
this.renderer.addDebugData(debug);
|
||||||
{
|
{
|
||||||
TimingStatistics.update();
|
TimingStatistics.update();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.lwjgl.opengl.GL20C;
|
|||||||
import static org.lwjgl.opengl.GL11.*;
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
import static org.lwjgl.opengl.GL32.glGetInteger64;
|
import static org.lwjgl.opengl.GL32.glGetInteger64;
|
||||||
import static org.lwjgl.opengl.GL43C.GL_MAX_SHADER_STORAGE_BLOCK_SIZE;
|
import static org.lwjgl.opengl.GL43C.GL_MAX_SHADER_STORAGE_BLOCK_SIZE;
|
||||||
|
import static org.lwjgl.opengl.NVXGPUMemoryInfo.*;
|
||||||
|
|
||||||
public class Capabilities {
|
public class Capabilities {
|
||||||
|
|
||||||
@@ -16,9 +17,13 @@ public class Capabilities {
|
|||||||
public final boolean INT64_t;
|
public final boolean INT64_t;
|
||||||
public final long ssboMaxSize;
|
public final long ssboMaxSize;
|
||||||
public final boolean isMesa;
|
public final boolean isMesa;
|
||||||
|
public final boolean canQueryGpuMemory;
|
||||||
|
public final long totalDedicatedMemory;//Bytes, dedicated memory
|
||||||
|
public final long totalDynamicMemory;//Bytes, total allocation memory - dedicated memory
|
||||||
public Capabilities() {
|
public Capabilities() {
|
||||||
var cap = GL.getCapabilities();
|
var cap = GL.getCapabilities();
|
||||||
this.meshShaders = cap.GL_NV_mesh_shader && cap.GL_NV_representative_fragment_test;
|
this.meshShaders = cap.GL_NV_mesh_shader && cap.GL_NV_representative_fragment_test;
|
||||||
|
this.canQueryGpuMemory = cap.GL_NVX_gpu_memory_info;
|
||||||
//this.INT64_t = cap.GL_ARB_gpu_shader_int64 || cap.GL_AMD_gpu_shader_int64;
|
//this.INT64_t = cap.GL_ARB_gpu_shader_int64 || cap.GL_AMD_gpu_shader_int64;
|
||||||
//The only reliable way to test for int64 support is to try compile a shader
|
//The only reliable way to test for int64 support is to try compile a shader
|
||||||
this.INT64_t = testShaderCompilesOk(ShaderType.COMPUTE, """
|
this.INT64_t = testShaderCompilesOk(ShaderType.COMPUTE, """
|
||||||
@@ -33,6 +38,14 @@ public class Capabilities {
|
|||||||
this.ssboMaxSize = glGetInteger64(GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
|
this.ssboMaxSize = glGetInteger64(GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
|
||||||
|
|
||||||
this.isMesa = glGetString(GL_VERSION).toLowerCase().contains("mesa");
|
this.isMesa = glGetString(GL_VERSION).toLowerCase().contains("mesa");
|
||||||
|
|
||||||
|
if (this.canQueryGpuMemory) {
|
||||||
|
this.totalDedicatedMemory = glGetInteger64(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX)*1024;//Since its in Kb
|
||||||
|
this.totalDynamicMemory = (glGetInteger64(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX)*1024) - this.totalDedicatedMemory;//Since its in Kb
|
||||||
|
} else {
|
||||||
|
this.totalDedicatedMemory = -1;
|
||||||
|
this.totalDynamicMemory = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
@@ -47,4 +60,13 @@ public class Capabilities {
|
|||||||
|
|
||||||
return result == GL20C.GL_TRUE;
|
return result == GL20C.GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getFreeDedicatedGpuMemory() {
|
||||||
|
if (!this.canQueryGpuMemory) {
|
||||||
|
throw new IllegalStateException("Cannot query gpu memory, missing extension");
|
||||||
|
}
|
||||||
|
return glGetInteger64(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX)*1024;//Since its in Kb
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: add gpu eviction tracking
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import me.cortex.voxy.common.util.TrackedObject;
|
|||||||
|
|
||||||
import static org.lwjgl.opengl.ARBFramebufferObject.glDeleteFramebuffers;
|
import static org.lwjgl.opengl.ARBFramebufferObject.glDeleteFramebuffers;
|
||||||
import static org.lwjgl.opengl.ARBFramebufferObject.glGenFramebuffers;
|
import static org.lwjgl.opengl.ARBFramebufferObject.glGenFramebuffers;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_RGBA8;
|
||||||
import static org.lwjgl.opengl.GL11C.*;
|
import static org.lwjgl.opengl.GL11C.*;
|
||||||
import static org.lwjgl.opengl.GL30C.glGetIntegeri;
|
import static org.lwjgl.opengl.GL30.GL_DEPTH24_STENCIL8;
|
||||||
import static org.lwjgl.opengl.GL45C.*;
|
import static org.lwjgl.opengl.GL45C.*;
|
||||||
|
|
||||||
public class GlTexture extends TrackedObject {
|
public class GlTexture extends TrackedObject {
|
||||||
@@ -14,7 +15,12 @@ public class GlTexture extends TrackedObject {
|
|||||||
private int format;
|
private int format;
|
||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
private int layers;
|
private int levels;
|
||||||
|
private boolean hasAllocated;
|
||||||
|
|
||||||
|
private static int COUNT;
|
||||||
|
private static long ESTIMATED_TOTAL_SIZE;
|
||||||
|
|
||||||
public GlTexture() {
|
public GlTexture() {
|
||||||
this(GL_TEXTURE_2D);
|
this(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
@@ -22,6 +28,7 @@ public class GlTexture extends TrackedObject {
|
|||||||
public GlTexture(int type) {
|
public GlTexture(int type) {
|
||||||
this.id = glCreateTextures(type);
|
this.id = glCreateTextures(type);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
COUNT++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GlTexture(int type, boolean useGenTypes) {
|
private GlTexture(int type, boolean useGenTypes) {
|
||||||
@@ -31,22 +38,30 @@ public class GlTexture extends TrackedObject {
|
|||||||
this.id = glCreateTextures(type);
|
this.id = glCreateTextures(type);
|
||||||
}
|
}
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
COUNT++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlTexture store(int format, int levels, int width, int height) {
|
public GlTexture store(int format, int levels, int width, int height) {
|
||||||
|
if (this.hasAllocated) {
|
||||||
|
throw new IllegalStateException("Texture already allocated");
|
||||||
|
}
|
||||||
|
this.hasAllocated = true;
|
||||||
|
|
||||||
this.format = format;
|
this.format = format;
|
||||||
if (this.type == GL_TEXTURE_2D) {
|
if (this.type == GL_TEXTURE_2D) {
|
||||||
glTextureStorage2D(this.id, levels, format, width, height);
|
glTextureStorage2D(this.id, levels, format, width, height);
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.layers = layers;
|
this.levels = levels;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Unknown texture type");
|
throw new IllegalStateException("Unknown texture type");
|
||||||
}
|
}
|
||||||
|
ESTIMATED_TOTAL_SIZE += this.getEstimatedSize();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlTexture createView() {
|
public GlTexture createView() {
|
||||||
|
this.assertAllocated();
|
||||||
var view = new GlTexture(this.type, true);
|
var view = new GlTexture(this.type, true);
|
||||||
glTextureView(view.id, this.type, this.id, this.format, 0, 1, 0, 1);
|
glTextureView(view.id, this.type, this.id, this.format, 0, 1, 0, 1);
|
||||||
return view;
|
return view;
|
||||||
@@ -54,23 +69,63 @@ public class GlTexture extends TrackedObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public void free() {
|
||||||
|
if (this.hasAllocated) {
|
||||||
|
ESTIMATED_TOTAL_SIZE -= this.getEstimatedSize();
|
||||||
|
}
|
||||||
|
COUNT--;
|
||||||
|
this.hasAllocated = false;
|
||||||
super.free0();
|
super.free0();
|
||||||
glDeleteTextures(this.id);
|
glDeleteTextures(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlTexture name(String name) {
|
public GlTexture name(String name) {
|
||||||
|
this.assertAllocated();
|
||||||
return GlDebug.name(name, this);
|
return GlDebug.name(name, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
|
this.assertAllocated();
|
||||||
return this.width;
|
return this.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
|
this.assertAllocated();
|
||||||
return this.height;
|
return this.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLayers() {
|
public int getLevels() {
|
||||||
return this.layers;
|
this.assertAllocated();
|
||||||
|
return this.levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getEstimatedSize() {
|
||||||
|
this.assertAllocated();
|
||||||
|
long elemSize = switch (this.format) {
|
||||||
|
case GL_RGBA8, GL_DEPTH24_STENCIL8 -> 4;
|
||||||
|
case GL_DEPTH_COMPONENT24 -> 4;//TODO: check this is right????
|
||||||
|
|
||||||
|
default -> throw new IllegalStateException("Unknown element size");
|
||||||
|
};
|
||||||
|
|
||||||
|
long size = 0;
|
||||||
|
for (int lvl = 0; lvl < this.levels; lvl++) {
|
||||||
|
size += Math.max((((long)this.width)>>lvl), 1) * Math.max((((long)this.height)>>lvl), 1) * elemSize;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertAllocated() {
|
||||||
|
if (!this.hasAllocated) {
|
||||||
|
throw new IllegalStateException("Texture not yet allocated");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static int getCount() {
|
||||||
|
return COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getEstimatedTotalSize() {
|
||||||
|
return ESTIMATED_TOTAL_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
package me.cortex.voxy.client.core.gl.shader;
|
package me.cortex.voxy.client.core.gl.shader;
|
||||||
|
|
||||||
import com.mojang.blaze3d.opengl.GlConst;
|
|
||||||
import com.mojang.blaze3d.opengl.GlStateManager;
|
|
||||||
import me.cortex.voxy.client.core.gl.GlBuffer;
|
import me.cortex.voxy.client.core.gl.GlBuffer;
|
||||||
import me.cortex.voxy.client.core.gl.GlDebug;
|
import me.cortex.voxy.client.core.gl.GlDebug;
|
||||||
import me.cortex.voxy.client.core.gl.GlTexture;
|
import me.cortex.voxy.client.core.gl.GlTexture;
|
||||||
import me.cortex.voxy.common.util.Pair;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.ARBDirectStateAccess.glBindTextureUnit;
|
import static org.lwjgl.opengl.ARBDirectStateAccess.glBindTextureUnit;
|
||||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
|
||||||
import static org.lwjgl.opengl.GL30.glBindBufferBase;
|
import static org.lwjgl.opengl.GL30.glBindBufferBase;
|
||||||
import static org.lwjgl.opengl.GL30.glBindBufferRange;
|
import static org.lwjgl.opengl.GL30.glBindBufferRange;
|
||||||
import static org.lwjgl.opengl.GL31.GL_UNIFORM_BUFFER;
|
import static org.lwjgl.opengl.GL31.GL_UNIFORM_BUFFER;
|
||||||
@@ -117,8 +113,6 @@ public class AutoBindingShader extends Shader {
|
|||||||
for (var binding : this.textureBindings) {
|
for (var binding : this.textureBindings) {
|
||||||
if (binding.texture != null) {
|
if (binding.texture != null) {
|
||||||
binding.texture.assertNotFreed();
|
binding.texture.assertNotFreed();
|
||||||
GlStateManager._activeTexture(GlConst.GL_TEXTURE0+binding.unit);
|
|
||||||
GlStateManager._bindTexture(0);
|
|
||||||
glBindTextureUnit(binding.unit, binding.texture.id);
|
glBindTextureUnit(binding.unit, binding.texture.id);
|
||||||
}
|
}
|
||||||
if (binding.sampler != -1) {
|
if (binding.sampler != -1) {
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
package me.cortex.voxy.client.core.model.bakery;
|
package me.cortex.voxy.client.core.model.bakery;
|
||||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
|
||||||
import com.mojang.blaze3d.opengl.GlConst;
|
|
||||||
import com.mojang.blaze3d.opengl.GlStateManager;
|
|
||||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
|
||||||
import com.mojang.blaze3d.platform.DepthTestFunction;
|
|
||||||
import com.mojang.blaze3d.systems.RenderPass;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.textures.GpuTexture;
|
import com.mojang.blaze3d.textures.GpuTexture;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
@@ -12,22 +7,14 @@ import me.cortex.voxy.client.core.gl.GlBuffer;
|
|||||||
import me.cortex.voxy.client.core.gl.GlVertexArray;
|
import me.cortex.voxy.client.core.gl.GlVertexArray;
|
||||||
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.util.SharedIndexBuffer;
|
|
||||||
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||||
import me.cortex.voxy.common.util.UnsafeUtil;
|
import net.minecraft.client.gl.GlGpuBuffer;
|
||||||
import net.minecraft.client.gl.*;
|
|
||||||
import net.minecraft.client.render.BuiltBuffer;
|
import net.minecraft.client.render.BuiltBuffer;
|
||||||
import net.minecraft.client.render.VertexFormats;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.ARBVertexArrayObject.glBindVertexArray;
|
|
||||||
import static org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER;
|
|
||||||
import static org.lwjgl.opengl.GL15.glBindBuffer;
|
|
||||||
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
||||||
import static org.lwjgl.opengl.GL33.glBindSampler;
|
import static org.lwjgl.opengl.GL33.glBindSampler;
|
||||||
import static org.lwjgl.opengl.GL43.glBindVertexBuffer;
|
|
||||||
import static org.lwjgl.opengl.GL45.*;
|
import static org.lwjgl.opengl.GL45.*;
|
||||||
|
|
||||||
public class BudgetBufferRenderer {
|
public class BudgetBufferRenderer {
|
||||||
@@ -82,9 +69,6 @@ public class BudgetBufferRenderer {
|
|||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
GlStateManager._activeTexture(GlConst.GL_TEXTURE0);
|
|
||||||
GlStateManager._bindTexture(0);
|
|
||||||
|
|
||||||
quadCount = quads;
|
quadCount = quads;
|
||||||
|
|
||||||
long size = quads * 4L * STRIDE;
|
long size = quads * 4L * STRIDE;
|
||||||
@@ -101,6 +85,7 @@ public class BudgetBufferRenderer {
|
|||||||
|
|
||||||
bakeryShader.bind();
|
bakeryShader.bind();
|
||||||
VA.bind();
|
VA.bind();
|
||||||
|
glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
|
||||||
glBindSampler(0, 0);
|
glBindSampler(0, 0);
|
||||||
glBindTextureUnit(0, texId);
|
glBindTextureUnit(0, texId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ import net.minecraft.world.chunk.light.LightingProvider;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_FRAMEBUFFER_BARRIER_BIT;
|
import static org.lwjgl.opengl.ARBShaderImageLoadStore.*;
|
||||||
import static org.lwjgl.opengl.ARBShaderImageLoadStore.glMemoryBarrier;
|
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
import static org.lwjgl.opengl.GL14C.glBlendFuncSeparate;
|
import static org.lwjgl.opengl.GL14C.glBlendFuncSeparate;
|
||||||
import static org.lwjgl.opengl.GL30.*;
|
import static org.lwjgl.opengl.GL30.*;
|
||||||
@@ -268,7 +267,7 @@ public class ModelTextureBakery {
|
|||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
//Finish and download
|
//Finish and download
|
||||||
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
|
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT|GL_TEXTURE_UPDATE_BARRIER_BIT|GL_PIXEL_BUFFER_BARRIER_BIT|GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);//Am not sure if barriers are right
|
||||||
this.capture.emitToStream(streamBuffer, streamOffset);
|
this.capture.emitToStream(streamBuffer, streamOffset);
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, this.capture.framebuffer.id);
|
glBindFramebuffer(GL_FRAMEBUFFER, this.capture.framebuffer.id);
|
||||||
|
|||||||
@@ -39,15 +39,27 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
|
|
||||||
private final WorldEngine world;
|
private final WorldEngine world;
|
||||||
|
|
||||||
|
private static long getGeometryBufferSize() {
|
||||||
|
long geometryCapacity = Math.min((1L<<(64-Long.numberOfLeadingZeros(Capabilities.INSTANCE.ssboMaxSize-1)))<<1, 1L<<32)-1024/*(1L<<32)-1024*/;
|
||||||
|
//Limit to available dedicated memory if possible
|
||||||
|
if (Capabilities.INSTANCE.canQueryGpuMemory) {
|
||||||
|
//512mb less than avalible,
|
||||||
|
long limit = Capabilities.INSTANCE.getFreeDedicatedGpuMemory() - 512*1024*1024;
|
||||||
|
// Give a minimum of 512 mb requirement
|
||||||
|
limit = Math.max(512*1024*1024, limit);
|
||||||
|
|
||||||
|
geometryCapacity = Math.min(geometryCapacity, limit);
|
||||||
|
}
|
||||||
|
//geometryCapacity = 1<<24;
|
||||||
|
return geometryCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public RenderService(WorldEngine world, ServiceThreadPool serviceThreadPool) {
|
public RenderService(WorldEngine world, ServiceThreadPool serviceThreadPool) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.modelService = new ModelBakerySubsystem(world.getMapper());
|
this.modelService = new ModelBakerySubsystem(world.getMapper());
|
||||||
|
|
||||||
//Max geometry: 1 gb
|
long geometryCapacity = getGeometryBufferSize();
|
||||||
long geometryCapacity = Math.min((1L<<(64-Long.numberOfLeadingZeros(Capabilities.INSTANCE.ssboMaxSize-1)))<<1, 1L<<32)-1024/*(1L<<32)-1024*/;
|
|
||||||
//geometryCapacity = 1<<24;
|
|
||||||
|
|
||||||
this.geometryData = (Q) new BasicSectionGeometryData(1<<20, geometryCapacity);
|
this.geometryData = (Q) new BasicSectionGeometryData(1<<20, geometryCapacity);
|
||||||
|
|
||||||
//Max sections: ~500k
|
//Max sections: ~500k
|
||||||
@@ -102,7 +114,6 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
|
|
||||||
this.sectionRenderer.renderOpaque(viewport, depthBoundTexture);
|
this.sectionRenderer.renderOpaque(viewport, depthBoundTexture);
|
||||||
|
|
||||||
|
|
||||||
//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
|
||||||
|
|
||||||
|
|||||||
@@ -130,21 +130,21 @@ public class AsyncNodeManager {
|
|||||||
private void run() {
|
private void run() {
|
||||||
if (this.workCounter.get() == 0) {
|
if (this.workCounter.get() == 0) {
|
||||||
LockSupport.park();
|
LockSupport.park();
|
||||||
if (this.workCounter.get() == 0) {//No work
|
if (this.workCounter.get() == 0 || !this.running) {//No work
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//This is a funny thing, wait a bit, this allows for better batching, but this thread is independent of everything else so waiting a bit should be mostly ok
|
||||||
|
try {
|
||||||
|
Thread.sleep(25);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.running) {
|
if (!this.running) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is a funny thing, wait a bit, this allows for better batching, but this thread is independent of everything else so waiting a bit should be mostly ok
|
|
||||||
try {
|
|
||||||
Thread.sleep(10);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
int workDone = 0;
|
int workDone = 0;
|
||||||
|
|
||||||
@@ -370,8 +370,14 @@ public class AsyncNodeManager {
|
|||||||
int val = iter.nextInt();
|
int val = iter.nextInt();
|
||||||
int placeId = results.geometryIdUpdateMap.putIfAbsent(val, results.geometryIdUpdateMap.size());
|
int placeId = results.geometryIdUpdateMap.putIfAbsent(val, results.geometryIdUpdateMap.size());
|
||||||
placeId = placeId==-1?results.geometryIdUpdateMap.size()-1:placeId;
|
placeId = placeId==-1?results.geometryIdUpdateMap.size()-1:placeId;
|
||||||
if (512<=placeId) {
|
if (results.geometryIdUpdateData.size<=placeId*32L) {
|
||||||
throw new IllegalStateException("Outside range of allowed updates");
|
//We need to expand the buffer :(
|
||||||
|
var old = results.geometryIdUpdateData;
|
||||||
|
var newBuffer = new MemoryBuffer((long) (old.size*1.5));
|
||||||
|
Logger.info("Expanding geometry update buffer to " + newBuffer.size);
|
||||||
|
old.cpyTo(newBuffer.address);
|
||||||
|
old.free();
|
||||||
|
results.geometryIdUpdateData = newBuffer;
|
||||||
}
|
}
|
||||||
//Write updated data
|
//Write updated data
|
||||||
this.geometryManager.writeMetadata(val, placeId*32L + results.geometryIdUpdateData.address);
|
this.geometryManager.writeMetadata(val, placeId*32L + results.geometryIdUpdateData.address);
|
||||||
@@ -388,8 +394,14 @@ public class AsyncNodeManager {
|
|||||||
int val = iter.nextInt();
|
int val = iter.nextInt();
|
||||||
int placeId = results.nodeIdUpdateMap.putIfAbsent(val, results.nodeIdUpdateMap.size());
|
int placeId = results.nodeIdUpdateMap.putIfAbsent(val, results.nodeIdUpdateMap.size());
|
||||||
placeId = placeId==-1?results.nodeIdUpdateMap.size()-1:placeId;
|
placeId = placeId==-1?results.nodeIdUpdateMap.size()-1:placeId;
|
||||||
if (1024<=placeId) {
|
if (results.nodeIdUpdateData.size<=placeId*16L) {
|
||||||
throw new IllegalStateException("Outside range of allowed updates");
|
//We need to expand the buffer :(
|
||||||
|
var old = results.nodeIdUpdateData;
|
||||||
|
var newBuffer = new MemoryBuffer((long) (old.size*1.5));
|
||||||
|
Logger.info("Expanding node update buffer to " + newBuffer.size);
|
||||||
|
old.cpyTo(newBuffer.address);
|
||||||
|
old.free();
|
||||||
|
results.nodeIdUpdateData = newBuffer;
|
||||||
}
|
}
|
||||||
//Write updated data
|
//Write updated data
|
||||||
this.manager.writeNode(val, placeId*16L + results.nodeIdUpdateData.address);
|
this.manager.writeNode(val, placeId*16L + results.nodeIdUpdateData.address);
|
||||||
@@ -633,7 +645,7 @@ public class AsyncNodeManager {
|
|||||||
|
|
||||||
//Node id updates + size
|
//Node id updates + size
|
||||||
private final Int2IntOpenHashMap nodeIdUpdateMap = new Int2IntOpenHashMap();//node id to update data location
|
private final Int2IntOpenHashMap nodeIdUpdateMap = new Int2IntOpenHashMap();//node id to update data location
|
||||||
private final MemoryBuffer nodeIdUpdateData = new MemoryBuffer(8192*2);//capacity for 1024 entries, TODO: ADD RESIZE
|
private MemoryBuffer nodeIdUpdateData = new MemoryBuffer(8192*2);//capacity for 1024 entries, TODO: ADD RESIZE
|
||||||
private int currentMaxNodeId;// the id of the ending of the node ids
|
private int currentMaxNodeId;// the id of the ending of the node ids
|
||||||
|
|
||||||
//TLN add/rem
|
//TLN add/rem
|
||||||
@@ -643,7 +655,7 @@ public class AsyncNodeManager {
|
|||||||
private int geometrySectionCount;
|
private int geometrySectionCount;
|
||||||
private final Int2ObjectOpenHashMap<MemoryBuffer> geometryUploads = new Int2ObjectOpenHashMap<>();
|
private final Int2ObjectOpenHashMap<MemoryBuffer> geometryUploads = new Int2ObjectOpenHashMap<>();
|
||||||
private final Int2IntOpenHashMap geometryIdUpdateMap = new Int2IntOpenHashMap();//geometry id to update data location
|
private final Int2IntOpenHashMap geometryIdUpdateMap = new Int2IntOpenHashMap();//geometry id to update data location
|
||||||
private final MemoryBuffer geometryIdUpdateData = new MemoryBuffer(8192*2);//capacity for 512 entries, TODO: ADD RESIZE
|
private MemoryBuffer geometryIdUpdateData = new MemoryBuffer(8192*2);//capacity for 512 entries, TODO: ADD RESIZE
|
||||||
|
|
||||||
|
|
||||||
public SyncResults() {
|
public SyncResults() {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ out vec4 colour;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
colour = texture(tex, texCoord);
|
colour = texture(tex, texCoord);
|
||||||
if (colour.a < 0.0001f && ((metadata&1u)!=0)) {
|
if (colour.a < 0.001f && ((metadata&1u)!=0)) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user