aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--gpu-screen-recorder.13
-rw-r--r--include/args_parser.h1
-rw-r--r--include/cuda.h6
-rw-r--r--include/encoder/video/nvenc.h1
-rw-r--r--include/overclock.h17
-rw-r--r--include/xnvctrl.h45
-rw-r--r--meson.build2
-rw-r--r--src/args_parser.c18
-rw-r--r--src/codec_query/nvenc.c2
-rw-r--r--src/cuda.c17
-rw-r--r--src/encoder/video/nvenc.c7
-rw-r--r--src/main.cpp20
-rw-r--r--src/overclock.c279
-rw-r--r--src/xnvctrl.c46
15 files changed, 15 insertions, 450 deletions
diff --git a/README.md b/README.md
index ad937b3..9e2a789 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,6 @@ There are also additional dependencies needed at runtime depending on your GPU v
* cuda runtime (libcuda.so.1) (libnvidia-compute)
* nvenc (libnvidia-encode)
* nvfbc (libnvidia-fbc1, when recording the screen on x11)
-* xnvctrl (libxnvctrl0, when using the `-oc` option)
# How to use
Run `gpu-screen-recorder --help` to see all options and run `man gpu-screen-recorder` to see more detailed explanations for the options and also examples.\
diff --git a/gpu-screen-recorder.1 b/gpu-screen-recorder.1
index 075daf6..c69dc0f 100644
--- a/gpu-screen-recorder.1
+++ b/gpu-screen-recorder.1
@@ -329,9 +329,6 @@ Clear buffer after saving replay (default: no).
Organize replays in date-based folders (default: no).
.SS Advanced Options
.TP
-.BI \-oc " yes|no"
-Overclock NVIDIA memory (X11 only). Requires Coolbits=12. Use at own risk.
-.TP
.BI \-p " plugin.so"
Load plugin (.so file). Can be specified multiple times.
.TP
diff --git a/include/args_parser.h b/include/args_parser.h
index 98fb30c..75d8bfa 100644
--- a/include/args_parser.h
+++ b/include/args_parser.h
@@ -97,7 +97,6 @@ typedef struct {
bool date_folders;
bool restore_portal_session;
bool restart_replay_on_save;
- bool overclock;
bool write_first_frame_ts;
bool is_livestream;
bool is_output_piped;
diff --git a/include/cuda.h b/include/cuda.h
index fd1f9f9..fb47b12 100644
--- a/include/cuda.h
+++ b/include/cuda.h
@@ -1,7 +1,6 @@
#ifndef GSR_CUDA_H
#define GSR_CUDA_H
-#include "overclock.h"
#include <stddef.h>
#include <stdbool.h>
@@ -75,9 +74,6 @@ typedef struct CUgraphicsResource_st *CUgraphicsResource;
typedef struct gsr_cuda gsr_cuda;
struct gsr_cuda {
- gsr_overclock overclock;
- bool do_overclock;
-
void *library;
CUcontext cu_ctx;
@@ -102,7 +98,7 @@ struct gsr_cuda {
CUresult (*cuGraphicsSubResourceGetMappedArray)(CUarray *pArray, CUgraphicsResource resource, unsigned int arrayIndex, unsigned int mipLevel);
};
-bool gsr_cuda_load(gsr_cuda *self, Display *display, bool overclock);
+bool gsr_cuda_load(gsr_cuda *self);
void gsr_cuda_unload(gsr_cuda *self);
#endif /* GSR_CUDA_H */
diff --git a/include/encoder/video/nvenc.h b/include/encoder/video/nvenc.h
index d4a906b..f6af2fc 100644
--- a/include/encoder/video/nvenc.h
+++ b/include/encoder/video/nvenc.h
@@ -7,7 +7,6 @@ typedef struct gsr_egl gsr_egl;
typedef struct {
gsr_egl *egl;
- bool overclock;
gsr_color_depth color_depth;
} gsr_video_encoder_nvenc_params;
diff --git a/include/overclock.h b/include/overclock.h
deleted file mode 100644
index d6ff901..0000000
--- a/include/overclock.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef GSR_OVERCLOCK_H
-#define GSR_OVERCLOCK_H
-
-#include "xnvctrl.h"
-
-typedef struct {
- gsr_xnvctrl xnvctrl;
- int num_performance_levels;
-} gsr_overclock;
-
-bool gsr_overclock_load(gsr_overclock *self, Display *display);
-void gsr_overclock_unload(gsr_overclock *self);
-
-bool gsr_overclock_start(gsr_overclock *self);
-void gsr_overclock_stop(gsr_overclock *self);
-
-#endif /* GSR_OVERCLOCK_H */
diff --git a/include/xnvctrl.h b/include/xnvctrl.h
deleted file mode 100644
index 33fc442..0000000
--- a/include/xnvctrl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef GSR_XNVCTRL_H
-#define GSR_XNVCTRL_H
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#define NV_CTRL_GPU_NVCLOCK_OFFSET 409
-#define NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET 410
-#define NV_CTRL_GPU_NVCLOCK_OFFSET_ALL_PERFORMANCE_LEVELS 424
-#define NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET_ALL_PERFORMANCE_LEVELS 425
-
-#define NV_CTRL_TARGET_TYPE_GPU 1
-
-#define NV_CTRL_STRING_PERFORMANCE_MODES 29
-
-typedef struct _XDisplay Display;
-
-typedef struct {
- int type;
- union {
- struct {
- int64_t min;
- int64_t max;
- } range;
- struct {
- unsigned int ints;
- } bits;
- } u;
- unsigned int permissions;
-} NVCTRLAttributeValidValuesRec;
-
-typedef struct {
- Display *display;
- void *library;
-
- int (*XNVCTRLQueryExtension)(Display *dpy, int *event_basep, int *error_basep);
- int (*XNVCTRLSetTargetAttributeAndGetStatus)(Display *dpy, int target_type, int target_id, unsigned int display_mask, unsigned int attribute, int value);
- int (*XNVCTRLQueryValidTargetAttributeValues)(Display *dpy, int target_type, int target_id, unsigned int display_mask, unsigned int attribute, NVCTRLAttributeValidValuesRec *values);
- int (*XNVCTRLQueryTargetStringAttribute)(Display *dpy, int target_type, int target_id, unsigned int display_mask, unsigned int attribute, char **ptr);
-} gsr_xnvctrl;
-
-bool gsr_xnvctrl_load(gsr_xnvctrl *self, Display *display);
-void gsr_xnvctrl_unload(gsr_xnvctrl *self);
-
-#endif /* GSR_XNVCTRL_H */
diff --git a/meson.build b/meson.build
index 3f3bc3f..da08c26 100644
--- a/meson.build
+++ b/meson.build
@@ -32,8 +32,6 @@ src = [
'src/replay_buffer/replay_buffer_disk.c',
'src/egl.c',
'src/cuda.c',
- 'src/xnvctrl.c',
- 'src/overclock.c',
'src/window_texture.c',
'src/shader.c',
'src/color_conversion.c',
diff --git a/src/args_parser.c b/src/args_parser.c
index a785172..eddbb6f 100644
--- a/src/args_parser.c
+++ b/src/args_parser.c
@@ -199,7 +199,7 @@ static void usage_header(void) {
const char *program_name = inside_flatpak ? "flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder" : "gpu-screen-recorder";
printf("usage: %s -w <window_id|monitor|focused|portal|region|v4l2_device_path> [-c <container_format>] [-s WxH] [-region WxH+X+Y] [-f <fps>] [-a <audio_input>] "
"[-q <quality>] [-r <replay_buffer_size_sec>] [-replay-storage ram|disk] [-restart-replay-on-save yes|no] "
- "[-k h264|hevc|av1|vp8|vp9|hevc_hdr|av1_hdr|hevc_10bit|av1_10bit] [-ac aac|opus|flac] [-ab <bitrate>] [-oc yes|no] [-fm cfr|vfr|content] "
+ "[-k h264|hevc|av1|vp8|vp9|hevc_hdr|av1_hdr|hevc_10bit|av1_10bit] [-ac aac|opus|flac] [-ab <bitrate>] [-fm cfr|vfr|content] "
"[-bm auto|qp|vbr|cbr] [-cr limited|full] [-tune performance|quality] [-df yes|no] [-sc <script_path>] [-p <plugin_path>] "
"[-cursor yes|no] [-keyint <value>] [-restore-portal-session yes|no] [-portal-session-token-filepath filepath] [-encoder gpu|cpu] "
"[-fallback-cpu-encoding yes|no] [-o <output_file>] [-ro <output_directory>] [-ffmpeg-opts <options>] [--list-capture-options [card_path]] "
@@ -261,7 +261,7 @@ static bool args_parser_set_values(args_parser *self) {
self->date_folders = args_get_boolean_by_key(self->args, NUM_ARGS, "-df", false);
self->restore_portal_session = args_get_boolean_by_key(self->args, NUM_ARGS, "-restore-portal-session", false);
self->restart_replay_on_save = args_get_boolean_by_key(self->args, NUM_ARGS, "-restart-replay-on-save", false);
- self->overclock = args_get_boolean_by_key(self->args, NUM_ARGS, "-oc", false);
+ const bool overclock = args_get_boolean_by_key(self->args, NUM_ARGS, "-oc", false);
self->fallback_cpu_encoding = args_get_boolean_by_key(self->args, NUM_ARGS, "-fallback-cpu-encoding", false);
self->write_first_frame_ts = args_get_boolean_by_key(self->args, NUM_ARGS, "-write-first-frame-ts", false);
self->low_power = args_get_boolean_by_key(self->args, NUM_ARGS, "-low-power", false);
@@ -271,6 +271,10 @@ static bool args_parser_set_values(args_parser *self) {
self->keyint = args_get_double_by_key(self->args, NUM_ARGS, "-keyint", 2.0);
+ if(overclock) {
+ fprintf(stderr, "gsr info: the overclock option (-oc) is deprecated and no longer has any effect as it's no longer needed (on GPUs that are 12 years old or younger)\n");
+ }
+
if(self->audio_codec == GSR_AUDIO_CODEC_FLAC) {
fprintf(stderr, "gsr warning: flac audio codec is temporary disabled, using opus audio codec instead\n");
self->audio_codec = GSR_AUDIO_CODEC_OPUS;
@@ -690,16 +694,6 @@ bool args_parser_validate_with_gl_info(args_parser *self, gsr_egl *egl) {
self->bitrate_mode = GSR_BITRATE_MODE_QP;
}
- if(egl->gpu_info.vendor != GSR_GPU_VENDOR_NVIDIA && self->overclock) {
- fprintf(stderr, "gsr info: overclock option has no effect on amd/intel, ignoring option\n");
- self->overclock = false;
- }
-
- if(egl->gpu_info.vendor == GSR_GPU_VENDOR_NVIDIA && self->overclock && wayland) {
- fprintf(stderr, "gsr info: overclocking is not possible on nvidia on wayland, ignoring option\n");
- self->overclock = false;
- }
-
if(egl->gpu_info.is_steam_deck) {
fprintf(stderr, "gsr warning: steam deck has multiple driver issues. One of them has been reported here: https://github.com/ValveSoftware/SteamOS/issues/1609\n"
"If you have issues with GPU Screen Recorder on steam deck that you don't have on a desktop computer then report the issue to Valve and/or AMD.\n");
diff --git a/src/codec_query/nvenc.c b/src/codec_query/nvenc.c
index 5e52807..37c25ba 100644
--- a/src/codec_query/nvenc.c
+++ b/src/codec_query/nvenc.c
@@ -197,7 +197,7 @@ bool gsr_get_supported_video_codecs_nvenc(gsr_supported_video_codecs *video_code
gsr_cuda cuda;
memset(&cuda, 0, sizeof(cuda));
- if(!gsr_cuda_load(&cuda, NULL, false)) {
+ if(!gsr_cuda_load(&cuda)) {
fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: failed to load cuda\n");
goto done;
}
diff --git a/src/cuda.c b/src/cuda.c
index 00683cf..bfafbcd 100644
--- a/src/cuda.c
+++ b/src/cuda.c
@@ -5,9 +5,8 @@
#include <dlfcn.h>
#include <assert.h>
-bool gsr_cuda_load(gsr_cuda *self, Display *display, bool do_overclock) {
+bool gsr_cuda_load(gsr_cuda *self) {
memset(self, 0, sizeof(gsr_cuda));
- self->do_overclock = do_overclock;
dlerror(); /* clear */
void *lib = dlopen("libcuda.so.1", RTLD_LAZY);
@@ -83,15 +82,6 @@ bool gsr_cuda_load(gsr_cuda *self, Display *display, bool do_overclock) {
goto fail;
}
- if(self->do_overclock && display) {
- if(gsr_overclock_load(&self->overclock, display))
- gsr_overclock_start(&self->overclock);
- else
- fprintf(stderr, "gsr warning: gsr_cuda_load: failed to load xnvctrl, failed to overclock memory transfer rate\n");
- } else if(self->do_overclock && !display) {
- fprintf(stderr, "gsr warning: gsr_cuda_load: overclocking enabled but no X server is running. Overclocking has been disabled\n");
- }
-
self->library = lib;
return true;
@@ -102,11 +92,6 @@ bool gsr_cuda_load(gsr_cuda *self, Display *display, bool do_overclock) {
}
void gsr_cuda_unload(gsr_cuda *self) {
- if(self->do_overclock && self->overclock.xnvctrl.library) {
- gsr_overclock_stop(&self->overclock);
- gsr_overclock_unload(&self->overclock);
- }
-
if(self->library) {
if(self->cu_ctx) {
self->cuCtxDestroy_v2(self->cu_ctx);
diff --git a/src/encoder/video/nvenc.c b/src/encoder/video/nvenc.c
index 0318a17..dd877c5 100644
--- a/src/encoder/video/nvenc.c
+++ b/src/encoder/video/nvenc.c
@@ -1,7 +1,7 @@
#include "../../../include/encoder/video/nvenc.h"
#include "../../../include/egl.h"
#include "../../../include/cuda.h"
-#include "../../../include/window/window.h"
+#include "../../../include/utils.h"
#include <libavcodec/avcodec.h>
#include <libavutil/hwcontext_cuda.h>
@@ -116,10 +116,7 @@ static void gsr_video_encoder_nvenc_stop(gsr_video_encoder_nvenc *self, AVCodecC
static bool gsr_video_encoder_nvenc_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
gsr_video_encoder_nvenc *self = encoder->priv;
- const bool is_x11 = gsr_window_get_display_server(self->params.egl->window) == GSR_DISPLAY_SERVER_X11;
- const bool overclock = is_x11 ? self->params.overclock : false;
- Display *display = is_x11 ? gsr_window_get_display(self->params.egl->window) : NULL;
- if(!gsr_cuda_load(&self->cuda, display, overclock)) {
+ if(!gsr_cuda_load(&self->cuda)) {
fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_start: failed to load cuda\n");
gsr_video_encoder_nvenc_stop(self, video_codec_context);
return false;
diff --git a/src/main.cpp b/src/main.cpp
index 9abc6be..b6471eb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1551,7 +1551,6 @@ static gsr_video_encoder* create_video_encoder(gsr_egl *egl, const args_parser &
case GSR_GPU_VENDOR_NVIDIA: {
gsr_video_encoder_nvenc_params params;
params.egl = egl;
- params.overclock = arg_parser.overclock;
params.color_depth = color_depth;
video_encoder = gsr_video_encoder_nvenc_create(&params);
break;
@@ -3571,6 +3570,10 @@ static void validate_args_with_capture_sources(args_parser &arg_parser, const st
fprintf(stderr, "gsr info: option '-w portal' was used without '-restore-portal-session yes'. The previous screencast session will be ignored\n");
}
+static void install_cuda_no_stable_perf_limit() {
+
+}
+
int main(int argc, char **argv) {
setlocale(LC_ALL, "C"); // Sigh... stupid C
#ifdef __GLIBC__
@@ -3645,21 +3648,6 @@ int main(int argc, char **argv) {
}
validate_args_with_capture_sources(arg_parser, capture_sources);
- // TODO: Remove, this isn't true
- 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 but 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;
- }
- }
-
- if(arg_parser.overclock && video_codec_is_vulkan(arg_parser.video_codec)) {
- fprintf(stderr, "gsr info: overclocking was set but has been forcefully disabled since you're using vulkan video encoder which doesn't suffer from cuda p2 power level issues\n");
- arg_parser.overclock = false;
- }
-
//av_log_set_level(AV_LOG_TRACE);
const Arg *audio_input_arg = args_parser_get_arg(&arg_parser, "-a");
diff --git a/src/overclock.c b/src/overclock.c
deleted file mode 100644
index f9375d5..0000000
--- a/src/overclock.c
+++ /dev/null
@@ -1,279 +0,0 @@
-#include "../include/overclock.h"
-#include <X11/Xlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-// HACK!!!: When a program uses cuda (including nvenc) then the nvidia driver drops to max performance level - 1 (memory transfer rate is dropped and possibly graphics clock).
-// Nvidia does this because in some very extreme cases of cuda there can be memory corruption when running at max memory transfer rate.
-// So to get around this we overclock memory transfer rate (maybe this should also be done for graphics clock?) to the best performance level while GPU Screen Recorder is running.
-
-static int min_int(int a, int b) {
- return a < b ? a : b;
-}
-
-// Fields are 0 if not set
-typedef struct {
- int perf;
-
- int nv_clock;
- int nv_clock_min;
- int nv_clock_max;
-
- int mem_clock;
- int mem_clock_min;
- int mem_clock_max;
-
- int mem_transfer_rate;
- int mem_transfer_rate_min;
- int mem_transfer_rate_max;
-} NVCTRLPerformanceLevel;
-
-#define MAX_PERFORMANCE_LEVELS 12
-typedef struct {
- NVCTRLPerformanceLevel performance_level[MAX_PERFORMANCE_LEVELS];
- int num_performance_levels;
-} NVCTRLPerformanceLevelQuery;
-
-typedef void (*split_callback)(const char *str, size_t size, void *userdata);
-static void split_by_delimiter(const char *str, size_t size, char delimiter, split_callback callback, void *userdata) {
- const char *it = str;
- while(it < str + size) {
- const char *prev_it = it;
- it = memchr(it, delimiter, (str + size) - it);
- if(!it)
- it = str + size;
-
- callback(prev_it, it - prev_it, userdata);
- it += 1; // skip delimiter
- }
-}
-
-typedef enum {
- NVCTRL_GPU_NVCLOCK,
- NVCTRL_ATTRIB_GPU_MEM_TRANSFER_RATE,
-} NvCTRLAttributeType;
-
-static unsigned int attribute_type_to_attribute_param(NvCTRLAttributeType attribute_type) {
- switch(attribute_type) {
- case NVCTRL_GPU_NVCLOCK:
- return NV_CTRL_GPU_NVCLOCK_OFFSET;
- case NVCTRL_ATTRIB_GPU_MEM_TRANSFER_RATE:
- return NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET;
- }
- return 0;
-}
-
-static unsigned int attribute_type_to_attribute_param_all_levels(NvCTRLAttributeType attribute_type) {
- switch(attribute_type) {
- case NVCTRL_GPU_NVCLOCK:
- return NV_CTRL_GPU_NVCLOCK_OFFSET_ALL_PERFORMANCE_LEVELS;
- case NVCTRL_ATTRIB_GPU_MEM_TRANSFER_RATE:
- return NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET_ALL_PERFORMANCE_LEVELS;
- }
- return 0;
-}
-
-// Returns 0 on error
-static int xnvctrl_get_attribute_max_value(gsr_xnvctrl *xnvctrl, int num_performance_levels, NvCTRLAttributeType attribute_type) {
- NVCTRLAttributeValidValuesRec valid;
- if(xnvctrl->XNVCTRLQueryValidTargetAttributeValues(xnvctrl->display, NV_CTRL_TARGET_TYPE_GPU, 0, 0, attribute_type_to_attribute_param_all_levels(attribute_type), &valid)) {
- return valid.u.range.max;
- }
-
- if(num_performance_levels > 0 && xnvctrl->XNVCTRLQueryValidTargetAttributeValues(xnvctrl->display, NV_CTRL_TARGET_TYPE_GPU, 0, num_performance_levels - 1, attribute_type_to_attribute_param(attribute_type), &valid)) {
- return valid.u.range.max;
- }
-
- return 0;
-}
-
-static bool xnvctrl_set_attribute_offset(gsr_xnvctrl *xnvctrl, int num_performance_levels, int offset, NvCTRLAttributeType attribute_type) {
- bool success = false;
-
- // NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET_ALL_PERFORMANCE_LEVELS works (or at least used to?) without Xorg running as root
- // so we try that first. NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET_ALL_PERFORMANCE_LEVELS also only works with GTX 1000+.
- // TODO: Reverse engineer NVIDIA Xorg driver so we can set this always without root access.
- if(xnvctrl->XNVCTRLSetTargetAttributeAndGetStatus(xnvctrl->display, NV_CTRL_TARGET_TYPE_GPU, 0, 0, attribute_type_to_attribute_param_all_levels(attribute_type), offset))
- success = true;
-
- for(int i = 0; i < num_performance_levels; ++i) {
- success |= xnvctrl->XNVCTRLSetTargetAttributeAndGetStatus(xnvctrl->display, NV_CTRL_TARGET_TYPE_GPU, 0, i, attribute_type_to_attribute_param(attribute_type), offset);
- }
-
- return success;
-}
-
-static void strip(const char **str, int *size) {
- const char *str_d = *str;
- int s_d = *size;
-
- const char *start = str_d;
- const char *end = start + s_d;
-
- while(str_d < end) {
- char c = *str_d;
- if(c != ' ' && c != '\t' && c != '\n')
- break;
- ++str_d;
- }
-
- int start_offset = str_d - start;
- while(s_d > start_offset) {
- char c = start[s_d];
- if(c != ' ' && c != '\t' && c != '\n')
- break;
- --s_d;
- }
-
- *str = str_d;
- *size = s_d;
-}
-
-static void attribute_callback(const char *str, size_t size, void *userdata) {
- if(size > 255 - 1)
- return;
-
- int size_i = size;
- strip(&str, &size_i);
-
- char attribute[255];
- memcpy(attribute, str, size_i);
- attribute[size_i] = '\0';
-
- const char *sep = strchr(attribute, '=');
- if(!sep)
- return;
-
- const char *attribute_name = attribute;
- size_t attribute_name_len = sep - attribute_name;
- const char *attribute_value_str = sep + 1;
-
- int attribute_value = 0;
- if(sscanf(attribute_value_str, "%d", &attribute_value) != 1)
- return;
-
- NVCTRLPerformanceLevel *performance_level = userdata;
- if(attribute_name_len == 4 && memcmp(attribute_name, "perf", 4) == 0)
- performance_level->perf = attribute_value;
- else if(attribute_name_len == 7 && memcmp(attribute_name, "nvclock", 7) == 0)
- performance_level->nv_clock = attribute_value;
- else if(attribute_name_len == 10 && memcmp(attribute_name, "nvclockmin", 10) == 0)
- performance_level->nv_clock_min = attribute_value;
- else if(attribute_name_len == 10 && memcmp(attribute_name, "nvclockmax", 10) == 0)
- performance_level->nv_clock_max = attribute_value;
- else if(attribute_name_len == 8 && memcmp(attribute_name, "memclock", 8) == 0)
- performance_level->mem_clock = attribute_value;
- else if(attribute_name_len == 11 && memcmp(attribute_name, "memclockmin", 11) == 0)
- performance_level->mem_clock_min = attribute_value;
- else if(attribute_name_len == 11 && memcmp(attribute_name, "memclockmax", 11) == 0)
- performance_level->mem_clock_max = attribute_value;
- else if(attribute_name_len == 15 && memcmp(attribute_name, "memTransferRate", 15) == 0)
- performance_level->mem_transfer_rate = attribute_value;
- else if(attribute_name_len == 18 && memcmp(attribute_name, "memTransferRatemin", 18) == 0)
- performance_level->mem_transfer_rate_min = attribute_value;
- else if(attribute_name_len == 18 && memcmp(attribute_name, "memTransferRatemax", 18) == 0)
- performance_level->mem_transfer_rate_max = attribute_value;
-}
-
-static void attribute_line_callback(const char *str, size_t size, void *userdata) {
- NVCTRLPerformanceLevelQuery *query = userdata;
- if(query->num_performance_levels >= MAX_PERFORMANCE_LEVELS)
- return;
-
- NVCTRLPerformanceLevel *current_performance_level = &query->performance_level[query->num_performance_levels];
- memset(current_performance_level, 0, sizeof(NVCTRLPerformanceLevel));
- ++query->num_performance_levels;
- split_by_delimiter(str, size, ',', attribute_callback, current_performance_level);
-}
-
-static bool xnvctrl_get_performance_levels(gsr_xnvctrl *xnvctrl, NVCTRLPerformanceLevelQuery *query) {
- bool success = false;
- memset(query, 0, sizeof(NVCTRLPerformanceLevelQuery));
-
- char *attributes = NULL;
- if(!xnvctrl->XNVCTRLQueryTargetStringAttribute(xnvctrl->display, NV_CTRL_TARGET_TYPE_GPU, 0, 0, NV_CTRL_STRING_PERFORMANCE_MODES, &attributes)) {
- success = false;
- goto done;
- }
-
- split_by_delimiter(attributes, strlen(attributes), ';', attribute_line_callback, query);
- success = true;
-
- done:
- if(attributes)
- XFree(attributes);
-
- return success;
-}
-
-static int compare_mem_transfer_rate_max_asc(const void *a, const void *b) {
- const NVCTRLPerformanceLevel *perf_a = a;
- const NVCTRLPerformanceLevel *perf_b = b;
- return perf_a->mem_transfer_rate_max - perf_b->mem_transfer_rate_max;
-}
-
-bool gsr_overclock_load(gsr_overclock *self, Display *display) {
- memset(self, 0, sizeof(gsr_overclock));
- self->num_performance_levels = 0;
-
- return gsr_xnvctrl_load(&self->xnvctrl, display);
-}
-
-void gsr_overclock_unload(gsr_overclock *self) {
- gsr_xnvctrl_unload(&self->xnvctrl);
-}
-
-bool gsr_overclock_start(gsr_overclock *self) {
- int basep = 0;
- int errorp = 0;
- if(!self->xnvctrl.XNVCTRLQueryExtension(self->xnvctrl.display, &basep, &errorp)) {
- fprintf(stderr, "gsr warning: gsr_overclock_start: xnvctrl is not supported on your system, failed to overclock memory transfer rate\n");
- return false;
- }
-
- NVCTRLPerformanceLevelQuery query;
- if(!xnvctrl_get_performance_levels(&self->xnvctrl, &query) || query.num_performance_levels == 0) {
- fprintf(stderr, "gsr warning: gsr_overclock_start: failed to get performance levels for overclocking\n");
- return false;
- }
- self->num_performance_levels = query.num_performance_levels;
-
- qsort(query.performance_level, query.num_performance_levels, sizeof(NVCTRLPerformanceLevel), compare_mem_transfer_rate_max_asc);
-
- int target_transfer_rate_offset = xnvctrl_get_attribute_max_value(&self->xnvctrl, query.num_performance_levels, NVCTRL_ATTRIB_GPU_MEM_TRANSFER_RATE);
- if(query.num_performance_levels > 1) {
- const int transfer_rate_max_diff = query.performance_level[query.num_performance_levels - 1].mem_transfer_rate_max - query.performance_level[query.num_performance_levels - 2].mem_transfer_rate_max;
- target_transfer_rate_offset = min_int(target_transfer_rate_offset, transfer_rate_max_diff);
- if(target_transfer_rate_offset >= 0 && xnvctrl_set_attribute_offset(&self->xnvctrl, self->num_performance_levels, target_transfer_rate_offset, NVCTRL_ATTRIB_GPU_MEM_TRANSFER_RATE)) {
- fprintf(stderr, "gsr info: gsr_overclock_start: successfully set memory transfer rate offset to %d\n", target_transfer_rate_offset);
- } else {
- fprintf(stderr, "gsr info: gsr_overclock_start: failed to overclock memory transfer rate offset to %d\n", target_transfer_rate_offset);
- }
- }
-
- // TODO: Sort by nv_clock_max
-
- // TODO: Enable. Crashes on my system (gtx 1080) so it's disabled for now. Seems to crash even if graphics clock is increasd by 1, let alone 1200
- /*
- int target_nv_clock_offset = xnvctrl_get_attribute_max_value(&self->xnvctrl, query.num_performance_levels, NVCTRL_GPU_NVCLOCK);
- if(query.num_performance_levels > 1) {
- const int nv_clock_max_diff = query.performance_level[query.num_performance_levels - 1].nv_clock_max - query.performance_level[query.num_performance_levels - 2].nv_clock_max;
- target_nv_clock_offset = min_int(target_nv_clock_offset, nv_clock_max_diff);
- if(target_nv_clock_offset >= 0 && xnvctrl_set_attribute_offset(&self->xnvctrl, self->num_performance_levels, target_nv_clock_offset, NVCTRL_GPU_NVCLOCK)) {
- fprintf(stderr, "gsr info: gsr_overclock_start: successfully set nv clock offset to %d\n", target_nv_clock_offset);
- } else {
- fprintf(stderr, "gsr info: gsr_overclock_start: failed to overclock nv clock offset to %d\n", target_nv_clock_offset);
- }
- }
- */
-
- XSync(self->xnvctrl.display, False);
- return true;
-}
-
-void gsr_overclock_stop(gsr_overclock *self) {
- xnvctrl_set_attribute_offset(&self->xnvctrl, self->num_performance_levels, 0, NVCTRL_ATTRIB_GPU_MEM_TRANSFER_RATE);
- //xnvctrl_set_attribute_offset(&self->xnvctrl, self->num_performance_levels, 0, NVCTRL_GPU_NVCLOCK);
- XSync(self->xnvctrl.display, False);
-}
diff --git a/src/xnvctrl.c b/src/xnvctrl.c
deleted file mode 100644
index af46493..0000000
--- a/src/xnvctrl.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#include "../include/xnvctrl.h"
-#include "../include/library_loader.h"
-#include <string.h>
-#include <stdio.h>
-#include <dlfcn.h>
-
-bool gsr_xnvctrl_load(gsr_xnvctrl *self, Display *display) {
- memset(self, 0, sizeof(gsr_xnvctrl));
- self->display = display;
-
- dlerror(); /* clear */
- void *lib = dlopen("libXNVCtrl.so.0", RTLD_LAZY);
- if(!lib) {
- fprintf(stderr, "gsr error: gsr_xnvctrl_load failed: failed to load libXNVCtrl.so.0, error: %s\n", dlerror());
- return false;
- }
-
- const dlsym_assign required_dlsym[] = {
- { (void**)&self->XNVCTRLQueryExtension, "XNVCTRLQueryExtension" },
- { (void**)&self->XNVCTRLSetTargetAttributeAndGetStatus, "XNVCTRLSetTargetAttributeAndGetStatus" },
- { (void**)&self->XNVCTRLQueryValidTargetAttributeValues, "XNVCTRLQueryValidTargetAttributeValues" },
- { (void**)&self->XNVCTRLQueryTargetStringAttribute, "XNVCTRLQueryTargetStringAttribute" },
-
- { NULL, NULL }
- };
-
- if(!dlsym_load_list(lib, required_dlsym)) {
- fprintf(stderr, "gsr error: gsr_xnvctrl_load failed: missing required symbols in libXNVCtrl.so.0\n");
- goto fail;
- }
-
- self->library = lib;
- return true;
-
- fail:
- dlclose(lib);
- memset(self, 0, sizeof(gsr_xnvctrl));
- return false;
-}
-
-void gsr_xnvctrl_unload(gsr_xnvctrl *self) {
- if(self->library) {
- dlclose(self->library);
- memset(self, 0, sizeof(gsr_xnvctrl));
- }
-}