Have GLProxy attempt creating contexts with all supported GL versions

This commit is contained in:
James Seibel
2023-10-13 21:56:06 -05:00
parent 78e2b4ff3f
commit 1e5a4d43f7
3 changed files with 128 additions and 83 deletions
@@ -19,6 +19,9 @@
package com.seibel.distanthorizons.coreapi.util;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Miscellaneous string helper functions.
*
@@ -42,6 +45,8 @@ public class StringUtil
return pos;
}
/** @see StringUtil#join(String, Iterable) */
public static <T> String join(String delimiter, T[] list) { return join(delimiter, Arrays.asList(list)); }
/** Combines each item in the given list together separated by the given delimiter. */
public static <T> String join(String delimiter, Iterable<T> list)
{
@@ -30,8 +30,10 @@ import com.seibel.distanthorizons.core.config.types.*;
import com.seibel.distanthorizons.core.config.types.enums.*;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.EnumUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.coreapi.util.StringUtil;
import org.apache.logging.log4j.Logger;
import javax.swing.*;
@@ -1224,30 +1226,30 @@ public class Config
+ "")
.build();
public static ConfigEntry<Integer> glContextMajorVersion = new ConfigEntry.Builder<Integer>()
.setMinDefaultMax(3, 3, 4)
.comment("" +
"Can be changed if you experience crashing when loading into a world.\n" +
"Note: setting to an invalid version may also cause the game to crash.\n" +
"\n" +
"Defines the requested OpenGL context major version Distant Horizons will create. \n" +
"Possible values (DH requires 3.2 or higher at minimum): \n" +
"4.6, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0 \n" +
"3.3, 3.2 \n" +
"")
.build();
public static ConfigEntry<Integer> glContextMinorVersion = new ConfigEntry.Builder<Integer>()
.setMinDefaultMax(0, 2, 6)
.comment("" +
"Can be changed if you experience crashing when loading into a world.\n" +
"Note: setting to an invalid version may also cause the game to crash.\n" +
"\n" +
"Defines the requested OpenGL context major version Distant Horizons will create. \n" +
"Possible values (DH requires 3.2 or higher at minimum): \n" +
"4.6, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0 \n" +
"3.3, 3.2 \n" +
"")
.build();
//public static ConfigEntry<Integer> glContextMajorVersion = new ConfigEntry.Builder<Integer>()
// .setMinDefaultMax(3, 3, 4)
// .comment("" +
// "Can be changed if you experience crashing when loading into a world.\n" +
// "Note: setting to an invalid version may also cause the game to crash.\n" +
// "\n" +
// "Defines the requested OpenGL context major version Distant Horizons will create. \n" +
// "Possible values (DH requires 3.2 or higher at minimum): \n" +
// "4.6, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0 \n" +
// "3.3, 3.2 \n" +
// "")
// .build();
//public static ConfigEntry<Integer> glContextMinorVersion = new ConfigEntry.Builder<Integer>()
// .setMinDefaultMax(0, 2, 6)
// .comment("" +
// "Can be changed if you experience crashing when loading into a world.\n" +
// "Note: setting to an invalid version may also cause the game to crash.\n" +
// "\n" +
// "Defines the requested OpenGL context major version Distant Horizons will create. \n" +
// "Possible values (DH requires 3.2 or higher at minimum): \n" +
// "4.6, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0 \n" +
// "3.3, 3.2 \n" +
// "")
// .build();
public static ConfigEntry<EGlProfileMode> glProfileMode = new ConfigEntry.Builder<EGlProfileMode>()
.set(EGlProfileMode.CORE)
@@ -1256,6 +1258,7 @@ public class Config
"\n" +
"Defines the OpenGL context type Distant Horizon's will create. \n" +
"Generally this should be left as ["+EGlProfileMode.CORE+"] unless there is an issue with your GPU driver. \n" +
"Possible values: ["+ StringUtil.join("],[", EGlProfileMode.values())+"] \n" +
"")
.build();
public static ConfigEntry<Boolean> enableGlForwardCompatibilityMode = new ConfigEntry.Builder<Boolean>()
@@ -31,8 +31,10 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.ReflectionUtil;
import com.seibel.distanthorizons.core.util.objects.GLMessage;
import com.seibel.distanthorizons.core.util.objects.GLMessageOutputStream;
import com.seibel.distanthorizons.core.util.objects.Pair;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.coreapi.util.StringUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
@@ -43,9 +45,12 @@ import org.lwjgl.opengl.GLUtil;
import java.io.PrintStream;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
/**
* A singleton that holds references to different openGL contexts
@@ -73,6 +78,13 @@ public class GLProxy
public static final ConfigBasedLogger GL_LOGGER = new ConfigBasedLogger(LogManager.getLogger(GLProxy.class),
() -> Config.Client.Advanced.Logging.logRendererGLEvent.get());
/** newest version first */
private static final ArrayList<Pair<Integer, Integer>> SUPPORTED_GL_VERSIONS = new ArrayList<>(
Arrays.asList(
new Pair<>(4,6), new Pair<>(4,5), new Pair<>(4,4), new Pair<>(4,3), new Pair<>(4,2), new Pair<>(4,1), new Pair<>(4,0),
new Pair<>(3,3), new Pair<>(3,2)
));
private static GLProxy instance = null;
@@ -155,67 +167,92 @@ public class GLProxy
// create the lod builder context //
//================================//
GLFW.glfwMakeContextCurrent(0L);
String contextCreateErrorMessage = "";
long potentialLodBuilderGlContext = 0;
GLCapabilities potentialLodBuilderGlCapabilities = null;
// context creation setup
GLFW.glfwDefaultWindowHints();
// make the context window invisible
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
int glMajorVersion = Config.Client.Advanced.Debugging.OpenGl.glContextMajorVersion.get();
int glMinorVersion = Config.Client.Advanced.Debugging.OpenGl.glContextMinorVersion.get();
boolean debugContextEnabled = Config.Client.Advanced.Debugging.OpenGl.enableGlDebugContext.get();
boolean forwardCompatEnabled = Config.Client.Advanced.Debugging.OpenGl.enableGlForwardCompatibilityMode.get();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, glMajorVersion);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, glMinorVersion);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_DEBUG_CONTEXT, debugContextEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, forwardCompatEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
int profileModeInt;
EGlProfileMode profileModeEnum = Config.Client.Advanced.Debugging.OpenGl.glProfileMode.get();
switch (profileModeEnum)
for (Pair<Integer, Integer> supportedGlVersion : SUPPORTED_GL_VERSIONS)
{
case CORE:
profileModeInt = GLFW.GLFW_OPENGL_CORE_PROFILE;
break;
case COMPAT:
profileModeInt = GLFW.GLFW_OPENGL_COMPAT_PROFILE;
break;
default:
case ANY:
profileModeInt = GLFW.GLFW_OPENGL_ANY_PROFILE;
break;
}
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, profileModeInt);
String failErrorMessage =
"ERROR: Failed to create LodBuilder OpenGL GLFW context for " +
"OpenGL Version: ["+glMajorVersion+"."+glMinorVersion+"] " +
"with Debugging: ["+(debugContextEnabled ? "Enabled" : "Disabled")+"], " +
"Forward Compatibility: ["+(forwardCompatEnabled ? "Enabled" : "Disabled")+"], " +
"and Profile: ["+profileModeEnum.name()+"]. \n" +
"Your OS and GPU Driver may have not support this combination.";
// create the Lod Builder context
this.lodBuilderGlContext = GLFW.glfwCreateWindow(64, 48, "LOD Builder Window", 0L, this.minecraftGlContext);
if (this.lodBuilderGlContext == 0)
{
GL_LOGGER.error(failErrorMessage);
GL_LOGGER.error("Minecraft GL Capabilities:\n [\n"+ReflectionUtil.getAllFieldValuesAsString(this.minecraftGlCapabilities)+"\n]\n");
int glMajorVersion = supportedGlVersion.first;
int glMinorVersion = supportedGlVersion.second;
throw new UnsupportedOperationException("Forward Compat Core Profile 3.2 creation failure");
GL_LOGGER.info("Attempting to create a context with GL version: ["+glMajorVersion+"."+glMinorVersion+"]");
GLFW.glfwMakeContextCurrent(0L);
// context creation setup
GLFW.glfwDefaultWindowHints();
// make the context window invisible
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
boolean debugContextEnabled = Config.Client.Advanced.Debugging.OpenGl.enableGlDebugContext.get();
boolean forwardCompatEnabled = Config.Client.Advanced.Debugging.OpenGl.enableGlForwardCompatibilityMode.get();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, glMajorVersion);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, glMinorVersion);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_DEBUG_CONTEXT, debugContextEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, forwardCompatEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
int profileModeInt;
EGlProfileMode profileModeEnum = Config.Client.Advanced.Debugging.OpenGl.glProfileMode.get();
switch (profileModeEnum)
{
case CORE:
profileModeInt = GLFW.GLFW_OPENGL_CORE_PROFILE;
break;
case COMPAT:
profileModeInt = GLFW.GLFW_OPENGL_COMPAT_PROFILE;
break;
default:
case ANY:
profileModeInt = GLFW.GLFW_OPENGL_ANY_PROFILE;
break;
}
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, profileModeInt);
contextCreateErrorMessage =
"Failed to create OpenGL GLFW context for OpenGL Version: [" + glMajorVersion + "." + glMinorVersion + "] \n" +
"with Debugging: [" + (debugContextEnabled ? "Enabled" : "Disabled") + "], \n" +
"Forward Compatibility: [" + (forwardCompatEnabled ? "Enabled" : "Disabled") + "], \n" +
"and Profile: [" + profileModeEnum.name() + "]. ";
// try creating the Lod Builder context
potentialLodBuilderGlContext = GLFW.glfwCreateWindow(1, 1, "LOD Builder Window", 0L, this.minecraftGlContext);
if (potentialLodBuilderGlContext == 0)
{
GL_LOGGER.debug(contextCreateErrorMessage);
GL_LOGGER.debug("Minecraft GL Capabilities:\n [\n" + ReflectionUtil.getAllFieldValuesAsString(this.minecraftGlCapabilities) + "\n]\n");
continue;
}
// create the window
GLFW.glfwMakeContextCurrent(potentialLodBuilderGlContext);
GL_LOGGER.info("Successfully created a context with GL version: ["+glMajorVersion+"."+glMinorVersion+"]");
// set and log the capabilities
potentialLodBuilderGlCapabilities = GL.createCapabilities();
GL_LOGGER.info("lodBuilderGlCapabilities:\n" + this.versionInfoToString(potentialLodBuilderGlCapabilities));
// override the GL logger
GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream(GLProxy::logMessage, this.lodBuilderDebugMessageBuilder), true));
// clear the context for the next stage
GLFW.glfwMakeContextCurrent(0L);
break;
}
// create the window
GLFW.glfwMakeContextCurrent(this.lodBuilderGlContext);
// set and log the capabilities
this.lodBuilderGlCapabilities = GL.createCapabilities();
GL_LOGGER.info("lodBuilderGlCapabilities:\n" + this.versionInfoToString(this.lodBuilderGlCapabilities));
// override the GL logger
GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream(GLProxy::logMessage, this.lodBuilderDebugMessageBuilder), true));
// clear the context for the next stage
GLFW.glfwMakeContextCurrent(0L);
if (potentialLodBuilderGlContext == 0)
{
// no context was created
throw new UnsupportedOperationException("ERROR: Unable to create a GL Context using any of the supported GL versions: ["+ StringUtil.join(",", SUPPORTED_GL_VERSIONS) +"]");
}
this.lodBuilderGlContext = potentialLodBuilderGlContext;
this.lodBuilderGlCapabilities = potentialLodBuilderGlCapabilities;
@@ -227,7 +264,8 @@ public class GLProxy
this.proxyWorkerGlContext = GLFW.glfwCreateWindow(64, 48, "LOD proxy worker Window", 0L, this.minecraftGlContext);
if (this.proxyWorkerGlContext == 0)
{
GL_LOGGER.error(failErrorMessage);
GL_LOGGER.error(contextCreateErrorMessage +
"\n Your OS and GPU Driver may have not support this combination.");
GL_LOGGER.error("Minecraft GL Capabilities:\n [\n"+ReflectionUtil.getAllFieldValuesAsString(this.minecraftGlCapabilities)+"\n]\n");
throw new UnsupportedOperationException("Forward Compat Core Profile 3.2 creation failure");
@@ -408,7 +446,6 @@ public class GLProxy
//============================//
// MC render thread runnables //
//============================//