From 1df3360989b84388bbd36831c7eb42d14c1984a4 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Wed, 23 Dec 2020 03:11:25 +0000 Subject: [PATCH] diagnostic: warn the user if they are using a software GL renderer Signed-off-by: Yuxuan Shui --- src/backend/backend.h | 2 ++ src/backend/gl/glx.c | 54 ++++++++++++++++++++++++++++++++++++++++++- src/backend/gl/glx.h | 5 ++++ src/diagnostic.c | 17 ++++++++++++-- 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/backend/backend.h b/src/backend/backend.h index a0205c4c..7abea9ec 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -240,6 +240,8 @@ struct backend_operations { // =========== Misc ============ /// Return the driver that is been used by the backend enum driver (*detect_driver)(backend_t *backend_data); + + void (*diagnostics)(backend_t *backend_data); }; extern struct backend_operations *backend_list[]; diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index 1f378854..7d66151e 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -26,9 +26,9 @@ #include "backend/gl/glx.h" #include "common.h" #include "compiler.h" -#include "picom.h" #include "config.h" #include "log.h" +#include "picom.h" #include "region.h" #include "utils.h" #include "win.h" @@ -480,6 +480,45 @@ static int glx_buffer_age(backend_t *base) { return (int)val ?: -1; } +static void glx_diagnostics(backend_t *base) { + struct _glx_data *gd = (void *)base; + bool warn_software_rendering = false; + const char *software_renderer_names[] = {"llvmpipe", "SWR", "softpipe"}; + auto glx_vendor = glXGetClientString(gd->display, GLX_VENDOR); + printf("* Driver vendors:\n"); + printf(" * GLX: %s\n", glx_vendor); + printf(" * GL: %s\n", glGetString(GL_VENDOR)); + + auto gl_renderer = (const char *)glGetString(GL_RENDERER); + printf("* GL renderer: %s\n", gl_renderer); + if (strcmp(glx_vendor, "Mesa Project and SGI")) { + for (size_t i = 0; i < ARR_SIZE(software_renderer_names); i++) { + if (strstr(gl_renderer, software_renderer_names[i]) != NULL) { + warn_software_rendering = true; + break; + } + } + } + +#ifdef GLX_MESA_query_renderer + if (glxext.has_GLX_MESA_query_renderer) { + unsigned int accelerated = 0; + glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_ACCELERATED_MESA, &accelerated); + printf("* Accelerated: %d\n", accelerated); + + // Trust GLX_MESA_query_renderer when it's available + warn_software_rendering = (accelerated == 0); + } +#endif + + if (warn_software_rendering) { + printf("\n(You are using a software renderer. Unless you are doing this\n" + "intentionally, this means you don't have a graphics driver\n" + "properly installed. Performance will suffer. Please fix this\n" + "before reporting your issue.)\n"); + } +} + struct backend_operations glx_ops = { .init = glx_init, .deinit = glx_deinit, @@ -497,6 +536,7 @@ struct backend_operations glx_ops = { .create_blur_context = gl_create_blur_context, .destroy_blur_context = gl_destroy_blur_context, .get_blur_size = gl_get_blur_size, + .diagnostics = glx_diagnostics, .max_buffer_age = 5, // Why? }; @@ -546,6 +586,10 @@ PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT; PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT; PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB; +#ifdef GLX_MESA_query_renderer +PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glXQueryCurrentRendererIntegerMESA; +#endif + void glxext_init(Display *dpy, int screen) { if (glxext.initialized) { return; @@ -560,6 +604,9 @@ void glxext_init(Display *dpy, int screen) { check_ext(GLX_EXT_texture_from_pixmap); check_ext(GLX_ARB_create_context); check_ext(GLX_EXT_buffer_age); +#ifdef GLX_MESA_query_renderer + check_ext(GLX_MESA_query_renderer); +#endif #undef check_ext #define lookup(name) (name = (__typeof__(name))glXGetProcAddress((GLubyte *)#name)) @@ -587,5 +634,10 @@ void glxext_init(Display *dpy, int screen) { if (!lookup(glXCreateContextAttribsARB)) { glxext.has_GLX_ARB_create_context = false; } +#ifdef GLX_MESA_query_renderer + if (!lookup(glXQueryCurrentRendererIntegerMESA)) { + glxext.has_GLX_MESA_query_renderer = false; + } +#endif #undef lookup } diff --git a/src/backend/gl/glx.h b/src/backend/gl/glx.h index 99a8e29a..1061f0bb 100644 --- a/src/backend/gl/glx.h +++ b/src/backend/gl/glx.h @@ -54,6 +54,7 @@ struct glxext_info { bool has_GLX_EXT_texture_from_pixmap; bool has_GLX_ARB_create_context; bool has_GLX_EXT_buffer_age; + bool has_GLX_MESA_query_renderer; }; extern struct glxext_info glxext; @@ -69,4 +70,8 @@ extern PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT; extern PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT; extern PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB; +#ifdef GLX_MESA_query_renderer +extern PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glXQueryCurrentRendererIntegerMESA; +#endif + void glxext_init(Display *, int screen); diff --git a/src/diagnostic.c b/src/diagnostic.c index 8aab8bf8..d275b1a1 100644 --- a/src/diagnostic.c +++ b/src/diagnostic.c @@ -22,9 +22,9 @@ void print_diagnostics(session_t *ps, const char *config_file, bool compositor_r printf("* Use Overlay: %s\n", ps->overlay != XCB_NONE ? "Yes" : "No"); if (ps->overlay == XCB_NONE) { if (compositor_running) { - printf(" (Another compositor is already running)\n"); + printf(" (Another compositor is already running)\n"); } else if (session_redirection_mode(ps) != XCB_COMPOSITE_REDIRECT_MANUAL) { - printf(" (Not in manual redirection mode)\n"); + printf(" (Not in manual redirection mode)\n"); } else { printf("\n"); } @@ -35,6 +35,19 @@ void print_diagnostics(session_t *ps, const char *config_file, bool compositor_r printf("* Config file used: %s\n", config_file ?: "None"); printf("\n### Drivers (inaccurate):\n\n"); print_drivers(ps->drivers); + + for (int i = 0; i < NUM_BKEND; i++) { + if (backend_list[i] && backend_list[i]->diagnostics) { + printf("\n### Backend: %s\n\n", BACKEND_STRS[i]); + auto data = backend_list[i]->init(ps); + if (!data) { + printf(" Cannot initialize this backend\n"); + } else { + backend_list[i]->diagnostics(data); + backend_list[i]->deinit(data); + } + } + } } // vim: set noet sw=8 ts=8 :