From 42dac86d02edf5a4adbf2485f7b7acb0869e7298 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sat, 22 Jun 2024 11:37:42 -0700 Subject: [PATCH 1/6] Port driver checks to 1.20.6/stable --- .../mods/sodium/client/SodiumPreLaunch.java | 1 + .../compatibility/checks/BugChecks.java | 1 + .../compatibility/checks/PreLaunchChecks.java | 48 ++++++++++++++++--- .../sodium/client/platform/MessageBox.java | 25 ++++++++-- 4 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/SodiumPreLaunch.java b/src/main/java/me/jellysquid/mods/sodium/client/SodiumPreLaunch.java index fd5b30206a..23a0d2ae0c 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/SodiumPreLaunch.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/SodiumPreLaunch.java @@ -8,6 +8,7 @@ public class SodiumPreLaunch implements PreLaunchEntrypoint { @Override public void onPreLaunch() { + PreLaunchChecks.beforeLWJGLInit(); GraphicsAdapterProbe.findAdapters(); PreLaunchChecks.onGameInit(); Workarounds.init(); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/BugChecks.java b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/BugChecks.java index ccd0edf3f1..36db764224 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/BugChecks.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/BugChecks.java @@ -8,6 +8,7 @@ class BugChecks { public static final boolean ISSUE_899 = configureCheck("issue899", true); public static final boolean ISSUE_1486 = configureCheck("issue1486", true); public static final boolean ISSUE_2048 = configureCheck("issue2048", true); + public static final boolean ISSUE_2561 = configureCheck("issue2561", true); private static boolean configureCheck(String name, boolean defaultValue) { var propertyValue = System.getProperty(getPropertyKey(name), null); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/PreLaunchChecks.java b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/PreLaunchChecks.java index 9225e7d6f5..1c93a986ab 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/PreLaunchChecks.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/PreLaunchChecks.java @@ -9,9 +9,12 @@ import me.jellysquid.mods.sodium.client.util.OsUtils; import me.jellysquid.mods.sodium.client.util.OsUtils.OperatingSystem; import org.jetbrains.annotations.Nullable; +import org.lwjgl.Version; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; + /** * Performs OpenGL driver validation before the game creates an OpenGL context. This runs during the earliest possible * opportunity at game startup, and uses a custom hardware prober to search for problematic drivers. @@ -19,12 +22,46 @@ public class PreLaunchChecks { private static final Logger LOGGER = LoggerFactory.getLogger("Sodium-EarlyDriverScanner"); + // This string should be determined at compile time, so it can be checked against the runtime version. + private static final String REQUIRED_LWJGL_VERSION = Version.VERSION_MAJOR + "." + Version.VERSION_MINOR + "." + Version.VERSION_REVISION; + + private static final String normalMessage = "You must change the LWJGL version in your launcher to continue. This is usually controlled by the settings for a profile or instance in your launcher."; + + private static final String prismMessage = "It appears you are using Prism Launcher to start the game. You can likely fix this problem by opening your instance settings and navigating to the Version section in the sidebar."; + + public static void beforeLWJGLInit() { + if (BugChecks.ISSUE_2561) { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + String message = normalMessage; + + if (Arrays.stream(stackTrace).map(StackTraceElement::toString).anyMatch(s -> s.contains("org.prismlauncher."))) { + message = prismMessage; + } + + if (!Version.getVersion().startsWith(REQUIRED_LWJGL_VERSION)) { + showCriticalErrorAndClose("Sodium Renderer - Unsupported LWJGL", + (""" + The game failed to start because the currently active LWJGL version is not \ + compatible. + + Installed version: ###CURRENT_VERSION### + Required version: ###REQUIRED_VERSION### + + """ + message) + .replace("###CURRENT_VERSION###", org.lwjgl.Version.getVersion()) + .replace("###REQUIRED_VERSION###", REQUIRED_LWJGL_VERSION), + "https://github.com/CaffeineMC/sodium-fabric/wiki/LWJGL-Compatibility"); + + } + } + } + public static void onGameInit() { if (BugChecks.ISSUE_899) { var installedVersion = findIntelDriverMatchingBug899(); if (installedVersion != null) { - showUnsupportedDriverMessageBox( + showCriticalErrorAndClose("Sodium Renderer - Unsupported Driver", """ The game failed to start because the currently installed Intel Graphics Driver is not \ compatible. @@ -42,7 +79,7 @@ public static void onGameInit() { var installedVersion = findNvidiaDriverMatchingBug1486(); if (installedVersion != null) { - showUnsupportedDriverMessageBox( + showCriticalErrorAndClose("Sodium Renderer - Unsupported Driver", """ The game failed to start because the currently installed NVIDIA Graphics Driver is not \ compatible. @@ -58,17 +95,17 @@ public static void onGameInit() { } } - private static void showUnsupportedDriverMessageBox(String message, String url) { + private static void showCriticalErrorAndClose(String title, String message, String url) { // Always print the information to the log file first, just in case we can't show the message box. LOGGER.error(""" ###ERROR_DESCRIPTION### For more information, please see: ###HELP_URL###""" .replace("###ERROR_DESCRIPTION###", message) - .replace("###HELP_URL###", url)); + .replace("###HELP_URL###", url == null ? "" : url)); // Try to show a graphical message box (if the platform supports it) and shut down the game. - MessageBox.showMessageBox(null, MessageBox.IconType.ERROR, "Sodium Renderer - Unsupported Driver", message, url); + MessageBox.showMessageBox(null, MessageBox.IconType.ERROR, title, message, url); System.exit(1 /* failure code */); } @@ -130,5 +167,4 @@ private static void showUnsupportedDriverMessageBox(String message, String url) return null; } - } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/platform/MessageBox.java b/src/main/java/me/jellysquid/mods/sodium/client/platform/MessageBox.java index 7e3e8be414..861e36a2cc 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/platform/MessageBox.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/platform/MessageBox.java @@ -10,7 +10,10 @@ import org.lwjgl.glfw.GLFWNativeWin32; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; +import org.lwjgl.util.tinyfd.TinyFileDialogs; + import java.nio.ByteBuffer; +import java.util.Locale; import java.util.Objects; public class MessageBox { @@ -30,10 +33,11 @@ private interface MessageBoxImpl { static @Nullable MessageBoxImpl chooseImpl() { if (OsUtils.getOs() == OsUtils.OperatingSystem.WIN) { return new WindowsMessageBoxImpl(); + } else { + // TODO: Tiny File Dialogs is really bad. We need something better. + //return new TFDMessageBoxImpl(); + return null; } - - // TODO: Provide an implementation on other platforms - return null; } void showMessageBox(@Nullable Window window, @@ -42,6 +46,21 @@ void showMessageBox(@Nullable Window window, @Nullable String helpUrl); } + private static class TFDMessageBoxImpl implements MessageBoxImpl { + // This adds information about how to open the help box, since we cannot change the buttons. + private static final String NOTICE = "\n\nFor more information, click OK; otherwise, click Cancel."; + + @Override + public void showMessageBox(@Nullable Window window, IconType icon, String title, String description, @Nullable String helpUrl) { + boolean clicked = TinyFileDialogs.tinyfd_messageBox(title, helpUrl == null ? description : description + NOTICE, helpUrl == null ? "ok" : "okcancel", icon.name().toLowerCase(Locale.ROOT), false); + + if (clicked && helpUrl != null) { + Util.getOperatingSystem() + .open(helpUrl); + } + } + } + private static class WindowsMessageBoxImpl implements MessageBoxImpl { @Override public void showMessageBox(@Nullable Window window, From 704c31e843f6bca264ab2108a436b4d2cf7089c8 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Thu, 20 Jun 2024 17:29:18 -0700 Subject: [PATCH 2/6] Use launcher brand to figure out Prism --- .../client/compatibility/checks/PreLaunchChecks.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/PreLaunchChecks.java b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/PreLaunchChecks.java index 1c93a986ab..8327cc233b 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/PreLaunchChecks.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/checks/PreLaunchChecks.java @@ -31,14 +31,13 @@ public class PreLaunchChecks { public static void beforeLWJGLInit() { if (BugChecks.ISSUE_2561) { - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - String message = normalMessage; + if (!Version.getVersion().startsWith(REQUIRED_LWJGL_VERSION)) { + String message = normalMessage; - if (Arrays.stream(stackTrace).map(StackTraceElement::toString).anyMatch(s -> s.contains("org.prismlauncher."))) { - message = prismMessage; - } + if (System.getProperty("minecraft.launcher.brand", "unknown").equalsIgnoreCase("PrismLauncher")) { + message = prismMessage; + } - if (!Version.getVersion().startsWith(REQUIRED_LWJGL_VERSION)) { showCriticalErrorAndClose("Sodium Renderer - Unsupported LWJGL", (""" The game failed to start because the currently active LWJGL version is not \ From 4390faedb4da0c42ecabb6169053e8b65ceed9d5 Mon Sep 17 00:00:00 2001 From: JellySquid <1363084+jellysquid3@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:24:03 -0600 Subject: [PATCH 3/6] Add early launch drivers for Intel Xe to vendor list --- .../environment/probe/GraphicsAdapterVendor.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java index 3d2cc60326..7b890661b6 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java @@ -31,8 +31,10 @@ public static GraphicsAdapterVendor fromIcdName(String name) { // Intel Gen 8 - ig8icd // Intel Gen 9, 9.5 - ig9icd // Intel Gen 11 - ig11icd - // Intel Gen 12 - igxelpicd (Xe-LP; integrated) and igxehpicd (Xe-LP; dedicated) - if (name.matches("ig(4|7|75|8|9|11|xelp|xehp)icd(32|64)")) { + // Intel Gen 12 - ig12icd (UHD Graphics, with early drivers) + // igxelpicd (Xe-LP; integrated) + // igxehpicd (Xe-HP; dedicated) + if (name.matches("ig(4|7|75|8|9|11|12|xelp|xehp)icd(32|64)")) { return INTEL; } From 7c53462d26e09342495a65b55e4c4e1acb02c8ff Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sat, 22 Jun 2024 11:45:44 -0700 Subject: [PATCH 4/6] Do not allow adapter check to crash the game --- .../probe/GraphicsAdapterProbe.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterProbe.java b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterProbe.java index fab52da236..2a56bf6a8c 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterProbe.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterProbe.java @@ -11,6 +11,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; public class GraphicsAdapterProbe { @@ -21,11 +22,18 @@ public class GraphicsAdapterProbe { public static void findAdapters() { LOGGER.info("Searching for graphics cards..."); - List adapters = switch (OsUtils.getOs()) { - case WIN -> findAdapters$Windows(); - case LINUX -> findAdapters$Linux(); - default -> null; - }; + List adapters; + + try { + adapters = switch (OsUtils.getOs()) { + case WIN -> findAdapters$Windows(); + case LINUX -> findAdapters$Linux(); + default -> null; + }; + } catch (Exception e) { + LOGGER.error("Failed to find graphics adapters!", e); + return; + } if (adapters == null) { // Not supported on this platform @@ -90,7 +98,8 @@ public static void findAdapters() { public static Collection getAdapters() { if (ADAPTERS == null) { - throw new RuntimeException("Graphics adapters not probed yet"); + LOGGER.error("Graphics adapters not probed yet; returning an empty list."); + return Collections.emptyList(); } return ADAPTERS; From 3d4cf6a957b0065e57518a5f188c23deaaa1bf7f Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sat, 22 Jun 2024 16:28:53 -0700 Subject: [PATCH 5/6] Backport fluid rendering fixes from /dev --- .../chunk/compile/pipeline/FluidRenderer.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/FluidRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/FluidRenderer.java index cfece30547..ce6a3af6c2 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/FluidRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/FluidRenderer.java @@ -67,16 +67,15 @@ public FluidRenderer(ColorProviderRegistry colorProviderRegistry, LightPipelineP } private boolean isFluidOccluded(BlockRenderView world, int x, int y, int z, Direction dir, Fluid fluid) { - BlockPos pos = this.scratchPos.set(x, y, z); - BlockState blockState = world.getBlockState(pos); - BlockPos adjPos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); - - if (blockState.isOpaque()) { - return world.getFluidState(adjPos).getFluid().matchesType(fluid) || blockState.isSideSolid(world, pos, dir, SideShapeType.FULL); + var adjPos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); + BlockState blockState = world.getBlockState(adjPos); + if (blockState.getFluidState().getFluid().matchesType(fluid)) { + return true; } - return world.getFluidState(adjPos).getFluid().matchesType(fluid); + return blockState.isOpaque() && dir != Direction.UP && blockState.isSideSolid(world, adjPos, dir.getOpposite(), SideShapeType.FULL); } + private boolean isSideExposed(BlockRenderView world, int x, int y, int z, Direction dir, float height) { BlockPos pos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); BlockState blockState = world.getBlockState(pos); @@ -85,10 +84,7 @@ private boolean isSideExposed(BlockRenderView world, int x, int y, int z, Direct VoxelShape shape = blockState.getCullingShape(world, pos); // Hoist these checks to avoid allocating the shape below - if (shape == VoxelShapes.fullCube()) { - // The top face always be inset, so if the shape above is a full cube it can't possibly occlude - return dir == Direction.UP; - } else if (shape.isEmpty()) { + if (shape.isEmpty()) { return true; } From 9b937ffb8d972f04fb93813bb52182518815047a Mon Sep 17 00:00:00 2001 From: douira Date: Fri, 10 May 2024 07:43:50 -0700 Subject: [PATCH 6/6] Reorient water quads according to the corner heights (#2467) The seam is placed such that it touches either the highest or lowest corner. Closes #609 --- .../chunk/compile/pipeline/FluidRenderer.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/FluidRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/FluidRenderer.java index ce6a3af6c2..2120e8248f 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/FluidRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/FluidRenderer.java @@ -44,6 +44,7 @@ public class FluidRenderer { // TODO: allow this to be changed by vertex format // TODO: move fluid rendering to a separate render pass and control glPolygonOffset and glDepthFunc to fix this properly private static final float EPSILON = 0.001f; + private static final float ALIGNED_EQUALS_EPSILON = 0.011f; private final BlockPos.Mutable scratchPos = new BlockPos.Mutable(); private final MutableFloat scratchHeight = new MutableFloat(0); @@ -96,6 +97,10 @@ private boolean isSideExposed(BlockRenderView world, int x, int y, int z, Direct return true; } + private static boolean isAlignedEquals(float a, float b) { + return Math.abs(a - b) <= ALIGNED_EQUALS_EPSILON; + } + public void render(WorldSlice world, FluidState fluidState, BlockPos blockPos, BlockPos offset, ChunkBuildBuffers buffers) { var material = DefaultMaterials.forFluidState(fluidState); var meshBuilder = buffers.get(material); @@ -215,10 +220,30 @@ public void render(WorldSlice world, FluidState fluidState, BlockPos blockPos, B quad.setSprite(sprite); - setVertex(quad, 0, 0.0f, northWestHeight, 0.0f, u1, v1); - setVertex(quad, 1, 0.0f, southWestHeight, 1.0F, u2, v2); - setVertex(quad, 2, 1.0F, southEastHeight, 1.0F, u3, v3); - setVertex(quad, 3, 1.0F, northEastHeight, 0.0f, u4, v4); + + // top surface alignedness is calculated with a more relaxed epsilon + boolean aligned = isAlignedEquals(northEastHeight, northWestHeight) + && isAlignedEquals(northWestHeight, southEastHeight) + && isAlignedEquals(southEastHeight, southWestHeight) + && isAlignedEquals(southWestHeight, northEastHeight); + + boolean creaseNorthEastSouthWest = aligned + || northEastHeight > northWestHeight && northEastHeight > southEastHeight + || northEastHeight < northWestHeight && northEastHeight < southEastHeight + || southWestHeight > northWestHeight && southWestHeight > southEastHeight + || southWestHeight < northWestHeight && southWestHeight < southEastHeight; + + if (creaseNorthEastSouthWest) { + setVertex(quad, 1, 0.0f, northWestHeight, 0.0f, u1, v1); + setVertex(quad, 2, 0.0f, southWestHeight, 1.0F, u2, v2); + setVertex(quad, 3, 1.0F, southEastHeight, 1.0F, u3, v3); + setVertex(quad, 0, 1.0F, northEastHeight, 0.0f, u4, v4); + } else { + setVertex(quad, 0, 0.0f, northWestHeight, 0.0f, u1, v1); + setVertex(quad, 1, 0.0f, southWestHeight, 1.0F, u2, v2); + setVertex(quad, 2, 1.0F, southEastHeight, 1.0F, u3, v3); + setVertex(quad, 3, 1.0F, northEastHeight, 0.0f, u4, v4); + } this.updateQuad(quad, world, blockPos, lighter, Direction.UP, 1.0F, colorProvider, fluidState); this.writeQuad(meshBuilder, material, offset, quad, facing, false); @@ -228,7 +253,6 @@ public void render(WorldSlice world, FluidState fluidState, BlockPos blockPos, B ModelQuadFacing.NEG_Y, true); } - } if (!sfDown) { @@ -363,7 +387,7 @@ private ColorProvider getColorProvider(Fluid fluid, FluidRenderHandl if (override != null) { return override; } - + return DefaultColorProviders.adapt(handler); } @@ -397,7 +421,7 @@ private void writeQuad(ChunkModelBuilder builder, Material material, BlockPos of var vertices = this.vertices; for (int i = 0; i < 4; i++) { - var out = vertices[flip ? 3 - i : i]; + var out = vertices[flip ? (3 - i + 1) & 0b11 : i]; out.x = offset.getX() + quad.getX(i); out.y = offset.getY() + quad.getY(i); out.z = offset.getZ() + quad.getZ(i);