Browse Source

Also add nv_perf_level for nvidia (needed as a parameter to nvidia-xsettings)

Marc Di Luzio 6 years ago
parent
commit
142b2fb32d

+ 9 - 0
daemon/daemon_config.c

@@ -81,6 +81,7 @@ struct GameModeConfig {
 	long gpu_device;
 	long nv_core_clock_mhz_offset;
 	long nv_mem_clock_mhz_offset;
+	long nv_perf_level;
 	long amd_core_clock_percentage;
 	long amd_mem_clock_percentage;
 };
@@ -213,6 +214,8 @@ static int inih_handler(void *user, const char *section, const char *name, const
 			valid = get_long_value(name, value, &self->nv_core_clock_mhz_offset);
 		} else if (strcmp(name, "nv_mem_clock_mhz_offset") == 0) {
 			valid = get_long_value(name, value, &self->nv_mem_clock_mhz_offset);
+		} else if (strcmp(name, "nv_perf_level") == 0) {
+			valid = get_long_value(name, value, &self->nv_perf_level);
 		} else if (strcmp(name, "amd_core_clock_percentage") == 0) {
 			valid = get_long_value(name, value, &self->amd_core_clock_percentage);
 		} else if (strcmp(name, "amd_mem_clock_percentage") == 0) {
@@ -284,6 +287,7 @@ static void load_config_files(GameModeConfig *self)
 	self->gpu_device = -1; /* 0 is a valid device ID so use -1 to indicate no value */
 	self->nv_core_clock_mhz_offset = 0;
 	self->nv_mem_clock_mhz_offset = 0;
+	self->nv_perf_level = -1;
 	self->amd_core_clock_percentage = 0;
 	self->amd_mem_clock_percentage = 0;
 
@@ -543,6 +547,11 @@ void config_get_nv_core_clock_mhz_offset(GameModeConfig *self, long *value)
 void config_get_nv_mem_clock_mhz_offset(GameModeConfig *self, long *value)
 {
 	memcpy_locked_config(self, value, &self->nv_mem_clock_mhz_offset, sizeof(long));
+
+}
+void config_get_nv_perf_level(GameModeConfig *self, long *value)
+{
+	memcpy_locked_config(self, value, &self->nv_perf_level, sizeof(long));
 }
 
 void config_get_amd_core_clock_percentage(GameModeConfig *self, long *value)

+ 1 - 0
daemon/daemon_config.h

@@ -138,5 +138,6 @@ void config_get_gpu_vendor(GameModeConfig *self, long *value);
 void config_get_gpu_device(GameModeConfig *self, long *value);
 void config_get_nv_core_clock_mhz_offset(GameModeConfig *self, long *value);
 void config_get_nv_mem_clock_mhz_offset(GameModeConfig *self, long *value);
+void config_get_nv_perf_level(GameModeConfig *self, long *value);
 void config_get_amd_core_clock_percentage(GameModeConfig *self, long *value);
 void config_get_amd_mem_clock_percentage(GameModeConfig *self, long *value);

+ 13 - 1
daemon/gamemode-gpu.c

@@ -111,7 +111,7 @@ int game_mode_initialise_gpu(GameModeConfig *config, GameModeGPUInfo **info)
 		const int nv_mem_hard_limit = 2000;
 		if (new_info->core > nv_core_hard_limit || new_info->mem > nv_mem_hard_limit) {
 			LOG_ERROR(
-			    "ERROR NVIDIA Overclock value above safety levels of +%d (core) +%d (mem), will "
+			    "ERROR: NVIDIA Overclock value above safety levels of +%d (core) +%d (mem), will "
 			    "not overclock!\n",
 			    nv_core_hard_limit,
 			    nv_mem_hard_limit);
@@ -122,6 +122,15 @@ int game_mode_initialise_gpu(GameModeConfig *config, GameModeGPUInfo **info)
 			return -1;
 		}
 
+		/* Sanity check the performance level value as well */
+		config_get_nv_perf_level(config, &new_info->nv_perf_level);
+		if(new_info->nv_perf_level < 0 || new_info->nv_perf_level > 16)
+		{
+			LOG_ERROR( "ERROR: NVIDIA Performance level value invalid (%ld), will not apply optimisations!\n", new_info->nv_perf_level );
+			free(new_info);
+			return -1;
+		}
+
 		break;
 	case Vendor_AMD:
 		config_get_amd_core_clock_percentage(config, &new_info->core);
@@ -186,6 +195,8 @@ int game_mode_apply_gpu(const GameModeGPUInfo *info, bool apply)
 	snprintf(core, 8, "%ld", info->core);
 	char mem[8];
 	snprintf(mem, 8, "%ld", info->mem);
+	char nv_perf_level[4];
+	snprintf(nv_perf_level, 4, "%ld", info->nv_perf_level);
 
 	// TODO: Actually pass right arguments
 	const char *const exec_args[] = {
@@ -196,6 +207,7 @@ int game_mode_apply_gpu(const GameModeGPUInfo *info, bool apply)
 		"set",
 		apply ? core : "0", /* For now simply reset to zero */
 		apply ? mem : "0",  /* could in the future store default values for reset */
+		info->vendor == Vendor_NVIDIA ? nv_perf_level : NULL, /* Only use this if Nvidia */
 		NULL,
 	};
 

+ 2 - 2
daemon/gpu-control.c

@@ -35,11 +35,11 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "logging.h"
 
 // TODO
-// Gather GPU type and information automatically
 // Apply Nvidia GPU settings (CoolBits will be needed)
 // Apply AMD GPU settings (Will need user changing pwm1_enable)
-// Intel?
 // Provide documentation on optimisations
+// Intel?
+// Gather GPU type and information automatically if possible
 
 // NVIDIA
 // Running these commands:

+ 2 - 0
daemon/gpu-control.h

@@ -49,6 +49,8 @@ struct GameModeGPUInfo {
 
 	long core; /* Core clock to apply */
 	long mem;  /* Mem clock to apply */
+
+	long nv_perf_level; /* The Nvidia Performance Level to adjust */
 };
 
 /**

+ 12 - 6
daemon/gpuclockctl.c

@@ -36,7 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "gpu-control.h"
 
 /* Helper to quit with usage */
-static const char *usage_text = "usage: gpuclockctl PCI_ID DEVICE [get] [set CORE MEM]";
+static const char *usage_text = "usage: gpuclockctl PCI_ID DEVICE [get] [set CORE MEM [PERF_LEVEL]]]";
 static void print_usage_and_exit(void)
 {
 	fprintf(stderr, "%s\n", usage_text);
@@ -68,12 +68,12 @@ static long get_device(const char *val)
 }
 
 /* Helper to get and verify core and mem value */
-static long get_coremem(const char *val)
+static long get_generic_value(const char *val)
 {
 	char *end;
 	long ret = strtol(val, &end, 10);
 	if (ret < 0 || end == val) {
-		LOG_ERROR("ERROR: Invalid core or mem value passed (%ld)!\n", ret);
+		LOG_ERROR("ERROR: Invalid value passed (%ld)!\n", ret);
 		print_usage_and_exit();
 	}
 	return ret;
@@ -95,7 +95,7 @@ int main(int argc, char *argv[])
 		get_gpu_state(&info);
 		printf("%ld %ld\n", info.core, info.mem);
 
-	} else if (argc == 6 && strncmp(argv[3], "set", 3) == 0) {
+	} else if (argc >=6 && argc <=7 && strncmp(argv[3], "set", 3) == 0) {
 		/* Must be root to set the state */
 		if (geteuid() != 0) {
 			fprintf(stderr, "gpuclockctl must be run as root to set values\n");
@@ -107,8 +107,11 @@ int main(int argc, char *argv[])
 		memset(&info, 0, sizeof(info));
 		info.vendor = get_vendor(argv[1]);
 		info.device = get_device(argv[2]);
-		info.core = get_coremem(argv[4]);
-		info.mem = get_coremem(argv[5]);
+		info.core = get_generic_value(argv[4]);
+		info.mem = get_generic_value(argv[5]);
+
+		if( info.vendor == Vendor_NVIDIA )
+			info.nv_perf_level = get_generic_value(argv[6]);
 
 		printf("gpuclockctl setting core:%ld mem:%ld on device:%ld with vendor 0x%04x\n",
 		       info.core,
@@ -116,6 +119,9 @@ int main(int argc, char *argv[])
 		       info.device,
 		       (unsigned short)info.vendor);
 
+		if( info.vendor == Vendor_NVIDIA )
+			printf("on Performance Level %ld\n", info.nv_perf_level);
+
 		return set_gpu_state(&info);
 	} else {
 		print_usage_and_exit();

+ 2 - 0
example/gamemode.ini

@@ -52,6 +52,8 @@ inhibit_screensaver=1
 ; Requires the coolbits extension activated in nvidia-xconfig
 ;nv_core_clock_mhz_offset=0
 ;nv_mem_clock_mhz_offset=0
+; This corresponds to the performance level to edit in nvidia-xconfig
+;nv_perf_level=1
 
 ; AMD specific settings (these are percentages applied on top of the baseline, ie. 0 applies no change)
 ; Requires the the AMDGPU kernel module