mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-04-06 03:26:38 +09:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec90166c6e | ||
|
|
d34a1036ef | ||
|
|
bf6011ffcf | ||
|
|
20e101bfe9 | ||
|
|
e99605fec2 | ||
|
|
9e59f5f5cd | ||
|
|
96c62f2db2 |
11
README.md
11
README.md
@@ -14,7 +14,7 @@ This is a cli-only tool, if you want an UI for this check out [GPU Screen Record
|
||||
Supported video codecs:
|
||||
* H264 (default)
|
||||
* HEVC (Optionally with HDR)
|
||||
* AV1 (Optionally with HDR. Not currently supported on NVIDIA if you use GPU Screen Recorder flatpak)
|
||||
* AV1 (Optionally with HDR. Not currently supported on NVIDIA in the flatpak version of GPU Screen Recorder)
|
||||
* VP8
|
||||
* VP9
|
||||
|
||||
@@ -154,6 +154,11 @@ Note that this option is currently only available on X11, or with desktop portal
|
||||
## NVIDIA
|
||||
Nvidia drivers have an issue where CUDA breaks if CUDA is running when suspend/hibernation happens, and it remains broken until you reload the nvidia driver. `extra/gsr-nvidia.conf` will be installed by default when you install GPU Screen Recorder and that should fix this issue. If this doesn't fix the issue for you then your distro may use a different path for modprobe files. In that case you have to install that `extra/gsr-nvidia.conf` yourself into that location.
|
||||
You have to reboot your computer after installing GPU Screen Recorder for the first time for the fix to have any effect.
|
||||
|
||||
# TEMPORARY ISSUES
|
||||
1) Videos are in variable framerate format. Use MPV to play such videos, otherwise you might experience stuttering in the video if you are using a buggy video player. You can try saving the video into a .mkv file instead as some software may have better support for .mkv files (such as kdenlive). You can use the "-fm cfr" option to to use constant framerate mode.
|
||||
2) FLAC audio codec is disabled at the moment because of temporary issues.
|
||||
|
||||
# Examples
|
||||
Look at the [scripts](https://git.dec05eba.com/gpu-screen-recorder/tree/scripts) directory for script examples. For example if you want to automatically save a recording/replay into a folder with the same name as the game you are recording.
|
||||
|
||||
@@ -185,10 +190,6 @@ See [https://git.dec05eba.com/?p=about](https://git.dec05eba.com/?p=about).
|
||||
# Demo
|
||||
[](https://www.youtube.com/watch?v=n5tm0g01n6A)
|
||||
|
||||
# TEMPORARY ISSUES
|
||||
1) Videos are in variable framerate format. Use MPV to play such videos, otherwise you might experience stuttering in the video if you are using a buggy video player. You can try saving the video into a .mkv file instead as some software may have better support for .mkv files (such as kdenlive). You can use the "-fm cfr" option to to use constant framerate mode.
|
||||
2) FLAC audio codec is disabled at the moment because of temporary issues.
|
||||
|
||||
# FAQ
|
||||
## It tells me that my AMD/Intel GPU is not supported or that my GPU doesn't support h264/hevc, but that's not true!
|
||||
Some linux distros (such as manjaro and fedora) disable hardware accelerated h264/hevc on AMD/Intel because of "patent license issues". If you are using an arch-based distro then you can install mesa-git instead of mesa and if you are using another distro then you may have to switch to a better distro. On fedora based distros you can follow this: [Hardware Accelerated Codec](https://rpmfusion.org/Howto/Multimedia).\
|
||||
|
||||
4
TODO
4
TODO
@@ -346,3 +346,7 @@ Support desktop portal hdr capture when this gets merged: https://invent.kde.org
|
||||
Add option to save screenshot as .qoi. Use that then in gsr-ui for the background for the window (capture the monitor that the ui is going to show on). Do that on cosmic and hyprland, which are unable to display things behind the fullscreen window.
|
||||
|
||||
Support pausing recording when recording while replay/streaming.
|
||||
|
||||
Maybe use VK_VALVE_video_encode_rgb_conversion with vulkan encoding for shader-less rgb to yuv conversion. That would allow screen capture with no gpu processing.
|
||||
|
||||
Cursor sometimes doesn't have color when capturing region scaled (on kde plasma wayland at least).
|
||||
@@ -60,7 +60,7 @@ typedef struct {
|
||||
int gsr_color_conversion_init(gsr_color_conversion *self, const gsr_color_conversion_params *params);
|
||||
void gsr_color_conversion_deinit(gsr_color_conversion *self);
|
||||
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, gsr_source_color source_color, bool external_texture, bool alpha_blending);
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, gsr_source_color source_color, bool external_texture);
|
||||
void gsr_color_conversion_clear(gsr_color_conversion *self);
|
||||
void gsr_color_conversion_read_destination_texture(gsr_color_conversion *self, int destination_texture_index, int x, int y, int width, int height, unsigned int color_format, unsigned int data_format, void *pixels);
|
||||
|
||||
|
||||
@@ -58,4 +58,6 @@ vec2i scale_keep_aspect_ratio(vec2i from, vec2i to);
|
||||
|
||||
unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format, int filter);
|
||||
|
||||
bool get_nvidia_driver_version(int *major, int *minor);
|
||||
|
||||
#endif /* GSR_UTILS_H */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.8.1', default_options : ['warning_level=2'])
|
||||
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.8.2', default_options : ['warning_level=2'])
|
||||
|
||||
add_project_arguments('-Wshadow', language : ['c', 'cpp'])
|
||||
if get_option('buildtype') == 'debug'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "gpu-screen-recorder"
|
||||
type = "executable"
|
||||
version = "5.8.1"
|
||||
version = "5.8.2"
|
||||
platforms = ["posix"]
|
||||
|
||||
[config]
|
||||
|
||||
@@ -508,7 +508,7 @@ static void render_drm_cursor(gsr_capture_kms *self, gsr_color_conversion *color
|
||||
gsr_color_conversion_draw(color_conversion, self->cursor_texture_id,
|
||||
cursor_pos, (vec2i){cursor_size.x * scale.x, cursor_size.y * scale.y},
|
||||
(vec2i){0, 0}, cursor_size, cursor_size,
|
||||
gsr_monitor_rotation_to_rotation(rotation), GSR_SOURCE_COLOR_RGB, cursor_texture_id_is_external, true);
|
||||
gsr_monitor_rotation_to_rotation(rotation), GSR_SOURCE_COLOR_RGB, cursor_texture_id_is_external);
|
||||
|
||||
self->params.egl->glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
@@ -536,7 +536,7 @@ static void render_x11_cursor(gsr_capture_kms *self, gsr_color_conversion *color
|
||||
gsr_color_conversion_draw(color_conversion, self->x11_cursor.texture_id,
|
||||
cursor_pos, (vec2i){self->x11_cursor.size.x * scale.x, self->x11_cursor.size.y * scale.y},
|
||||
(vec2i){0, 0}, self->x11_cursor.size, self->x11_cursor.size,
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false, true);
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false);
|
||||
|
||||
self->params.egl->glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
@@ -654,7 +654,7 @@ static int gsr_capture_kms_capture(gsr_capture *cap, gsr_capture_metadata *captu
|
||||
gsr_color_conversion_draw(color_conversion, self->external_texture_fallback ? self->external_input_texture_id : self->input_texture_id,
|
||||
target_pos, output_size,
|
||||
capture_pos, self->capture_size, (vec2i){ drm_fd->width, drm_fd->height },
|
||||
gsr_monitor_rotation_to_rotation(rotation), GSR_SOURCE_COLOR_RGB, self->external_texture_fallback, false);
|
||||
gsr_monitor_rotation_to_rotation(rotation), GSR_SOURCE_COLOR_RGB, self->external_texture_fallback);
|
||||
|
||||
if(self->params.record_cursor) {
|
||||
gsr_kms_response_item *cursor_drm_fd = find_cursor_drm_if_on_monitor(self, drm_fd->connector_id, capture_is_combined_plane);
|
||||
|
||||
@@ -55,40 +55,6 @@ static uint32_t get_output_id_from_display_name(NVFBC_RANDR_OUTPUT_INFO *outputs
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: Test with optimus and open kernel modules */
|
||||
static bool get_driver_version(int *major, int *minor) {
|
||||
*major = 0;
|
||||
*minor = 0;
|
||||
|
||||
FILE *f = fopen("/proc/driver/nvidia/version", "rb");
|
||||
if(!f) {
|
||||
fprintf(stderr, "gsr warning: failed to get nvidia driver version (failed to read /proc/driver/nvidia/version)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[2048];
|
||||
size_t bytes_read = fread(buffer, 1, sizeof(buffer) - 1, f);
|
||||
buffer[bytes_read] = '\0';
|
||||
|
||||
bool success = false;
|
||||
const char *p = strstr(buffer, "Kernel Module");
|
||||
if(p) {
|
||||
p += 13;
|
||||
int driver_major_version = 0, driver_minor_version = 0;
|
||||
if(sscanf(p, "%d.%d", &driver_major_version, &driver_minor_version) == 2) {
|
||||
*major = driver_major_version;
|
||||
*minor = driver_minor_version;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!success)
|
||||
fprintf(stderr, "gsr warning: failed to get nvidia driver version\n");
|
||||
|
||||
fclose(f);
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool version_at_least(int major, int minor, int expected_major, int expected_minor) {
|
||||
return major > expected_major || (major == expected_major && minor >= expected_minor);
|
||||
}
|
||||
@@ -288,7 +254,7 @@ static int gsr_capture_nvfbc_start(gsr_capture *cap, gsr_capture_metadata *captu
|
||||
self->supports_direct_cursor = false;
|
||||
int driver_major_version = 0;
|
||||
int driver_minor_version = 0;
|
||||
if(self->params.direct_capture && get_driver_version(&driver_major_version, &driver_minor_version)) {
|
||||
if(self->params.direct_capture && get_nvidia_driver_version(&driver_major_version, &driver_minor_version)) {
|
||||
fprintf(stderr, "gsr info: detected nvidia version: %d.%d\n", driver_major_version, driver_minor_version);
|
||||
|
||||
// TODO:
|
||||
@@ -397,7 +363,7 @@ static int gsr_capture_nvfbc_capture(gsr_capture *cap, gsr_capture_metadata *cap
|
||||
gsr_color_conversion_draw(color_conversion, self->setup_params.dwTextures[grab_params.dwTextureIndex],
|
||||
target_pos, (vec2i){output_size.x, output_size.y},
|
||||
self->params.region_position, frame_size, original_frame_size,
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_BGR, false, false);
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_BGR, false);
|
||||
|
||||
//self->params.egl->glFlush();
|
||||
//self->params.egl->glFinish();
|
||||
|
||||
@@ -373,7 +373,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
||||
gsr_color_conversion_draw(color_conversion, self->pipewire_data.using_external_image ? self->texture_map.external_texture_id : self->texture_map.texture_id,
|
||||
target_pos, output_size,
|
||||
(vec2i){self->pipewire_data.region.x, self->pipewire_data.region.y}, (vec2i){self->pipewire_data.region.width, self->pipewire_data.region.height}, actual_texture_size,
|
||||
gsr_monitor_rotation_to_rotation(self->pipewire_data.rotation), GSR_SOURCE_COLOR_RGB, self->pipewire_data.using_external_image, fourcc_alpha);
|
||||
gsr_monitor_rotation_to_rotation(self->pipewire_data.rotation), GSR_SOURCE_COLOR_RGB, self->pipewire_data.using_external_image);
|
||||
|
||||
if(self->params.record_cursor && self->texture_map.cursor_texture_id > 0 && self->pipewire_data.cursor_region.width > 0) {
|
||||
const vec2d scale = {
|
||||
@@ -394,7 +394,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
||||
(vec2i){0, 0},
|
||||
(vec2i){self->pipewire_data.cursor_region.width, self->pipewire_data.cursor_region.height},
|
||||
(vec2i){self->pipewire_data.cursor_region.width, self->pipewire_data.cursor_region.height},
|
||||
gsr_monitor_rotation_to_rotation(self->pipewire_data.rotation), GSR_SOURCE_COLOR_RGB, false, true);
|
||||
gsr_monitor_rotation_to_rotation(self->pipewire_data.rotation), GSR_SOURCE_COLOR_RGB, false);
|
||||
self->params.egl->glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
|
||||
@@ -244,7 +244,7 @@ static int gsr_capture_xcomposite_capture(gsr_capture *cap, gsr_capture_metadata
|
||||
gsr_color_conversion_draw(color_conversion, window_texture_get_opengl_texture_id(&self->window_texture),
|
||||
target_pos, output_size,
|
||||
(vec2i){0, 0}, self->texture_size, self->texture_size,
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false, false);
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false);
|
||||
|
||||
if(self->params.record_cursor && self->cursor.visible) {
|
||||
const vec2d scale = {
|
||||
@@ -265,7 +265,7 @@ static int gsr_capture_xcomposite_capture(gsr_capture *cap, gsr_capture_metadata
|
||||
gsr_color_conversion_draw(color_conversion, self->cursor.texture_id,
|
||||
cursor_pos, (vec2i){self->cursor.size.x * scale.x, self->cursor.size.y * scale.y},
|
||||
(vec2i){0, 0}, self->cursor.size, self->cursor.size,
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false, true);
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false);
|
||||
}
|
||||
|
||||
//self->params.egl->glFlush();
|
||||
|
||||
@@ -160,7 +160,7 @@ static int gsr_capture_ximage_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
||||
gsr_color_conversion_draw(color_conversion, self->texture_id,
|
||||
target_pos, output_size,
|
||||
(vec2i){0, 0}, self->capture_size, self->capture_size,
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false, false);
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false);
|
||||
|
||||
if(self->params.record_cursor && self->cursor.visible) {
|
||||
const vec2d scale = {
|
||||
@@ -181,7 +181,7 @@ static int gsr_capture_ximage_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
||||
gsr_color_conversion_draw(color_conversion, self->cursor.texture_id,
|
||||
cursor_pos, (vec2i){self->cursor.size.x * scale.x, self->cursor.size.y * scale.y},
|
||||
(vec2i){0, 0}, self->cursor.size, self->cursor.size,
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false, true);
|
||||
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false);
|
||||
|
||||
self->params.egl->glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
@@ -39,10 +39,6 @@
|
||||
" 0.060118, 0.429412, -0.038049, 0.000000,\n" \
|
||||
" 0.062745, 0.500000, 0.500000, 1.000000);\n"
|
||||
|
||||
static int max_int(int a, int b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
static const char* color_format_range_get_transform_matrix(gsr_destination_color color_format, gsr_color_range color_range) {
|
||||
switch(color_format) {
|
||||
case GSR_DESTINATION_COLOR_NV12: {
|
||||
@@ -483,6 +479,12 @@ static void gsr_color_conversion_draw_graphics(gsr_color_conversion *self, unsig
|
||||
const vec2i dest_texture_size = self->params.destination_textures_size[0];
|
||||
const int texture_target = external_texture ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
|
||||
|
||||
if(rotation == GSR_ROT_90 || rotation == GSR_ROT_270) {
|
||||
const float tmp = texture_size.x;
|
||||
texture_size.x = texture_size.y;
|
||||
texture_size.y = tmp;
|
||||
}
|
||||
|
||||
self->params.egl->glBindTexture(texture_target, texture_id);
|
||||
gsr_color_conversion_swizzle_texture_source(self, source_color);
|
||||
|
||||
@@ -501,18 +503,11 @@ static void gsr_color_conversion_draw_graphics(gsr_color_conversion *self, unsig
|
||||
(float)source_position.y / (texture_size.y == 0 ? 1.0f : (float)texture_size.y),
|
||||
};
|
||||
|
||||
vec2f texture_size_norm = {
|
||||
const vec2f texture_size_norm = {
|
||||
(float)source_size.x / (texture_size.x == 0 ? 1.0f : (float)texture_size.x),
|
||||
(float)source_size.y / (texture_size.y == 0 ? 1.0f : (float)texture_size.y),
|
||||
};
|
||||
|
||||
if(rotation == GSR_ROT_90 || rotation == GSR_ROT_270) {
|
||||
const float ratio_x = (double)source_size.x / (double)source_size.y;
|
||||
const float ratio_y = (double)source_size.y / (double)source_size.x;
|
||||
texture_size_norm.x *= ratio_y;
|
||||
texture_size_norm.y *= ratio_x;
|
||||
}
|
||||
|
||||
const float vertices[] = {
|
||||
-1.0f + 0.0f, -1.0f + 0.0f + size_norm.y, texture_pos_norm.x, texture_pos_norm.y + texture_size_norm.y,
|
||||
-1.0f + 0.0f, -1.0f + 0.0f, texture_pos_norm.x, texture_pos_norm.y,
|
||||
@@ -574,7 +569,7 @@ static void gsr_color_conversion_draw_graphics(gsr_color_conversion *self, unsig
|
||||
self->params.egl->glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, gsr_source_color source_color, bool external_texture, bool alpha_blending) {
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, gsr_source_color source_color, bool external_texture) {
|
||||
assert(!external_texture || self->params.load_external_image_shader);
|
||||
if(external_texture && !self->params.load_external_image_shader) {
|
||||
fprintf(stderr, "gsr error: gsr_color_conversion_draw: external texture not loaded\n");
|
||||
|
||||
15
src/main.cpp
15
src/main.cpp
@@ -3102,6 +3102,10 @@ int main(int argc, char **argv) {
|
||||
|
||||
set_display_server_environment_variables();
|
||||
|
||||
// Linux nvidia driver 580.105.08 added the environment variable CUDA_DISABLE_PERF_BOOST to disable the p2 power level issue,
|
||||
// where running cuda (which includes nvenc) causes the gpu to be forcefully set to p2 power level which on many nvidia gpus
|
||||
// decreases gpu performance in games. On my GTX 1080 it decreased game performance by 10% for absolutely no reason.
|
||||
setenv("CUDA_DISABLE_PERF_BOOST", "1", true);
|
||||
// Stop nvidia driver from buffering frames
|
||||
setenv("__GL_MaxFramesAllowed", "1", true);
|
||||
// If this is set to 1 then cuGraphicsGLRegisterImage will fail for egl context with error: invalid OpenGL or DirectX context,
|
||||
@@ -3139,6 +3143,15 @@ int main(int argc, char **argv) {
|
||||
if(!args_parser_parse(&arg_parser, argc, argv, &arg_handlers, NULL))
|
||||
_exit(1);
|
||||
|
||||
if(arg_parser.overclock) {
|
||||
int driver_major_version = 0;
|
||||
int driver_minor_version = 0;
|
||||
if(get_nvidia_driver_version(&driver_major_version, &driver_minor_version) && (driver_major_version > 580 || (driver_major_version == 580 && driver_minor_version >= 105))) {
|
||||
fprintf(stderr, "gsr info: overclocking was set by has been forcefully disabled since your gpu supports CUDA_DISABLE_PERF_BOOST to workaround driver issue (overclocking is not needed)\n");
|
||||
arg_parser.overclock = false;
|
||||
}
|
||||
}
|
||||
|
||||
//av_log_set_level(AV_LOG_TRACE);
|
||||
|
||||
const Arg *audio_input_arg = args_parser_get_arg(&arg_parser, "-a");
|
||||
@@ -3808,7 +3821,7 @@ int main(int argc, char **argv) {
|
||||
gsr_color_conversion_draw(&color_conversion, plugins.texture,
|
||||
{0, 0}, {capture_metadata.width, capture_metadata.height},
|
||||
{0, 0}, {capture_metadata.width, capture_metadata.height},
|
||||
{capture_metadata.width, capture_metadata.height}, GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false, true);
|
||||
{capture_metadata.width, capture_metadata.height}, GSR_ROT_0, GSR_SOURCE_COLOR_RGB, false);
|
||||
}
|
||||
|
||||
if(capture_has_synchronous_task) {
|
||||
|
||||
36
src/utils.c
36
src/utils.c
@@ -148,6 +148,8 @@ int get_connector_type_by_name(const char *name) {
|
||||
return 3;
|
||||
else if(len >= 4 && strncmp(name, "eDP-", 4) == 0)
|
||||
return 4;
|
||||
else if(len >= 4 && strncmp(name, "DVI-", 4) == 0)
|
||||
return 5;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
@@ -606,3 +608,37 @@ unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal
|
||||
egl->glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
/* TODO: Test with optimus and open kernel modules */
|
||||
bool get_nvidia_driver_version(int *major, int *minor) {
|
||||
*major = 0;
|
||||
*minor = 0;
|
||||
|
||||
FILE *f = fopen("/proc/driver/nvidia/version", "rb");
|
||||
if(!f) {
|
||||
fprintf(stderr, "gsr warning: failed to get nvidia driver version (failed to read /proc/driver/nvidia/version)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[2048];
|
||||
size_t bytes_read = fread(buffer, 1, sizeof(buffer) - 1, f);
|
||||
buffer[bytes_read] = '\0';
|
||||
|
||||
bool success = false;
|
||||
const char *p = strstr(buffer, "Kernel Module");
|
||||
if(p) {
|
||||
p += 13;
|
||||
int driver_major_version = 0, driver_minor_version = 0;
|
||||
if(sscanf(p, "%d.%d", &driver_major_version, &driver_minor_version) == 2) {
|
||||
*major = driver_major_version;
|
||||
*minor = driver_minor_version;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!success)
|
||||
fprintf(stderr, "gsr warning: failed to get nvidia driver version\n");
|
||||
|
||||
fclose(f);
|
||||
return success;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user