Add support for FREX flawless frames, failed attempt to fix intel igpus
This commit is contained in:
@@ -6,11 +6,17 @@ import me.cortex.voxy.commonImpl.VoxyCommon;
|
|||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
|
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class VoxyClient implements ClientModInitializer {
|
public class VoxyClient implements ClientModInitializer {
|
||||||
|
private static final HashSet<String> FREX = new HashSet<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
|
|
||||||
ClientLifecycleEvents.CLIENT_STARTED.register(client->{
|
ClientLifecycleEvents.CLIENT_STARTED.register(client->{
|
||||||
boolean systemSupported = Capabilities.INSTANCE.compute && Capabilities.INSTANCE.indirectParameters;
|
boolean systemSupported = Capabilities.INSTANCE.compute && Capabilities.INSTANCE.indirectParameters;
|
||||||
if (systemSupported) {
|
if (systemSupported) {
|
||||||
@@ -26,5 +32,17 @@ public class VoxyClient implements ClientModInitializer {
|
|||||||
dispatcher.register(VoxyCommands.register());
|
dispatcher.register(VoxyCommands.register());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
FabricLoader.getInstance()
|
||||||
|
.getEntrypoints("frex_flawless_frames", Consumer.class)
|
||||||
|
.forEach(api -> ((Consumer<Function<String,Consumer<Boolean>>>)api).accept(name->active->{if (active) {
|
||||||
|
FREX.add(name);
|
||||||
|
} else {
|
||||||
|
FREX.remove(name);
|
||||||
|
}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isFrexActive() {
|
||||||
|
return !FREX.isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.mojang.blaze3d.opengl.GlConst;
|
|||||||
import com.mojang.blaze3d.opengl.GlStateManager;
|
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.VoxyClient;
|
||||||
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;
|
||||||
@@ -233,7 +234,7 @@ public class VoxyRenderSystem {
|
|||||||
//Tick upload stream (this is ok to do here as upload ticking is just memory management)
|
//Tick upload stream (this is ok to do here as upload ticking is just memory management)
|
||||||
UploadStream.INSTANCE.tick();
|
UploadStream.INSTANCE.tick();
|
||||||
|
|
||||||
this.renderDistanceTracker.setCenterAndProcess(cameraX, cameraZ);
|
while (this.renderDistanceTracker.setCenterAndProcess(cameraX, cameraZ) && VoxyClient.isFrexActive());//While FF is active, run until everything is processed
|
||||||
|
|
||||||
//Done here as is allows less gl state resetup
|
//Done here as is allows less gl state resetup
|
||||||
this.renderer.tickModelService(Math.max(3_000_000-(System.nanoTime()-startTime), 500_000));
|
this.renderer.tickModelService(Math.max(3_000_000-(System.nanoTime()-startTime), 500_000));
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public class Capabilities {
|
|||||||
public final long totalDynamicMemory;//Bytes, total allocation memory - dedicated memory
|
public final long totalDynamicMemory;//Bytes, total allocation memory - dedicated memory
|
||||||
public final boolean compute;
|
public final boolean compute;
|
||||||
public final boolean indirectParameters;
|
public final boolean indirectParameters;
|
||||||
|
public final boolean isIntel;
|
||||||
|
|
||||||
public Capabilities() {
|
public Capabilities() {
|
||||||
var cap = GL.getCapabilities();
|
var cap = GL.getCapabilities();
|
||||||
this.compute = cap.glDispatchComputeIndirect != 0;
|
this.compute = cap.glDispatchComputeIndirect != 0;
|
||||||
@@ -42,6 +44,7 @@ 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");
|
||||||
|
this.isIntel = glGetString(GL_VENDOR).toLowerCase().contains("intel");
|
||||||
|
|
||||||
if (this.canQueryGpuMemory) {
|
if (this.canQueryGpuMemory) {
|
||||||
this.totalDedicatedMemory = glGetInteger64(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX)*1024;//Since its in Kb
|
this.totalDedicatedMemory = glGetInteger64(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX)*1024;//Since its in Kb
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package me.cortex.voxy.client.core.gl.shader;
|
package me.cortex.voxy.client.core.gl.shader;
|
||||||
|
|
||||||
|
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.GlDebug;
|
import me.cortex.voxy.client.core.gl.GlDebug;
|
||||||
import me.cortex.voxy.common.Logger;
|
import me.cortex.voxy.common.Logger;
|
||||||
@@ -147,6 +148,7 @@ public class Shader extends TrackedObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public T compile() {
|
public T compile() {
|
||||||
|
this.defineIf("IS_INTEL", Capabilities.INSTANCE.isIntel);
|
||||||
return this.constructor.make(this, this.compileToProgram());
|
return this.constructor.make(this, this.compileToProgram());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class RenderDistanceTracker {
|
|||||||
this.tracker = new RingTracker(this.tracker, renderDistance, ((int)this.posX)>>9, ((int)this.posZ)>>9, true);//Steal from previous tracker
|
this.tracker = new RingTracker(this.tracker, renderDistance, ((int)this.posX)>>9, ((int)this.posZ)>>9, true);//Steal from previous tracker
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCenterAndProcess(double x, double z) {
|
public boolean setCenterAndProcess(double x, double z) {
|
||||||
double dx = this.posX-x;
|
double dx = this.posX-x;
|
||||||
double dz = this.posZ-z;
|
double dz = this.posZ-z;
|
||||||
if (CHECK_DISTANCE_BLOCKS*CHECK_DISTANCE_BLOCKS<dx*dx+dz*dz) {
|
if (CHECK_DISTANCE_BLOCKS*CHECK_DISTANCE_BLOCKS<dx*dx+dz*dz) {
|
||||||
@@ -43,7 +43,7 @@ public class RenderDistanceTracker {
|
|||||||
this.posZ = z;
|
this.posZ = z;
|
||||||
this.tracker.moveCenter(((int)x)>>9, ((int)z)>>9);
|
this.tracker.moveCenter(((int)x)>>9, ((int)z)>>9);
|
||||||
}
|
}
|
||||||
this.tracker.process(this.processRate, this::add, this::rem);
|
return this.tracker.process(this.processRate, this::add, this::rem)!=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(int x, int z) {
|
private void add(int x, int z) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package me.cortex.voxy.client.core.rendering;
|
|||||||
|
|
||||||
import me.cortex.voxy.client.RenderStatistics;
|
import me.cortex.voxy.client.RenderStatistics;
|
||||||
import me.cortex.voxy.client.TimingStatistics;
|
import me.cortex.voxy.client.TimingStatistics;
|
||||||
|
import me.cortex.voxy.client.VoxyClient;
|
||||||
import me.cortex.voxy.client.core.gl.Capabilities;
|
import me.cortex.voxy.client.core.gl.Capabilities;
|
||||||
import me.cortex.voxy.client.core.gl.GlTexture;
|
import me.cortex.voxy.client.core.gl.GlTexture;
|
||||||
import me.cortex.voxy.client.core.model.ModelBakerySubsystem;
|
import me.cortex.voxy.client.core.model.ModelBakerySubsystem;
|
||||||
@@ -14,6 +15,7 @@ import me.cortex.voxy.client.core.rendering.section.geometry.*;
|
|||||||
import me.cortex.voxy.client.core.rendering.section.IUsesMeshlets;
|
import me.cortex.voxy.client.core.rendering.section.IUsesMeshlets;
|
||||||
import me.cortex.voxy.client.core.rendering.section.MDICSectionRenderer;
|
import me.cortex.voxy.client.core.rendering.section.MDICSectionRenderer;
|
||||||
import me.cortex.voxy.client.core.rendering.util.DownloadStream;
|
import me.cortex.voxy.client.core.rendering.util.DownloadStream;
|
||||||
|
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||||
import me.cortex.voxy.common.Logger;
|
import me.cortex.voxy.common.Logger;
|
||||||
import me.cortex.voxy.common.world.WorldEngine;
|
import me.cortex.voxy.common.world.WorldEngine;
|
||||||
import me.cortex.voxy.common.thread.ServiceThreadPool;
|
import me.cortex.voxy.common.thread.ServiceThreadPool;
|
||||||
@@ -117,18 +119,12 @@ 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();
|
||||||
|
|
||||||
//NOTE: need to do the upload and download tick here, after the section renderer renders the world, to ensure "stable"
|
do {
|
||||||
// sections
|
//NOTE: need to do the upload and download tick here, after the section renderer renders the world, to ensure "stable"
|
||||||
|
// sections
|
||||||
|
{
|
||||||
//FIXME: we only want to tick once per full frame, this is due to how the data of sections is updated
|
TimingStatistics.main.stop();
|
||||||
// we basicly need the data to stay stable from one frame to the next, till after renderOpaque
|
TimingStatistics.dynamic.start();
|
||||||
// this is because e.g. shadows, cause this pipeline to be invoked multiple times
|
|
||||||
// which may cause the geometry to become outdated resulting in corruption rendering in renderOpaque
|
|
||||||
//TODO: Need to find a proper way to fix this (if there even is one)
|
|
||||||
{
|
|
||||||
TimingStatistics.main.stop();
|
|
||||||
TimingStatistics.dynamic.start();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
this.sectionUpdateQueue.consume(128);
|
this.sectionUpdateQueue.consume(128);
|
||||||
@@ -143,29 +139,40 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
TimingStatistics.D.start();
|
TimingStatistics.D.start();
|
||||||
//Tick download stream
|
//Tick download stream
|
||||||
DownloadStream.INSTANCE.tick();
|
DownloadStream.INSTANCE.tick();
|
||||||
TimingStatistics.D.stop();
|
TimingStatistics.D.stop();
|
||||||
|
|
||||||
this.nodeManager.tick(this.traversal.getNodeBuffer(), this.nodeCleaner);
|
this.nodeManager.tick(this.traversal.getNodeBuffer(), this.nodeCleaner);
|
||||||
//glFlush();
|
//glFlush();
|
||||||
|
|
||||||
this.nodeCleaner.tick(this.traversal.getNodeBuffer());//Probably do this here??
|
this.nodeCleaner.tick(this.traversal.getNodeBuffer());//Probably do this here??
|
||||||
|
|
||||||
TimingStatistics.dynamic.stop();
|
TimingStatistics.dynamic.stop();
|
||||||
TimingStatistics.main.start();
|
TimingStatistics.main.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
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_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||||
|
if (depthBuffer == 0) {
|
||||||
|
depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimingStatistics.I.start();
|
||||||
|
this.traversal.doTraversal(viewport, depthBuffer);
|
||||||
|
TimingStatistics.I.stop();
|
||||||
|
|
||||||
|
|
||||||
|
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()));
|
||||||
|
|
||||||
int depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
|
||||||
if (depthBuffer == 0) {
|
|
||||||
depthBuffer = glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
|
||||||
}
|
|
||||||
TimingStatistics.I.start();
|
|
||||||
this.traversal.doTraversal(viewport, depthBuffer);
|
|
||||||
TimingStatistics.I.stop();
|
|
||||||
|
|
||||||
TimingStatistics.H.start();
|
TimingStatistics.H.start();
|
||||||
this.sectionRenderer.buildDrawCalls(viewport);
|
this.sectionRenderer.buildDrawCalls(viewport);
|
||||||
|
|||||||
@@ -717,6 +717,10 @@ public class AsyncNodeManager {
|
|||||||
debug.add("UC/GC: " + (this.getUsedGeometryCapacity()/(1<<20))+"/"+(this.getGeometryCapacity()/(1<<20)));
|
debug.add("UC/GC: " + (this.getUsedGeometryCapacity()/(1<<20))+"/"+(this.getGeometryCapacity()/(1<<20)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasWork() {
|
||||||
|
return this.workCounter.get()!=0 && RESULT_HANDLE.get(this) != null;
|
||||||
|
}
|
||||||
|
|
||||||
//Results object, which is to be synced between the render thread and worker thread
|
//Results object, which is to be synced between the render thread and worker thread
|
||||||
private static final class SyncResults {
|
private static final class SyncResults {
|
||||||
//Contains
|
//Contains
|
||||||
|
|||||||
@@ -43,12 +43,20 @@ void main() {
|
|||||||
|
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
|
#ifdef IS_INTEL
|
||||||
|
uint val = subgroupExclusiveAdd(warpPrefixSum[gl_SubgroupInvocationID]);
|
||||||
|
barrier();
|
||||||
|
if (gl_SubgroupID == 0) {
|
||||||
|
warpPrefixSum[gl_SubgroupInvocationID] = val;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (gl_SubgroupID == 0) {
|
if (gl_SubgroupID == 0) {
|
||||||
uint val = warpPrefixSum[gl_SubgroupInvocationID];
|
uint val = warpPrefixSum[gl_SubgroupInvocationID];
|
||||||
subgroupBarrier();
|
subgroupBarrier();
|
||||||
//Use warp to do entire add in 1 reduction
|
//Use warp to do entire add in 1 reduction
|
||||||
warpPrefixSum[gl_SubgroupInvocationID] = subgroupExclusiveAdd(val);
|
warpPrefixSum[gl_SubgroupInvocationID] = subgroupExclusiveAdd(val);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
barrier();
|
barrier();
|
||||||
//Add the computed sum across all threads and warps
|
//Add the computed sum across all threads and warps
|
||||||
|
|||||||
Reference in New Issue
Block a user