diagnostic: warn the user if they are using a software GL renderer

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2020-12-23 03:11:25 +00:00
parent b66e5fd422
commit 1df3360989
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
4 changed files with 75 additions and 3 deletions

View File

@ -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[];

View File

@ -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
}

View File

@ -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);

View File

@ -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 :