From e6fdcf22409034d900074859585c29e139221787 Mon Sep 17 00:00:00 2001 From: Vcmp <125277899+thr3343@users.noreply.github.com> Date: Tue, 5 Sep 2023 12:47:01 +0100 Subject: [PATCH 1/4] Add Native Wayland Support --- .../java/net/vulkanmod/config/Options.java | 14 +++---- .../net/vulkanmod/config/VideoResolution.java | 41 +++++++++++++++++++ .../vulkanmod/mixin/debug/GlDebugInfoM.java | 2 +- .../mixin/render/MinecraftMixin.java | 16 ++++++++ .../java/net/vulkanmod/vulkan/DeviceInfo.java | 18 +++++++- .../vulkan/framebuffer/SwapChain.java | 6 ++- 6 files changed, 85 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/vulkanmod/config/Options.java b/src/main/java/net/vulkanmod/config/Options.java index b6e4312a1..f2921c3d7 100644 --- a/src/main/java/net/vulkanmod/config/Options.java +++ b/src/main/java/net/vulkanmod/config/Options.java @@ -3,13 +3,15 @@ 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.Renderer; +import net.vulkanmod.vulkan.Vulkan; public class Options { + + //Fix Glitches+Crashes if Wayland and the Mesa RADV driver are used, and the available SwapChain images are set above 2 (possible RADV Bug?) + private static final boolean limitSwapChain = VideoResolution.isWayLand() && Vulkan.getDeviceInfo().isAMD(); static net.minecraft.client.Options minecraftOptions = Minecraft.getInstance().options; static Config config = Initializer.CONFIG; static Window window = Minecraft.getInstance().getWindow(); @@ -51,9 +53,7 @@ public static Option[] getVideoOpts() { new SwitchOption("VSync", value -> { minecraftOptions.enableVsync().set(value); - if (Minecraft.getInstance().getWindow() != null) { - Minecraft.getInstance().getWindow().updateVsync(value); - } + Minecraft.getInstance().getWindow().updateVsync(value); }, () -> minecraftOptions.enableVsync().get()), new CyclingOption<>("Gui Scale", @@ -170,8 +170,8 @@ public static Option[] getGraphicsOpts() { public static Option[] getOtherOpts() { return new Option[] { - new RangeOption("Queue Frames", 2, - 5, 1, + new RangeOption("RenderFrameQueue", 2, + limitSwapChain ? 2 : 5, 1, value -> { config.frameQueueSize = value; Renderer.scheduleSwapChainUpdate(); diff --git a/src/main/java/net/vulkanmod/config/VideoResolution.java b/src/main/java/net/vulkanmod/config/VideoResolution.java index 032ebcb17..ebc16fd91 100644 --- a/src/main/java/net/vulkanmod/config/VideoResolution.java +++ b/src/main/java/net/vulkanmod/config/VideoResolution.java @@ -9,9 +9,20 @@ 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; + //Make sure Wayland is ALWAYS preferred in 100% of cases (and only fallback to X11 if Wayland isn't available) + private static final int[] plats = new int[]{ + GLFW_PLATFORM_WIN32, + GLFW_PLATFORM_WAYLAND, + GLFW_PLATFORM_X11}; + + private static final int activePlat = getSupportedPlat(); + int width; int height; int refreshRate; @@ -49,13 +60,43 @@ public int[] refreshRates() { return arr; } + //Prioritise Wayland over X11 if xWayland (if correct) is present public static void init() { RenderSystem.assertOnRenderThread(); + GLFW.glfwInitHint(GLFW_PLATFORM, activePlat); GLFW.glfwInit(); videoResolutions = populateVideoResolutions(GLFW.glfwGetPrimaryMonitor()); } + private static int getSupportedPlat() { + + for (int plat : plats) { + if(GLFW.glfwPlatformSupported(plat)) + { + LOGGER.info("Selecting Platform: "+getStringFromPlat(plat)); + return plat; + } + } + throw new RuntimeException("No Supported Platforms Present!"); + } + + private static String getStringFromPlat(int plat) { + return switch (plat) + { + case GLFW_PLATFORM_WIN32 -> "WIN32"; + case GLFW_PLATFORM_WAYLAND -> "WAYLAND"; + case GLFW_PLATFORM_X11 -> "X11"; + default -> throw new IllegalStateException("Unexpected value: " + plat); + }; + } + + public static int getActivePlat() { return activePlat; } + //Allows platform specific checks to be handles (is missing macOS, however that may not be important due to macOS only version)) + 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 VideoResolution[] getVideoResolutions() { return videoResolutions; } diff --git a/src/main/java/net/vulkanmod/mixin/debug/GlDebugInfoM.java b/src/main/java/net/vulkanmod/mixin/debug/GlDebugInfoM.java index c41e518ea..254c82b43 100644 --- a/src/main/java/net/vulkanmod/mixin/debug/GlDebugInfoM.java +++ b/src/main/java/net/vulkanmod/mixin/debug/GlDebugInfoM.java @@ -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"; } /** diff --git a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java index 98f45490b..80dfd541a 100644 --- a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java @@ -1,8 +1,10 @@ package net.vulkanmod.mixin.render; import com.mojang.blaze3d.pipeline.RenderTarget; +import com.mojang.blaze3d.platform.IconSet; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.systems.TimerQuery; +import net.minecraft.SharedConstants; import net.minecraft.Util; import net.minecraft.client.Minecraft; @@ -17,7 +19,10 @@ import net.minecraft.client.resources.PaintingTextureManager; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.client.sounds.SoundManager; +import net.minecraft.server.packs.PackResources; +import net.minecraft.server.packs.VanillaPackResources; import net.minecraft.server.packs.resources.ReloadableResourceManager; +import net.vulkanmod.config.VideoResolution; import net.vulkanmod.render.texture.SpriteUtil; import net.vulkanmod.render.profiling.Profiler2; import net.vulkanmod.vulkan.Renderer; @@ -35,6 +40,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import java.io.IOException; import java.util.Optional; @Mixin(Minecraft.class) @@ -55,6 +61,8 @@ public class MinecraftMixin { @Shadow @Final private PaintingTextureManager paintingTextures; @Shadow public boolean noRender; + @Shadow @Final private VanillaPackResources vanillaPackResources; + @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V")) private void beginRender(int i, boolean bl) { Renderer renderer = Renderer.getInstance(); @@ -70,6 +78,14 @@ private void submitRender(boolean tick, CallbackInfo ci) { p.pop(); } + @Redirect(method="", 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); + } + } + @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;bindWrite(Z)V")) private void redirectMainTarget1(RenderTarget instance, boolean bl) { } diff --git a/src/main/java/net/vulkanmod/vulkan/DeviceInfo.java b/src/main/java/net/vulkanmod/vulkan/DeviceInfo.java index 81d0a4490..19440d2d1 100644 --- a/src/main/java/net/vulkanmod/vulkan/DeviceInfo.java +++ b/src/main/java/net/vulkanmod/vulkan/DeviceInfo.java @@ -28,7 +28,8 @@ public class DeviceInfo { public static final List graphicsCards; private final VkPhysicalDevice device; - public final String vendorId; + public final int vendorId; + public final String vendorIdString; public final String deviceName; public final String driverVersion; public final String vkVersion; @@ -57,7 +58,8 @@ public DeviceInfo(VkPhysicalDevice device, VkPhysicalDeviceProperties properties } this.device = device; - this.vendorId = decodeVendor(properties.vendorID()); + this.vendorId = properties.vendorID(); + this.vendorIdString = decodeVendor(this.vendorId); this.deviceName = properties.deviceNameString(); this.driverVersion = decodeDvrVersion(Device.deviceProperties.driverVersion(), Device.deviceProperties.vendorID()); this.vkVersion = decDefVersion(getVkVer()); @@ -185,4 +187,16 @@ public static String debugString(PointerBuffer ppPhysicalDevices, Set re public boolean isDrawIndirectSupported() { return drawIndirectSupported; } + + //Added these to allow GPU and vendor specific fixes to be applied + // (e.g. if we run into a bug that only occurs on a specific GPU, and only on Wayland for example e.g.) + public boolean isAMD() { + return this.vendorId==0x1022; + } + public boolean isNvidia() { + return this.vendorId==0x10DE; + } + public boolean isIntel() { + return this.vendorId==0x8086; + } } diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java index 32e80f80e..42188b38b 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/SwapChain.java @@ -6,6 +6,7 @@ import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.Synchronization; import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.config.VideoResolution; import net.vulkanmod.vulkan.queue.Queue; import net.vulkanmod.vulkan.texture.VulkanImage; import org.lwjgl.system.MemoryStack; @@ -34,8 +35,9 @@ public static int getDefaultDepthFormat() { } private RenderPass renderPass; + //Necessary until tearing-control-unstable-v1 is fully implemented on all GPU Drivers for Wayland + private static final int defUncappedMode = VideoResolution.isWayLand() ? VK_PRESENT_MODE_MAILBOX_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR; private long[] framebuffers; - private long swapChain = VK_NULL_HANDLE; private List swapChainImages; private VkExtent2D extent2D; @@ -353,7 +355,7 @@ private VkSurfaceFormatKHR getFormat(VkSurfaceFormatKHR.Buffer availableFormats) } private int getPresentMode(IntBuffer availablePresentModes) { - int requestedMode = vsync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR; + int requestedMode = vsync ? VK_PRESENT_MODE_FIFO_KHR : defUncappedMode; //fifo mode is the only mode that has to be supported if(requestedMode == VK_PRESENT_MODE_FIFO_KHR) From 300436e4cdfc995b9b7bacc937f94b0ec1ad3baf Mon Sep 17 00:00:00 2001 From: Vcmp <125277899+thr3343@users.noreply.github.com> Date: Tue, 5 Sep 2023 12:58:31 +0100 Subject: [PATCH 2/4] Fix Typo with Queue Frames --- src/main/java/net/vulkanmod/config/Options.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/vulkanmod/config/Options.java b/src/main/java/net/vulkanmod/config/Options.java index f2921c3d7..10e456260 100644 --- a/src/main/java/net/vulkanmod/config/Options.java +++ b/src/main/java/net/vulkanmod/config/Options.java @@ -10,7 +10,7 @@ public class Options { - //Fix Glitches+Crashes if Wayland and the Mesa RADV driver are used, and the available SwapChain images are set above 2 (possible RADV Bug?) + //Fix Glitches+Crashes if Wayland and the Mesa RADV driver are used, and Queue Frames is set above 2 (possible RADV Bug?) private static final boolean limitSwapChain = VideoResolution.isWayLand() && Vulkan.getDeviceInfo().isAMD(); static net.minecraft.client.Options minecraftOptions = Minecraft.getInstance().options; static Config config = Initializer.CONFIG; @@ -170,7 +170,7 @@ public static Option[] getGraphicsOpts() { public static Option[] getOtherOpts() { return new Option[] { - new RangeOption("RenderFrameQueue", 2, + new RangeOption("Queue Frames", 2, limitSwapChain ? 2 : 5, 1, value -> { config.frameQueueSize = value; From 94d09ddf2fd57555c8855bf1b0ad1a4cfcb65823 Mon Sep 17 00:00:00 2001 From: Vcmp <125277899+thr3343@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:52:41 +0100 Subject: [PATCH 3/4] Don't set the cursor position on Wayland Avoids "65548: Wayland: The platform does not support setting the cursor position" log spam --- .../net/vulkanmod/mixin/InputConstantsM.java | 27 ++++++++++++ src/main/resources/vulkanmod.mixins.json | 44 +++++++------------ 2 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 src/main/java/net/vulkanmod/mixin/InputConstantsM.java diff --git a/src/main/java/net/vulkanmod/mixin/InputConstantsM.java b/src/main/java/net/vulkanmod/mixin/InputConstantsM.java new file mode 100644 index 000000000..7b8734201 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/InputConstantsM.java @@ -0,0 +1,27 @@ +package net.vulkanmod.mixin; + +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 + */ + @Overwrite + public static void setupMouseCallbacks(long l, GLFWCursorPosCallbackI gLFWCursorPosCallbackI, GLFWMouseButtonCallbackI gLFWMouseButtonCallbackI, GLFWScrollCallbackI gLFWScrollCallbackI, GLFWDropCallbackI gLFWDropCallbackI) { + if(!VideoResolution.isWayLand()) + { + GLFW.glfwSetCursorPosCallback(l, gLFWCursorPosCallbackI); + } + GLFW.glfwSetMouseButtonCallback(l, gLFWMouseButtonCallbackI); + GLFW.glfwSetScrollCallback(l, gLFWScrollCallbackI); + GLFW.glfwSetDropCallback(l, gLFWDropCallbackI); + } +} diff --git a/src/main/resources/vulkanmod.mixins.json b/src/main/resources/vulkanmod.mixins.json index ad01a6d4f..7679a50fe 100644 --- a/src/main/resources/vulkanmod.mixins.json +++ b/src/main/resources/vulkanmod.mixins.json @@ -7,71 +7,61 @@ "mixins": [ ], "client": [ + "InputConstantsM", + "WindowMixin", "chunk.DirectionMixin", "chunk.FrustumMixin", "chunk.LevelRendererMixin", "chunk.VisibilitySetMixin", - - "compatibility.gl.GL11M", "compatibility.EffectInstanceM", "compatibility.ProgramM", "compatibility.UniformM", - + "compatibility.gl.GL11M", "debug.ChunkBorderRendererM", "debug.GlDebugInfoM", "debug.KeyboardHandlerM", - "gui.ChatComponentM", "gui.DebugHudM", "gui.GuiM", - "matrix.Matrix4fM", - "profiling.GuiMixin", "profiling.KeyboardHandlerM", - - "render.model.ModelPartCubeM", - "render.model.ModelPartM", - "render.vertex.FaceBakeryM", - "render.vertex.BufferBuilderM", - "render.vertex.VertexBufferM", - "render.vertex.VertexConsumerM", - "render.vertex.LiquidBlockRendererM", - "render.vertex.VertexFormatMixin", "render.BufferUploaderM", - "render.RenderTargetMixin", "render.GameRendererMixin", "render.GlProgramManagerMixin", "render.GlStateManagerM", - "render.vertex.IndexTypeMixin", + "render.LevelRendererMixin", + "render.MainTargetMixin", "render.MinecraftMixin", "render.RenderSystemMixin", + "render.RenderTargetMixin", "render.ShaderInstanceM", - "render.MainTargetMixin", - "render.LevelRendererMixin", - + "render.model.ModelPartCubeM", + "render.model.ModelPartM", + "render.vertex.BufferBuilderM", + "render.vertex.FaceBakeryM", + "render.vertex.IndexTypeMixin", + "render.vertex.LiquidBlockRendererM", + "render.vertex.VertexBufferM", + "render.vertex.VertexConsumerM", + "render.vertex.VertexFormatMixin", "screen.OptionsScreenM", - "texture.MAbstractTexture", "texture.MDynamicTexture", "texture.MFontTexture", "texture.MLightTexture", + "texture.MNativeImage", "texture.MOverlayTexture", "texture.MPlayerSkinTexture", "texture.MSimpleTexture", "texture.MSpriteAtlasTexture", "texture.MSpriteContents", "texture.MTextureManager", - "texture.MNativeImage", - "util.ScreenshotRecorderM", - "vertex.SpriteCoordinateExpanderM", "vertex.VertexMultiConsumersM$DoubleM", "vertex.VertexMultiConsumersM$MultipleM", - "vertex.VertexMultiConsumersM$SheetDecalM", - - "WindowMixin" + "vertex.VertexMultiConsumersM$SheetDecalM" ], "injectors": { "defaultRequire": 1 From 89a88c6f9c759bc6241998955e21eb3a8f7792e7 Mon Sep 17 00:00:00 2001 From: Vcmp <125277899+thr3343@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:52:41 +0100 Subject: [PATCH 4/4] Don't set the cursor position on Wayland Avoids "65548: Wayland: The platform does not support setting the cursor position" log spam --- .../net/vulkanmod/mixin/InputConstantsM.java | 24 ++++++++++ src/main/resources/vulkanmod.mixins.json | 44 +++++++------------ 2 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 src/main/java/net/vulkanmod/mixin/InputConstantsM.java diff --git a/src/main/java/net/vulkanmod/mixin/InputConstantsM.java b/src/main/java/net/vulkanmod/mixin/InputConstantsM.java new file mode 100644 index 000000000..204a2b19e --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/InputConstantsM.java @@ -0,0 +1,24 @@ +package net.vulkanmod.mixin; + +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 + */ + @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); + } +} diff --git a/src/main/resources/vulkanmod.mixins.json b/src/main/resources/vulkanmod.mixins.json index ad01a6d4f..7679a50fe 100644 --- a/src/main/resources/vulkanmod.mixins.json +++ b/src/main/resources/vulkanmod.mixins.json @@ -7,71 +7,61 @@ "mixins": [ ], "client": [ + "InputConstantsM", + "WindowMixin", "chunk.DirectionMixin", "chunk.FrustumMixin", "chunk.LevelRendererMixin", "chunk.VisibilitySetMixin", - - "compatibility.gl.GL11M", "compatibility.EffectInstanceM", "compatibility.ProgramM", "compatibility.UniformM", - + "compatibility.gl.GL11M", "debug.ChunkBorderRendererM", "debug.GlDebugInfoM", "debug.KeyboardHandlerM", - "gui.ChatComponentM", "gui.DebugHudM", "gui.GuiM", - "matrix.Matrix4fM", - "profiling.GuiMixin", "profiling.KeyboardHandlerM", - - "render.model.ModelPartCubeM", - "render.model.ModelPartM", - "render.vertex.FaceBakeryM", - "render.vertex.BufferBuilderM", - "render.vertex.VertexBufferM", - "render.vertex.VertexConsumerM", - "render.vertex.LiquidBlockRendererM", - "render.vertex.VertexFormatMixin", "render.BufferUploaderM", - "render.RenderTargetMixin", "render.GameRendererMixin", "render.GlProgramManagerMixin", "render.GlStateManagerM", - "render.vertex.IndexTypeMixin", + "render.LevelRendererMixin", + "render.MainTargetMixin", "render.MinecraftMixin", "render.RenderSystemMixin", + "render.RenderTargetMixin", "render.ShaderInstanceM", - "render.MainTargetMixin", - "render.LevelRendererMixin", - + "render.model.ModelPartCubeM", + "render.model.ModelPartM", + "render.vertex.BufferBuilderM", + "render.vertex.FaceBakeryM", + "render.vertex.IndexTypeMixin", + "render.vertex.LiquidBlockRendererM", + "render.vertex.VertexBufferM", + "render.vertex.VertexConsumerM", + "render.vertex.VertexFormatMixin", "screen.OptionsScreenM", - "texture.MAbstractTexture", "texture.MDynamicTexture", "texture.MFontTexture", "texture.MLightTexture", + "texture.MNativeImage", "texture.MOverlayTexture", "texture.MPlayerSkinTexture", "texture.MSimpleTexture", "texture.MSpriteAtlasTexture", "texture.MSpriteContents", "texture.MTextureManager", - "texture.MNativeImage", - "util.ScreenshotRecorderM", - "vertex.SpriteCoordinateExpanderM", "vertex.VertexMultiConsumersM$DoubleM", "vertex.VertexMultiConsumersM$MultipleM", - "vertex.VertexMultiConsumersM$SheetDecalM", - - "WindowMixin" + "vertex.VertexMultiConsumersM$SheetDecalM" ], "injectors": { "defaultRequire": 1