Skip to content

Commit

Permalink
Clean up the NVIDIA workarounds code
Browse files Browse the repository at this point in the history
  • Loading branch information
jellysquid3 committed Jul 23, 2023
1 parent 8ade8ab commit 8e986da
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 228 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package me.jellysquid.mods.sodium.client.util.workarounds;

import me.jellysquid.mods.sodium.client.util.workarounds.platform.NVIDIAWorkarounds;
import me.jellysquid.mods.sodium.client.util.workarounds.platform.NvidiaWorkarounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -11,13 +11,13 @@ public static void beforeContextCreation() {
LOGGER.info("Checking for any workarounds that need to be applied prior to context creation...");

if (Workarounds.isWorkaroundEnabled(Workarounds.Reference.NVIDIA_BAD_DRIVER_SETTINGS)) {
NVIDIAWorkarounds.install();
NvidiaWorkarounds.install();
}
}

public static void afterContextCreation() {
if (Workarounds.isWorkaroundEnabled(Workarounds.Reference.NVIDIA_BAD_DRIVER_SETTINGS)) {
NVIDIAWorkarounds.uninstall();
NvidiaWorkarounds.uninstall();
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package me.jellysquid.mods.sodium.client.util.workarounds.platform;

import me.jellysquid.mods.sodium.client.util.workarounds.platform.linux.LibC;
import me.jellysquid.mods.sodium.client.util.workarounds.platform.windows.Kernel32;
import me.jellysquid.mods.sodium.client.util.workarounds.platform.windows.WindowsProcessHacks;
import net.minecraft.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NvidiaWorkarounds {
private static final Logger LOGGER = LoggerFactory.getLogger("Sodium-NvidiaWorkarounds");

public static void install() {
LOGGER.warn("Attempting to apply workarounds for the NVIDIA Graphics Driver...");
LOGGER.warn("If the game crashes immediately after this point, please make a bug report: https://github.com/CaffeineMC/sodium-fabric/issues");

try {
switch (Util.getOperatingSystem()) {
case WINDOWS -> {
// The NVIDIA drivers rely on parsing the command line arguments to detect Minecraft. If we destroy those,
// then it shouldn't be able to detect us anymore.
WindowsProcessHacks.setCommandLine("net.caffeinemc.sodium");

// Ensures that Minecraft will run on the dedicated GPU, since the drivers can no longer detect it
Kernel32.setEnvironmentVariable("SHIM_MCCOMPAT", "0x800000001");
}
case LINUX -> {
// Unlike Windows, we don't need to hide ourselves from the driver. We can just request that
// it not use threaded optimizations instead.
LibC.setEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", "0");
}
}

LOGGER.info("... Successfully applied workarounds for the NVIDIA Graphics Driver!");
} catch (Throwable t) {
LOGGER.error("Failure while applying workarounds", t);

LOGGER.error("READ ME! The workarounds for the NVIDIA Graphics Driver did not apply correctly!");
LOGGER.error("READ ME! You are very likely going to run into unexplained crashes and severe performance issues!");
LOGGER.error("READ ME! Please see this issue for more information: https://github.com/CaffeineMC/sodium-fabric/issues/1816");
}
}

public static void uninstall() {
switch (Util.getOperatingSystem()) {
case WINDOWS -> {
WindowsProcessHacks.resetCommandLine();
}
case LINUX -> { }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package me.jellysquid.mods.sodium.client.util.workarounds.platform.linux;

import org.jetbrains.annotations.Nullable;
import org.lwjgl.system.*;

public class LibC {
private static final SharedLibrary LIBRARY = Library.loadNative("me.jellyquid.mods.sodium", "libc.so.6");

private static final long PFN_setenv;

static {
PFN_setenv = APIUtil.apiGetFunctionAddress(LIBRARY, "setenv");
}

public static void setEnvironmentVariable(String name, @Nullable String value) {
try (var stack = MemoryStack.stackPush()) {
var nameBuf = stack.UTF8(name);
var valueBuf = value != null ? stack.UTF8(value) : null;

JNI.callPPI(MemoryUtil.memAddress(nameBuf), MemoryUtil.memAddressSafe(valueBuf), 1 /* replace */, PFN_setenv);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package me.jellysquid.mods.sodium.client.util.workarounds.platform.windows;

import org.jetbrains.annotations.Nullable;
import org.lwjgl.system.*;

import java.nio.ByteBuffer;

public class Kernel32 {
private static final SharedLibrary LIBRARY = Library.loadNative("me.jellyquid.mods.sodium", "kernel32");

private static final long PFN_GetCommandLineW;
private static final long PFN_SetEnvironmentVariableW;

static {
PFN_GetCommandLineW = APIUtil.apiGetFunctionAddress(LIBRARY, "GetCommandLineW");
PFN_SetEnvironmentVariableW = APIUtil.apiGetFunctionAddress(LIBRARY, "SetEnvironmentVariableW");
}

public static void setEnvironmentVariable(String name, @Nullable String value) {
try (MemoryStack stack = MemoryStack.stackPush()) {
ByteBuffer lpNameBuf = stack.malloc(16, MemoryUtil.memLengthUTF16(name, true));
MemoryUtil.memUTF16(name, true, lpNameBuf);

ByteBuffer lpValueBuf = null;

if (value != null) {
lpValueBuf = stack.malloc(16, MemoryUtil.memLengthUTF16(value, true));
MemoryUtil.memUTF16(value, true, lpValueBuf);
}

JNI.callJJI(MemoryUtil.memAddress0(lpNameBuf), MemoryUtil.memAddressSafe(lpValueBuf), PFN_SetEnvironmentVariableW);
}
}

public static long getCommandLine() {
return JNI.callP(PFN_GetCommandLineW);
}
}
Loading

0 comments on commit 8e986da

Please sign in to comment.