mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-10-25 20:22:22 +00:00
Handle some Intel driver shenanigans (#1951)
This commit is contained in:
1 parent
10a5b550f2
commit
2db20ad866
4 files changed
+85
-4
No files matched your search
@@ -12,6 +12,7 @@ build/
|
||||
/config/
|
||||
/crash-reports/
|
||||
/logs/
|
||||
tmp/
|
||||
options.txt
|
||||
/saves/
|
||||
usernamecache.json
|
||||
|
||||
@@ -146,6 +146,9 @@ public class RenderSystem {
|
||||
coreProfile = true;
|
||||
GLStateManager.LOGGER.info("GL 3.3 core profile detected, enabling FFP shader emulation.");
|
||||
ShaderManager.getInstance().enable();
|
||||
} else {
|
||||
throw new IllegalStateException("Non-core GL context (profile mask 0x" + Integer.toHexString(profileMask)
|
||||
+ "); FFP emulation requires a core profile and nothing would render. Context creation should have rejected this.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,7 +552,7 @@ public class RenderSystem {
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse a GL version string (e.g. "4.6.0 NVIDIA ...") into concatenated digits "460". Inlined from StandardMacros.getGlVersion(). */
|
||||
/** Parse a GL version string (e.g. "4.6.0 NVIDIA ...") into concatenated digits "460" */
|
||||
static String parseGlVersionString(String info) {
|
||||
final Matcher matcher = SEMVER_PATTERN.matcher(Objects.requireNonNull(info));
|
||||
if (!matcher.matches()) {
|
||||
@@ -561,4 +564,18 @@ public class RenderSystem {
|
||||
if (bugfix == null || bugfix.isEmpty()) bugfix = "0";
|
||||
return major + minor + bugfix;
|
||||
}
|
||||
|
||||
/** Parse a GL version string into packed major*10+minor (e.g. "4.3.0 - Build ..." -> 43), or -1 if unparseable. */
|
||||
public static int parseMajorMinor(String glVersion) {
|
||||
if (glVersion == null) return -1;
|
||||
final Matcher matcher = SEMVER_PATTERN.matcher(glVersion.trim());
|
||||
if (!matcher.matches()) return -1;
|
||||
return Integer.parseInt(matcher.group("major")) * 10 + Integer.parseInt(matcher.group("minor"));
|
||||
}
|
||||
|
||||
public static boolean isContextValid(int requestedMajor, int requestedMinor, int actualVersion, boolean coreBitSet) {
|
||||
if (!coreBitSet) return false;
|
||||
if (actualVersion < 0) return true;
|
||||
return actualVersion >= requestedMajor * 10 + requestedMinor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.gtnewhorizons.angelica.glsm;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class GLVersionParseTest {
|
||||
|
||||
@Test
|
||||
void parseMajorMinor() {
|
||||
assertEquals(43, RenderSystem.parseMajorMinor("4.3.0 - Build 20.19.15.4835"));
|
||||
assertEquals(46, RenderSystem.parseMajorMinor("4.6.0 NVIDIA 551.61"));
|
||||
assertEquals(41, RenderSystem.parseMajorMinor("4.1 Metal - 88"));
|
||||
assertEquals(33, RenderSystem.parseMajorMinor("3.3"));
|
||||
assertEquals(46, RenderSystem.parseMajorMinor("4.6 (Core Profile) Mesa 24.0.3"));
|
||||
assertEquals(-1, RenderSystem.parseMajorMinor(null));
|
||||
assertEquals(-1, RenderSystem.parseMajorMinor(""));
|
||||
assertEquals(-1, RenderSystem.parseMajorMinor("garbage"));
|
||||
assertEquals(-1, RenderSystem.parseMajorMinor("OpenGL ES 3.2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isContextValid() {
|
||||
assertTrue(RenderSystem.isContextValid(4, 4, 46, true));
|
||||
assertTrue(RenderSystem.isContextValid(4, 4, 44, true));
|
||||
assertFalse(RenderSystem.isContextValid(4, 4, 43, true));
|
||||
assertFalse(RenderSystem.isContextValid(4, 4, 44, false));
|
||||
assertTrue(RenderSystem.isContextValid(4, 4, -1, true));
|
||||
assertFalse(RenderSystem.isContextValid(4, 4, -1, false));
|
||||
assertTrue(RenderSystem.isContextValid(3, 3, 33, true));
|
||||
}
|
||||
}
|
||||
+32
-3
@@ -3,6 +3,7 @@ package com.gtnewhorizons.angelica.mixins.early.angelica;
|
||||
import com.gtnewhorizon.gtnhlib.config.ConfigurationManager;
|
||||
import com.gtnewhorizons.angelica.AngelicaMod;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.glsm.RenderSystem;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -11,6 +12,7 @@ import org.lwjgl.LWJGLException;
|
||||
import org.lwjgl.opengl.ContextAttribs;
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
import org.lwjgl.opengl.PixelFormat;
|
||||
import org.lwjgl.LWJGLUtil;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -63,15 +65,22 @@ public abstract class MixinForgeHooksClient_CoreProfile {
|
||||
final int platformMaxMinor = (LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_MACOSX) ? 1 : 6;
|
||||
final int platformMax = platformMaxMajor * 10 + platformMaxMinor;
|
||||
|
||||
int maxProbe = platformMax;
|
||||
|
||||
// Try pinned version first if configured
|
||||
final int pinned = angelica$clampPinned(AngelicaConfig.pinnedGLVersion, platformMax);
|
||||
if (pinned >= 33) {
|
||||
final Exception e = angelica$tryCreate(attribs, format, setMajor, setMinor, pinned / 10, pinned % 10);
|
||||
if (e == null) {
|
||||
LOGGER.info("Created GL {}.{} core profile context (pinned)", pinned / 10, pinned % 10);
|
||||
return;
|
||||
final int cap = angelica$validateContext(pinned / 10, pinned % 10);
|
||||
if (cap == 0) {
|
||||
LOGGER.info("Created GL {}.{} core profile context (pinned)", pinned / 10, pinned % 10);
|
||||
return;
|
||||
}
|
||||
maxProbe = Math.min(maxProbe, cap);
|
||||
} else {
|
||||
LOGGER.warn("Pinned GL version {}.{} failed, probing from highest", pinned / 10, pinned % 10);
|
||||
}
|
||||
LOGGER.warn("Pinned GL version {}.{} failed, probing from highest", pinned / 10, pinned % 10);
|
||||
}
|
||||
|
||||
// Probe from highest to lowest
|
||||
@@ -80,8 +89,14 @@ public abstract class MixinForgeHooksClient_CoreProfile {
|
||||
final int maxMinor = (major == 4) ? platformMaxMinor : 3;
|
||||
final int minMinor = (major == 3) ? 3 : 0;
|
||||
for (int minor = maxMinor; minor >= minMinor; --minor) {
|
||||
if (major * 10 + minor > maxProbe) continue;
|
||||
final Exception e = angelica$tryCreate(attribs, format, setMajor, setMinor, major, minor);
|
||||
if (e == null) {
|
||||
final int cap = angelica$validateContext(major, minor);
|
||||
if (cap != 0) {
|
||||
maxProbe = Math.min(maxProbe, cap);
|
||||
continue;
|
||||
}
|
||||
final int version = major * 10 + minor;
|
||||
LOGGER.info("Created GL {}.{} core profile context", major, minor);
|
||||
// Auto-pin if below platform max, or update a stale pin
|
||||
@@ -127,6 +142,20 @@ public abstract class MixinForgeHooksClient_CoreProfile {
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static int angelica$validateContext(int major, int minor) {
|
||||
final String glVersion = GLStateManager.glGetString(GL11.GL_VERSION);
|
||||
final int actual = RenderSystem.parseMajorMinor(glVersion);
|
||||
final boolean core = (GLStateManager.glGetInteger(GL32.GL_CONTEXT_PROFILE_MASK) & GL32.GL_CONTEXT_CORE_PROFILE_BIT) != 0;
|
||||
if (RenderSystem.isContextValid(major, minor, actual, core)) {
|
||||
return 0;
|
||||
}
|
||||
LOGGER.warn("Requested GL {}.{} core context but driver returned \"{}\" (core profile: {}, GPU: {}); falling back to a lower version", major, minor, glVersion, core, GLStateManager.glGetString(GL11.GL_RENDERER));
|
||||
try { Display.destroy(); } catch (Exception ignored) {}
|
||||
final int requested = major * 10 + minor;
|
||||
return (actual >= 0 && actual < requested) ? actual : requested - 1;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void angelica$savePin(int version) {
|
||||
AngelicaConfig.pinnedGLVersion = version;
|
||||
|
||||
Reference in new issue
Block a user