diff options
author | dec05eba <dec05eba@protonmail.com> | 2024-11-21 00:25:56 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2024-11-21 00:25:56 +0100 |
commit | 02673c46445a78324416e08ec61284012f7bcc8d (patch) | |
tree | 54cf80ba361b6981cdecebe74e89c8b89dd8680a | |
parent | 68c9781f44bddc7256677668b559cd02f29bb059 (diff) |
Fix portal capture on broken amd drivers: fallback to opengl copy instead of vaapi on known buggy mesa version
-rw-r--r-- | include/defs.h | 5 | ||||
-rw-r--r-- | include/egl.h | 1 | ||||
-rw-r--r-- | include/utils.h | 1 | ||||
-rw-r--r-- | src/capture/kms.c | 4 | ||||
-rw-r--r-- | src/capture/portal.c | 4 | ||||
-rw-r--r-- | src/capture/xcomposite.c | 4 | ||||
-rw-r--r-- | src/utils.c | 27 |
7 files changed, 46 insertions, 0 deletions
diff --git a/include/defs.h b/include/defs.h index 8fd2ddc..76e798e 100644 --- a/include/defs.h +++ b/include/defs.h @@ -13,6 +13,11 @@ typedef struct { gsr_gpu_vendor vendor; int gpu_version; /* 0 if unknown */ bool is_steam_deck; + + /* Only currently set for Mesa. 0 if unknown format */ + int driver_major; + int driver_minor; + int driver_patch; } gsr_gpu_info; typedef enum { diff --git a/include/egl.h b/include/egl.h index 82014b9..8958f31 100644 --- a/include/egl.h +++ b/include/egl.h @@ -131,6 +131,7 @@ typedef void(*__GLXextFuncPtr)(void); #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 #define GL_COMPILE_STATUS 0x8B81 #define GL_INFO_LOG_LENGTH 0x8B84 diff --git a/include/utils.h b/include/utils.h index 984b963..5b771ba 100644 --- a/include/utils.h +++ b/include/utils.h @@ -39,6 +39,7 @@ bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl, const gsr_monitor *monitor); bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info); +bool gl_driver_version_greater_than(const gsr_egl *egl, int major, int minor, int patch); /* |output| should be at least 128 bytes in size */ bool gsr_get_valid_card_path(gsr_egl *egl, char *output, bool is_monitor_capture); diff --git a/src/capture/kms.c b/src/capture/kms.c index c85811e..fcf3b85 100644 --- a/src/capture/kms.c +++ b/src/capture/kms.c @@ -224,6 +224,10 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c video_codec_context->height = FFALIGN(self->params.output_resolution.y, 2); } + self->fast_path_failed = self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && !gl_driver_version_greater_than(self->params.egl, 24, 0, 9); + if(self->fast_path_failed) + fprintf(stderr, "gsr warning: gsr_capture_kms_start: your amd driver (mesa) version is known to be buggy (<= version 24.0.9), falling back to opengl copy\n"); + frame->width = video_codec_context->width; frame->height = video_codec_context->height; diff --git a/src/capture/portal.c b/src/capture/portal.c index d68e86f..a441299 100644 --- a/src/capture/portal.c +++ b/src/capture/portal.c @@ -310,6 +310,10 @@ static int gsr_capture_portal_start(gsr_capture *cap, AVCodecContext *video_code video_codec_context->height = FFALIGN(self->params.output_resolution.y, 2); } + self->fast_path_failed = self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && !gl_driver_version_greater_than(self->params.egl, 24, 0, 9); + if(self->fast_path_failed) + fprintf(stderr, "gsr warning: gsr_capture_kms_start: your amd driver (mesa) version is known to be buggy (<= version 24.0.9), falling back to opengl copy\n"); + frame->width = video_codec_context->width; frame->height = video_codec_context->height; diff --git a/src/capture/xcomposite.c b/src/capture/xcomposite.c index 2867b45..79cd60a 100644 --- a/src/capture/xcomposite.c +++ b/src/capture/xcomposite.c @@ -122,6 +122,10 @@ static int gsr_capture_xcomposite_start(gsr_capture *cap, AVCodecContext *video_ video_codec_context->height = FFALIGN(self->params.output_resolution.y, 2); } + self->fast_path_failed = self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && !gl_driver_version_greater_than(self->params.egl, 24, 0, 9); + if(self->fast_path_failed) + fprintf(stderr, "gsr warning: gsr_capture_kms_start: your amd driver (mesa) version is known to be buggy (<= version 24.0.9), falling back to opengl copy\n"); + frame->width = video_codec_context->width; frame->height = video_codec_context->height; diff --git a/src/utils.c b/src/utils.c index 188718f..be5e58b 100644 --- a/src/utils.c +++ b/src/utils.c @@ -415,9 +415,13 @@ bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info) { bool supported = true; const unsigned char *gl_vendor = egl->glGetString(GL_VENDOR); const unsigned char *gl_renderer = egl->glGetString(GL_RENDERER); + const unsigned char *gl_version = egl->glGetString(GL_VERSION); info->gpu_version = 0; info->is_steam_deck = false; + info->driver_major = 0; + info->driver_minor = 0; + info->driver_patch = 0; if(!gl_vendor) { fprintf(stderr, "gsr error: failed to get gpu vendor\n"); @@ -455,10 +459,33 @@ bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info) { info->is_steam_deck = strstr((const char*)gl_renderer, "vangogh") != NULL; } + if(gl_version) { + const char *mesa_p = strstr((const char*)gl_version, "Mesa "); + if(mesa_p) { + mesa_p += 5; + int major = 0; + int minor = 0; + int patch = 0; + if(sscanf(mesa_p, "%d.%d.%d", &major, &minor, &patch) == 3) { + info->driver_major = major; + info->driver_minor = minor; + info->driver_patch = patch; + } + } + } + end: return supported; } +static bool version_greater_than(int major, int minor, int patch, int other_major, int other_minor, int other_patch) { + return (major > other_major) || (major == other_major && minor > other_minor) || (major == other_major && minor == other_minor && patch > other_patch); +} + +bool gl_driver_version_greater_than(const gsr_egl *egl, int major, int minor, int patch) { + return version_greater_than(egl->gpu_info.driver_major, egl->gpu_info.driver_minor, egl->gpu_info.driver_patch, major, minor, patch); +} + static bool try_card_has_valid_plane(const char *card_path) { drmVersion *ver = NULL; drmModePlaneResPtr planes = NULL; |