Skip to content

Commit

Permalink
Merge pull request #325 from thr3343/NativeWaylandTestV3.2-Final
Browse files Browse the repository at this point in the history
Add native Wayland support + Minor performance optimisations
  • Loading branch information
xCollateral authored Nov 18, 2023
2 parents 0537d53 + 6d7487c commit 74b12ca
Show file tree
Hide file tree
Showing 34 changed files with 537 additions and 329 deletions.
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

0 comments on commit 74b12ca

Please sign in to comment.