Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Native Wayland Support V2 + Minor Nvidia/Performance Optimisations #325

Merged
merged 8 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/main/java/net/vulkanmod/config/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
import com.mojang.blaze3d.platform.Window;
import net.minecraft.client.*;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.contents.LiteralContents;
import net.minecraft.network.chat.contents.TranslatableContents;
import net.vulkanmod.Initializer;
import net.vulkanmod.vulkan.Drawer;
import net.vulkanmod.vulkan.Device;
import net.vulkanmod.vulkan.Renderer;
import org.lwjgl.system.MemoryStack;

import static net.vulkanmod.vulkan.Device.device;

public class Options {
static net.minecraft.client.Options minecraftOptions = Minecraft.getInstance().options;
static Config config = Initializer.CONFIG;
static Window window = Minecraft.getInstance().getWindow();
public static boolean fullscreenDirty = false;


public static Option<?>[] getVideoOpts() {
return new Option[] {
new CyclingOption<>("Resolution",
Expand Down Expand Up @@ -168,14 +168,15 @@ public static Option<?>[] getGraphicsOpts() {

public static Option<?>[] getOtherOpts() {
return new Option[] {
new RangeOption("Queue Frames", 2,
new RangeOption("Render queue size", 2,
5, 1,
value -> {
config.frameQueueSize = value;
Renderer.scheduleSwapChainUpdate();
}, () -> config.frameQueueSize)
.setTooltip(Component.nullToEmpty("""
Sets the number of queue frames""")),
Higher values might help stabilize frametime
but will increase input lag""")),
new SwitchOption("Gui Optimizations",
value -> config.guiOptimizations = value,
() -> config.guiOptimizations)
Expand Down Expand Up @@ -205,7 +206,7 @@ Enable Gui optimizations (Stats bar, Chat, Debug Hud)
value -> config.entityCulling = value,
() -> config.entityCulling)
.setTooltip(Component.nullToEmpty("""
Enables culling for entities on non visible sections.""")),
Enables culling for entities on not visible sections.""")),
new SwitchOption("Indirect Draw",
value -> config.indirectDraw = value,
() -> config.indirectDraw)
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/net/vulkanmod/config/VideoResolution.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@

import com.mojang.blaze3d.platform.VideoMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.apache.commons.lang3.SystemUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static net.vulkanmod.Initializer.LOGGER;
import static org.lwjgl.glfw.GLFW.*;

public class VideoResolution {
private static VideoResolution[] videoResolutions;
private static final int activePlat = getSupportedPlat();

int width;
int height;
Expand Down Expand Up @@ -52,10 +57,56 @@ public int[] refreshRates() {

public static void init() {
RenderSystem.assertOnRenderThread();
GLFW.glfwInitHint(GLFW_PLATFORM, activePlat);
LOGGER.info("Selecting Platform: "+getStringFromPlat(activePlat));
LOGGER.info("GLFW: "+GLFW.glfwGetVersionString());
GLFW.glfwInit();
videoResolutions = populateVideoResolutions(GLFW.glfwGetPrimaryMonitor());
}

//Actually detect the currently active Display Server (if both Wayland and X11 are present on the system and/or GLFW is compiled to support both)
private static int determineDisplayServer() {

//Return Null platform if not on Linux (i.e. no X11 or Wayland)
String xdgSessionType = System.getenv("XDG_SESSION_TYPE");
if(xdgSessionType==null) return GLFW_ANY_PLATFORM; //Likely Android
return switch (xdgSessionType) {
case "wayland" -> GLFW_PLATFORM_WAYLAND; //Wayland
case "x11" -> GLFW_PLATFORM_X11; //X11
default -> GLFW_ANY_PLATFORM; //Either unknown Platform or Display Server
};
}

private static int getSupportedPlat() {
//Switch statement would be ideal, but couldn't find a good way of implementing it, so fell back to basic if statements/branches
if(SystemUtils.IS_OS_WINDOWS) return GLFW_PLATFORM_WIN32;
if(SystemUtils.IS_OS_MAC_OSX) return GLFW_PLATFORM_COCOA;
if(SystemUtils.IS_OS_LINUX) return determineDisplayServer(); //Linux Or Android

return GLFW_ANY_PLATFORM; //Unknown platform
}

private static String getStringFromPlat(int plat) {
return switch (plat)
{
case GLFW_PLATFORM_WIN32 -> "WIN32";
case GLFW_PLATFORM_WAYLAND -> "WAYLAND";
case GLFW_PLATFORM_X11 -> "X11";
case GLFW_PLATFORM_COCOA -> "MACOS";
case GLFW_ANY_PLATFORM -> "ANDROID";
default -> throw new IllegalStateException("Unexpected value: " + plat);
};
}

public static int getActivePlat() { return activePlat; }

//Allows platform specific checks to be handled
public static boolean isWayLand() { return activePlat == GLFW_PLATFORM_WAYLAND; }
public static boolean isX11() { return activePlat == GLFW_PLATFORM_X11; }
public static boolean isWindows() { return activePlat == GLFW_PLATFORM_WIN32; }
public static boolean isMacOS() { return activePlat == GLFW_PLATFORM_COCOA; }
public static boolean isAndroid() { return activePlat == GLFW_ANY_PLATFORM; }

public static VideoResolution[] getVideoResolutions() {
return videoResolutions;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/vulkanmod/mixin/debug/GlDebugInfoM.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class GlDebugInfoM {
*/
@Overwrite
public static String getVendor() {
return Vulkan.getDeviceInfo() != null ? Vulkan.getDeviceInfo().vendorId : "n/a";
return Vulkan.getDeviceInfo() != null ? Vulkan.getDeviceInfo().vendorIdString : "n/a";
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.ResourceProvider;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.VRenderSystem;
import net.vulkanmod.vulkan.memory.MemoryManager;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
Expand All @@ -19,6 +21,7 @@
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.io.IOException;
Expand Down Expand Up @@ -344,4 +347,12 @@ public void preloadUiShader(ResourceProvider resourceProvider) {
}
}

// @Redirect(method = "renderLevel", at = @At(value="INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V"))
// private void clear2hand(int i, boolean bl) {
// Renderer.clearAttachments(0x100);
// }

@Redirect(method = "render", at = @At(value="INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V", ordinal = 0))
private void remClear(int i, boolean bl) {}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package net.vulkanmod.mixin.render;

import com.mojang.blaze3d.pipeline.RenderTarget;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.PostChain;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(LevelRenderer.class)
public abstract class LevelRendererMixin {
Expand Down Expand Up @@ -37,4 +40,10 @@ public void initOutline() {
// this.entityOutlinesFramebuffer = null;
// }
}

@Redirect(method = "renderLevel", at=@At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V"))
private void redirectClear2(int i, boolean bl) {}

@Redirect(method = "renderLevel", at=@At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;clear(Z)V"))
private void redirectClear(RenderTarget instance, boolean bl) {}
}
36 changes: 3 additions & 33 deletions src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,13 @@
import net.minecraft.client.GraphicsStatus;
import net.minecraft.client.Minecraft;
import net.minecraft.client.Options;
import net.minecraft.client.gui.font.FontManager;
import net.minecraft.client.main.GameConfig;
import net.minecraft.client.particle.ParticleEngine;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.VirtualScreen;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.resources.MobEffectTextureManager;
import net.minecraft.client.resources.PaintingTextureManager;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.sounds.SoundManager;
import net.minecraft.server.packs.resources.ReloadableResourceManager;
import net.vulkanmod.Initializer;
import net.vulkanmod.render.profiling.Profiler2;
import net.vulkanmod.render.texture.SpriteUtil;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.Vulkan;
import org.slf4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
Expand All @@ -41,19 +27,6 @@
@Mixin(Minecraft.class)
public class MinecraftMixin {

@Shadow @Final public ParticleEngine particleEngine;
@Shadow @Final public GameRenderer gameRenderer;
@Shadow @Final private ReloadableResourceManager resourceManager;
@Shadow @Final private FontManager fontManager;
@Shadow @Final private ModelManager modelManager;
@Shadow @Final private SoundManager soundManager;
@Shadow @Final private TextureManager textureManager;
@Shadow @Final private VirtualScreen virtualScreen;
@Shadow @Final private Window window;
@Shadow @Final private static Logger LOGGER;
@Shadow @Final public LevelRenderer levelRenderer;
@Shadow @Final private MobEffectTextureManager mobEffectTextures;
@Shadow @Final private PaintingTextureManager paintingTextures;
@Shadow public boolean noRender;
@Shadow @Final public Options options;

Expand Down Expand Up @@ -115,19 +88,16 @@ private void resetBuffers(boolean bl, CallbackInfo ci) {
Renderer.getInstance().resetBuffers();
}


@Inject(method = "close", at = @At(value = "HEAD"))
public void close(CallbackInfo ci) {
Vulkan.waitIdle();

}
@Inject(method = "close", at = @At(value = "RETURN"))
public void close2(CallbackInfo ci) {

Vulkan.cleanUp();

@Inject(method = "close", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/VirtualScreen;close()V"))
public void close2(CallbackInfo ci) {
Vulkan.cleanUp();
Util.shutdownExecutors();

}

@Redirect(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;emergencySave()V"))
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/net/vulkanmod/mixin/wayland/InputConstantsM.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.vulkanmod.mixin.wayland;

import com.mojang.blaze3d.platform.InputConstants;
import net.vulkanmod.config.VideoResolution;
import org.lwjgl.glfw.*;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(InputConstants.class)
public class InputConstantsM {
/**
* @author
* @reason Setting the cursor position is not supported on Wayland
*/
@Overwrite
public static void grabOrReleaseMouse(long l, int i, double d, double e) {
if (!VideoResolution.isWayLand())
GLFW.glfwSetCursorPos(l, d, e);
GLFW.glfwSetInputMode(l, 208897, i);
}
}
38 changes: 38 additions & 0 deletions src/main/java/net/vulkanmod/mixin/wayland/MinecraftMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package net.vulkanmod.mixin.wayland;

import com.mojang.blaze3d.platform.IconSet;
import com.mojang.blaze3d.platform.Window;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.client.Options;
import net.minecraft.server.packs.PackResources;
import net.minecraft.server.packs.VanillaPackResources;
import net.vulkanmod.config.VideoResolution;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import java.io.IOException;

@Mixin(Minecraft.class)
public class MinecraftMixin {

@Shadow @Final private Window window;
@Shadow @Final public Options options;

@Shadow @Final private VanillaPackResources vanillaPackResources;

/**
* @author
* @reason Only KWin supports setting the Icon on Wayland AFAIK
*/
@Redirect(method="<init>", at=@At(value="INVOKE", target="Lcom/mojang/blaze3d/platform/Window;setIcon(Lnet/minecraft/server/packs/PackResources;Lcom/mojang/blaze3d/platform/IconSet;)V"))
private void bypassWaylandIcon(Window instance, PackResources packResources, IconSet iconSet) throws IOException {
if(!VideoResolution.isWayLand())
{
this.window.setIcon(this.vanillaPackResources, SharedConstants.getCurrentVersion().isStable() ? IconSet.RELEASE : IconSet.SNAPSHOT);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void uploadAsync(AreaBuffer.Segment uploadSegment, long bufferId, long ds

VkCommandBuffer commandBuffer = commandBuffers[currentFrame].getHandle();

StagingBuffer stagingBuffer = Vulkan.getStagingBuffer(this.currentFrame);
StagingBuffer stagingBuffer = Vulkan.getStagingBuffer();
stagingBuffer.copyBuffer((int) bufferSize, src);

if(!dstBuffers.add(bufferId)) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/net/vulkanmod/render/chunk/ChunkArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.minecraft.core.BlockPos;
import net.vulkanmod.render.chunk.util.ResettableQueue;
import net.vulkanmod.render.chunk.util.StaticQueue;
import org.joml.FrustumIntersection;
import org.joml.Vector3i;

Expand All @@ -15,7 +16,8 @@ public class ChunkArea {

DrawBuffers drawBuffers;

final ResettableQueue<RenderSection> sectionQueue = new ResettableQueue<>();
//Help JIT optimisations by hardcoding the queue size to the max possible ChunkArea limit
final StaticQueue<RenderSection> sectionQueue = new StaticQueue<>(512);

public ChunkArea(int i, Vector3i origin) {
this.index = i;
Expand Down
Loading
Loading