summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRye <rye@alchemyviewer.org>2025-10-30 17:22:09 -0400
committerRye <rye@alchemyviewer.org>2025-11-02 21:40:05 -0500
commit0c1cbf2d38cbd0db5c9cfb86559b4fc5e4acee0d (patch)
tree725abfa056852880daeaa3bae41951b03c1bcb3d
parent0c796b0c429058b334ee8968c4f0019445c09d55 (diff)
Add support for GLX and EGL to GL extension loader
Fix dullahan wayland support Fix shader GL_ERROR under GL Core profile in Mesa Signed-off-by: Rye <rye@alchemyviewer.org>
-rw-r--r--indra/cmake/UI.cmake12
-rw-r--r--indra/llrender/llgl.cpp114
-rw-r--r--indra/llrender/llgl.h10
-rw-r--r--indra/llrender/llglheaders.h30
-rw-r--r--indra/llwindow/CMakeLists.txt2
-rw-r--r--indra/llwindow/llsdl.cpp2
-rw-r--r--indra/llwindow/llwindowsdl.cpp57
-rw-r--r--indra/llwindow/llwindowsdl.h33
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl1
9 files changed, 245 insertions, 16 deletions
diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake
index afa1350ef0..8e6382ceeb 100644
--- a/indra/cmake/UI.cmake
+++ b/indra/cmake/UI.cmake
@@ -14,12 +14,20 @@ if (LINUX)
find_package(PkgConfig REQUIRED)
pkg_check_modules(WAYLAND_CLIENT wayland-client)
- if( WAYLAND_CLIENT_FOUND )
- target_compile_definitions( ll::uilibraries INTERFACE LL_WAYLAND=1)
+ if(WAYLAND_CLIENT_FOUND)
+ target_compile_definitions(ll::uilibraries INTERFACE LL_WAYLAND=1)
else()
message("pkgconfig could not find wayland client, compiling without full wayland support")
endif()
+ find_package(X11)
+ if(X11_FOUND)
+ target_compile_definitions(ll::uilibraries INTERFACE LL_X11=1)
+ else()
+ message("Could not find X11, compiling without full X11 support")
+ endif()
+
+
target_link_libraries( ll::uilibraries INTERFACE
ll::fontconfig
ll::freetype
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 7b8eb7809e..c45ad70758 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -52,10 +52,11 @@
#include <glm/gtc/matrix_access.hpp>
#include "glm/gtc/type_ptr.hpp"
-#if LL_MESA
+#if LL_MESA_HEADLESS
# include "GL/osmesa.h"
# define LL_GET_PROC_ADDRESS(func) OSMesaGetProcAddress(func)
#elif LL_SDL_WINDOW
+# include "llwindowsdl.h"
# include "SDL3/SDL.h"
# define LL_GET_PROC_ADDRESS(func) SDL_GL_GetProcAddress(func)
#elif LL_WINDOWS
@@ -247,6 +248,19 @@ PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = nullptr;
#endif
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+// GLX_MESA_query_renderer
+PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glXQueryCurrentRendererIntegerMESA = nullptr;
+PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC glXQueryCurrentRendererStringMESA = nullptr;
+PFNGLXQUERYRENDERERINTEGERMESAPROC glXQueryRendererIntegerMESA = nullptr;
+PFNGLXQUERYRENDERERSTRINGMESAPROC glXQueryRendererStringMESA = nullptr;
+#endif
+
+#if LL_LINUX && LL_WAYLAND &&!LL_MESA_HEADLESS
+// EGL_VERSION_1_0
+PFNEGLQUERYSTRINGPROC eglQueryString = nullptr;
+#endif
+
// GL_VERSION_1_0
PFNGLCLEARCOLORPROC glClearColor = nullptr;
PFNGLCLEARPROC glClear = nullptr;
@@ -1039,6 +1053,42 @@ void LLGLManager::initWGL()
#endif
}
+void LLGLManager::initGLX()
+{
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+ if (!mIsX11)
+ return;
+
+ reloadExtensionsString();
+
+ mHasGLXMESAQueryRenderer = mGLExtensions.contains("GLX_MESA_query_renderer");
+ if (mHasGLXMESAQueryRenderer)
+ {
+ glXQueryCurrentRendererIntegerMESA = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)LL_GET_PROC_ADDRESS("glXQueryCurrentRendererIntegerMESA");
+ glXQueryCurrentRendererStringMESA = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC)LL_GET_PROC_ADDRESS("glXQueryCurrentRendererStringMESA");
+ glXQueryRendererIntegerMESA = (PFNGLXQUERYRENDERERINTEGERMESAPROC)LL_GET_PROC_ADDRESS("glXQueryRendererIntegerMESA");
+ glXQueryRendererStringMESA = (PFNGLXQUERYRENDERERSTRINGMESAPROC)LL_GET_PROC_ADDRESS("glXQueryRendererStringMESA");
+ }
+#endif
+}
+
+void LLGLManager::initEGL()
+{
+#if LL_LINUX && LL_WAYLAND && !LL_MESA_HEADLESS
+ if (!mIsWayland)
+ return;
+
+ reloadExtensionsString();
+
+ // EGL_VERSION_1_0
+ eglQueryString = (PFNEGLQUERYSTRINGPROC)LL_GET_PROC_ADDRESS("eglQueryString");
+
+ LL_INFOS("RenderInit") << "EGL_VENDOR " << ll_safe_string((const char *)eglQueryString(SDL_EGL_GetCurrentDisplay(), EGL_VENDOR)) << LL_ENDL;
+ LL_INFOS("RenderInit") << "EGL_VERSION " << ll_safe_string((const char *)eglQueryString(SDL_EGL_GetCurrentDisplay(), EGL_VERSION)) << LL_ENDL;
+#endif
+}
+
+
// return false if unable (or unwilling due to old drivers) to init GL
bool LLGLManager::initGL()
{
@@ -1221,6 +1271,23 @@ bool LLGLManager::initGL()
}
} else
#endif
+
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+ if(mHasGLXMESAQueryRenderer && mVRAM == 0)
+ {
+ unsigned int vram_val = 0;
+ if(glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_VIDEO_MEMORY_MESA, &vram_val))
+ {
+ gGLManager.mVRAM = vram_val;
+
+ if (mVRAM != 0)
+ {
+ LL_WARNS("RenderInit") << "VRAM Detected (GLXMesaQueryRenderer):" << mVRAM << LL_ENDL;
+ }
+ }
+ }
+#endif
+
#if LL_WINDOWS || LL_LINUX
{
if (mHasNVXGpuMemoryInfo && mVRAM == 0)
@@ -1452,13 +1519,12 @@ void LLGLManager::reloadExtensionsString()
}
#endif
-
#if LL_WINDOWS
{
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)LL_GET_PROC_ADDRESS("wglGetExtensionsStringARB");
if (wglGetExtensionsStringARB)
{
- std::string wgl_exts = ll_safe_string((const char*)wglGetExtensionsStringARB(wglGetCurrentDC()));;
+ std::string wgl_exts = ll_safe_string((const char*)wglGetExtensionsStringARB(wglGetCurrentDC()));
boost::char_separator<char> sep(" ");
boost::tokenizer<boost::char_separator<char> > tok(wgl_exts, sep);
for (boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
@@ -1468,6 +1534,48 @@ void LLGLManager::reloadExtensionsString()
}
}
#endif
+
+#if LL_SDL_WINDOW && LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+ if (mIsX11)
+ {
+ if (LLWindowSDL::sX11Data.xdisplay && LLWindowSDL::sX11Data.xwindow)
+ {
+ typedef const char *(*PFNEGLXQUERYEXTENSIONSSTRINGPROC) (Display *dpy, int screen );
+ PFNEGLXQUERYEXTENSIONSSTRINGPROC llglXQueryExtensionsString = (PFNEGLXQUERYEXTENSIONSSTRINGPROC)LL_GET_PROC_ADDRESS("glXQueryExtensionsString");
+ if (llglXQueryExtensionsString)
+ {
+ std::string glx_exts = ll_safe_string((const char*)llglXQueryExtensionsString(LLWindowSDL::sX11Data.xdisplay, LLWindowSDL::sX11Data.xscreen));
+ boost::char_separator<char> sep(" ");
+ boost::tokenizer<boost::char_separator<char> > tok(glx_exts, sep);
+ for (boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
+ {
+ mGLExtensions.insert(*i);
+ }
+ }
+ }
+ }
+#endif
+
+#if LL_SDL_WINDOW && LL_LINUX && LL_WAYLAND && !LL_MESA_HEADLESS
+ if (mIsWayland)
+ {
+ SDL_EGLDisplay egl_display = SDL_EGL_GetCurrentDisplay();
+ if (egl_display)
+ {
+ PFNEGLQUERYSTRINGPROC lleglQueryString = (PFNEGLQUERYSTRINGPROC)LL_GET_PROC_ADDRESS("eglQueryString");
+ if (lleglQueryString)
+ {
+ std::string egl_exts = ll_safe_string((const char*)lleglQueryString((EGLDisplay)egl_display, EGL_EXTENSIONS));
+ boost::char_separator<char> sep(" ");
+ boost::tokenizer<boost::char_separator<char> > tok(egl_exts, sep);
+ for (boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
+ {
+ mGLExtensions.insert(*i);
+ }
+ }
+ }
+ }
+#endif
}
void LLGLManager::initExtensions()
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index b7cd3df3c8..3a311ad03b 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -70,7 +70,9 @@ public:
bool initGL();
void shutdownGL();
- void initWGL(); // Initializes stupid WGL extensions
+ void initWGL(); // Initializes WGL extensions
+ void initGLX(); // Initializes GLX extensions
+ void initEGL(); // Initializes EGL extensions
std::string getRawGLString(); // For sending to simulator
@@ -103,6 +105,7 @@ public:
bool mHasAMDAssociations = false;
bool mHasNVXGpuMemoryInfo = false;
bool mHasATIMemInfo = false;
+ bool mHasGLXMESAQueryRenderer = false;
bool mIsAMD;
bool mIsNVIDIA;
@@ -147,6 +150,11 @@ public:
// GL Extension String
std::set<std::string> mGLExtensions;
+#if LL_LINUX
+ bool mIsX11 = false;
+ bool mIsWayland = false;
+#endif
+
private:
void reloadExtensionsString();
void initExtensions();
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index fb9c339c62..9e4d1c5b3a 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -27,11 +27,11 @@
#ifndef LL_LLGLHEADERS_H
#define LL_LLGLHEADERS_H
-#if LL_WINDOWS || LL_MESA || LL_SDL_WINDOW || LL_LINUX
+#if LL_WINDOWS || LL_MESA_HEADLESS || LL_SDL_WINDOW || LL_LINUX
//----------------------------------------------------------------------------
- // LL_WINDOWS || LL_MESA || LL_SDL_WINDOW || LL_LINUX
+ // LL_WINDOWS || LL_MESA_HEADLESS || LL_SDL_WINDOW || LL_LINUX
-#if LL_MESA
+#if LL_MESA_HEADLESS
#define GL_GLEXT_PROTOTYPES 1
#else
#define LL_GL_FUNC_POINTER 1
@@ -43,16 +43,22 @@
// quotes so we get libraries/.../GL/ version
#include "GL/glcorearb.h"
-#if LL_WINDOWS && !LL_MESA
+#if LL_WINDOWS && !LL_MESA_HEADLESS
#include "GL/wglext.h"
#endif
-#if LL_LINUX && !LL_MESA
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+#define GLX_GLXEXT_LEGACY
#define __gl_h_ 1
#include "GL/glx.h"
#include "GL/glxext.h"
#endif
+#if LL_LINUX && LL_WAYLAND && !LL_MESA_HEADLESS
+#define EGL_EGL_PROTOTYPES 0
+#include "EGL/egl.h"
+#endif
+
#elif LL_DARWIN
//----------------------------------------------------------------------------
// LL_DARWIN
@@ -64,7 +70,7 @@
#define GL_GLEXT_PROTOTYPES 1
#include "GL/glext.h"
-#endif // LL_MESA / LL_SDL_WINDOW // LL_LINUX / LL_WINDOWS / LL_DARWIN
+#endif // LL_MESA_HEADLESS / LL_SDL_WINDOW // LL_LINUX / LL_WINDOWS / LL_DARWIN
//GL_NVX_gpu_memory_info constants
#ifndef GL_NVX_gpu_memory_info
@@ -145,6 +151,18 @@ extern PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
#endif // LL_WINDOWS
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+// GLX_MESA_query_renderer
+extern PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glXQueryCurrentRendererIntegerMESA;
+extern PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC glXQueryCurrentRendererStringMESA;
+extern PFNGLXQUERYRENDERERINTEGERMESAPROC glXQueryRendererIntegerMESA;
+extern PFNGLXQUERYRENDERERSTRINGMESAPROC glXQueryRendererStringMESA;
+#endif
+
+#if LL_LINUX && LL_WAYLAND &&!LL_MESA_HEADLESS
+extern PFNEGLQUERYSTRINGPROC eglQueryString;
+#endif
+
// We get all functions via getProcAddress when using SDL
// GL_VERSION_1_0
extern PFNGLCULLFACEPROC glCullFace;
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 1f846de35d..aacaef9257 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -160,7 +160,7 @@ if (BUILD_HEADLESS)
${llwindowheadless_HEADER_FILES}
)
- target_compile_definitions( llwindowheadless PUBLIC LL_MESA=1 LL_MESA_HEADLESS=1 )
+ target_compile_definitions( llwindowheadless PUBLIC LL_MESA_HEADLESS=1 )
target_link_libraries (llwindowheadless
llcommon
diff --git a/indra/llwindow/llsdl.cpp b/indra/llwindow/llsdl.cpp
index c97356ee80..d0a7552647 100644
--- a/indra/llwindow/llsdl.cpp
+++ b/indra/llwindow/llsdl.cpp
@@ -64,10 +64,12 @@ void sdl_logger(void *userdata, int category, SDL_LogPriority priority, const ch
void init_sdl(const std::string& app_name)
{
+#ifndef LL_SDL_APP
if (!gSDLMainHandled)
{
SDL_SetMainReady();
}
+#endif
SDL_SetLogOutputFunction(&sdl_logger, nullptr);
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 57110f8634..1cfb0b2acb 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -40,11 +40,11 @@
#include "llpreeditor.h"
#include "llsdl.h"
+#if LL_LINUX
#ifdef LL_GLIB
#include <glib.h>
#endif
-#if LL_LINUX
extern "C" {
# include "fontconfig/fontconfig.h"
}
@@ -55,6 +55,13 @@ extern "C" {
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
+
+#if LL_X11
+LLWindowSDL::X11_DATA LLWindowSDL::sX11Data = {};
+#endif
+#if LL_WAYLAND
+LLWindowSDL::WAYLAND_DATA LLWindowSDL::sWaylandData = {};
+#endif
#endif // LL_LINUX
#if LL_DARWIN
@@ -248,7 +255,7 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b
if(mFullscreen)
{
- tryFindFullscreenSize( width, height );
+ tryFindFullscreenSize(width, height);
}
SDL_PropertiesID props = SDL_CreateProperties();
@@ -322,6 +329,52 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b
mRefreshRate = DEFAULT_REFRESH_RATE;
}
+ /* Grab the window manager specific information */
+#if LL_LINUX
+ if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0)
+ {
+ LL_INFOS() << "Running under X11" << LL_ENDL;
+ mServerProtocol = X11;
+
+ gGLManager.mIsX11 = true;
+
+#if LL_X11
+ sX11Data.xdisplay = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
+ sX11Data.xwindow = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
+ sX11Data.xscreen = (int)SDL_GetNumberProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_SCREEN_NUMBER, -1);
+ if (sX11Data.xdisplay && sX11Data.xwindow)
+ {
+
+ }
+#endif
+
+ gGLManager.initGLX();
+ }
+ else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0)
+ {
+ LL_INFOS() << "Running under Wayland" << LL_ENDL;
+ mServerProtocol = Wayland;
+
+ gGLManager.mIsWayland = true;
+
+#if LL_WAYLAND
+ sWaylandData.display = (struct wl_display *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr);
+ sWaylandData.surface = (struct wl_surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr);
+ if (sWaylandData.display && sWaylandData.surface)
+ {
+ }
+#endif
+
+ gGLManager.initEGL();
+
+ // If set (XWayland) remove DISPLAY, this will prompt dullahan to also use Wayland
+ if(getenv("DISPLAY"))
+ {
+ unsetenv("DISPLAY");
+ }
+ }
+#endif
+
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits);
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits);
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits);
diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h
index 966999ac12..8a8e9dd1bf 100644
--- a/indra/llwindow/llwindowsdl.h
+++ b/indra/llwindow/llwindowsdl.h
@@ -35,6 +35,15 @@
#include "SDL3/SDL.h"
#include "SDL3/SDL_endian.h"
+#ifdef LL_WAYLAND
+#include <wayland-client-protocol.h>
+#endif
+
+#if LL_X11
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+
class LLPreeditor;
class LLWindowSDL final : public LLWindow
@@ -217,6 +226,30 @@ private:
U32 mKeyModifiers = SDL_KMOD_NONE;
void tryFindFullscreenSize(int &aWidth, int &aHeight);
+
+ enum EServerProtocol{ X11, Wayland, Unknown };
+ EServerProtocol mServerProtocol = Unknown;
+public:
+#if LL_X11
+ // X11
+ struct X11_DATA
+ {
+ Display* xdisplay = nullptr;
+ Window xwindow = 0;
+ int xscreen = -1;
+ };
+ static X11_DATA sX11Data;
+#endif
+
+#if LL_WAYLAND
+ // Wayland
+ struct WAYLAND_DATA
+ {
+ struct wl_display* display = nullptr;
+ struct wl_surface* surface = nullptr;
+ };
+ static WAYLAND_DATA sWaylandData;
+#endif
};
class LLSplashScreenSDL : public LLSplashScreen
diff --git a/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl b/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl
index 5837308965..0fa4b32fda 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl
@@ -25,7 +25,6 @@
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
-#extension GL_EXT_gpu_shader4 : enable
/*[EXTRA_CODE_HERE]*/