Browse Source

Merge pull request #105 from mdiluz/auto-detect-vendor

Detect the GPU vendor automatically
Alex Smith 6 years ago
parent
commit
3c28e84700
5 changed files with 49 additions and 53 deletions
  1. 2 5
      daemon/daemon_config.c
  2. 0 1
      daemon/daemon_config.h
  3. 22 6
      daemon/gamemode-gpu.c
  4. 24 38
      daemon/gamemode-tests.c
  5. 1 3
      example/gamemode.ini

+ 2 - 5
daemon/daemon_config.c

@@ -87,7 +87,6 @@ struct GameModeConfig {
 		long reaper_frequency;
 
 		char apply_gpu_optimisations[CONFIG_VALUE_MAX];
-		long gpu_vendor;
 		long gpu_device;
 		long nv_core_clock_mhz_offset;
 		long nv_mem_clock_mhz_offset;
@@ -157,7 +156,8 @@ static bool get_long_value(const char *value_name, const char *value, long *outp
 /*
  * Get a long value from a hex string
  */
-static bool get_long_value_hex(const char *value_name, const char *value, long *output)
+__attribute__((unused)) static bool get_long_value_hex(const char *value_name, const char *value,
+                                                       long *output)
 {
 	char *end = NULL;
 	long config_value = strtol(value, &end, 16);
@@ -250,8 +250,6 @@ static int inih_handler(void *user, const char *section, const char *name, const
 		/* GPU subsection */
 		if (strcmp(name, "apply_gpu_optimisations") == 0) {
 			valid = get_string_value(value, self->values.apply_gpu_optimisations);
-		} else if (strcmp(name, "gpu_vendor") == 0) {
-			valid = get_long_value_hex(name, value, &self->values.gpu_vendor);
 		} else if (strcmp(name, "gpu_device") == 0) {
 			valid = get_long_value(name, value, &self->values.gpu_device);
 		} else if (strcmp(name, "nv_core_clock_mhz_offset") == 0) {
@@ -574,7 +572,6 @@ void config_get_apply_gpu_optimisations(GameModeConfig *self, char value[CONFIG_
 }
 
 /* Define the getters for GPU values */
-DEFINE_CONFIG_GET(gpu_vendor)
 DEFINE_CONFIG_GET(gpu_device)
 DEFINE_CONFIG_GET(nv_core_clock_mhz_offset)
 DEFINE_CONFIG_GET(nv_mem_clock_mhz_offset)

+ 0 - 1
daemon/daemon_config.h

@@ -134,7 +134,6 @@ long config_get_ioprio_value(GameModeConfig *self);
  * Get various config info for gpu optimisations
  */
 void config_get_apply_gpu_optimisations(GameModeConfig *self, char value[CONFIG_VALUE_MAX]);
-long config_get_gpu_vendor(GameModeConfig *self);
 long config_get_gpu_device(GameModeConfig *self);
 long config_get_nv_core_clock_mhz_offset(GameModeConfig *self);
 long config_get_nv_mem_clock_mhz_offset(GameModeConfig *self);

+ 22 - 6
daemon/gamemode-gpu.c

@@ -71,7 +71,6 @@ int game_mode_initialise_gpu(GameModeConfig *config, GameModeGPUInfo **info)
 	memset(new_info, 0, sizeof(GameModeGPUInfo));
 
 	/* Get the config parameters */
-	new_info->vendor = config_get_gpu_vendor(config);
 	new_info->device = config_get_gpu_device(config);
 
 	/* verify device ID */
@@ -83,13 +82,30 @@ int game_mode_initialise_gpu(GameModeConfig *config, GameModeGPUInfo **info)
 		return -1;
 	}
 
+	/* Fill in GPU vendor */
+	char path[64] = { 0 };
+	if (snprintf(path, 64, "/sys/class/drm/card%ld/device/vendor", new_info->device) < 0) {
+		LOG_ERROR("snprintf failed, will not apply gpu optimisations!\n");
+		return -1;
+	}
+	FILE *vendor = fopen(path, "r");
+	if (!vendor) {
+		LOG_ERROR("Couldn't open vendor file at %s, will not apply gpu optimisations!\n", path);
+		return -1;
+	}
+	char buff[64];
+	if (fgets(buff, 64, vendor) != NULL) {
+		new_info->vendor = strtol(buff, NULL, 0);
+	} else {
+		LOG_ERROR("Coudn't read contents of file %s, will not apply optimisations!\n", path);
+		return -1;
+	}
+
 	/* verify GPU vendor */
 	if (!GPUVendorValid(new_info->vendor)) {
-		LOG_ERROR(
-		    "Invalid gpu_vendor value (0x%04x) set in configuration, will not apply "
-		    "optimisations!\n",
-		    (unsigned int)new_info->vendor);
-		LOG_ERROR("Possible values are: 0x%04x (NVIDIA) 0x%04x (AMD) 0x%04x (Intel)\n",
+		LOG_ERROR("Unknown vendor value (0x%04x) found, cannot apply optimisations!\n",
+		          (unsigned int)new_info->vendor);
+		LOG_ERROR("Known values are: 0x%04x (NVIDIA) 0x%04x (AMD) 0x%04x (Intel)\n",
 		          Vendor_NVIDIA,
 		          Vendor_AMD,
 		          Vendor_Intel);

+ 24 - 38
daemon/gamemode-tests.c

@@ -413,82 +413,68 @@ int run_gpu_optimisation_tests(struct GameModeConfig *config)
 	}
 
 	/* Get current GPU values */
-	GameModeGPUInfo gpuinfo;
-	gpuinfo.device = config_get_gpu_device(config);
-	gpuinfo.vendor = config_get_gpu_vendor(config);
+	GameModeGPUInfo *gpuinfo;
+	game_mode_initialise_gpu(config, &gpuinfo);
 
-	if (gpuinfo.vendor == Vendor_NVIDIA)
-		gpuinfo.nv_perf_level = config_get_nv_perf_level(config);
-
-	if (game_mode_get_gpu(&gpuinfo) != 0) {
-		LOG_ERROR("Could not get current GPU info, see above!\n");
+	if (!gpuinfo) {
+		LOG_ERROR("Failed to initialise gpuinfo!\n");
 		return -1;
 	}
 
-	/* Store the original values */
-	long original_core = gpuinfo.core;
-	long original_mem = gpuinfo.mem;
-
 	/* Grab the expected values */
-	long expected_core = 0;
-	long expected_mem = 0;
-	switch (gpuinfo.vendor) {
-	case Vendor_NVIDIA:
-		expected_core = config_get_nv_core_clock_mhz_offset(config);
-		expected_mem = config_get_nv_mem_clock_mhz_offset(config);
-		break;
-	case Vendor_AMD:
-		expected_core = config_get_amd_core_clock_percentage(config);
-		expected_mem = config_get_amd_mem_clock_percentage(config);
-		break;
-	default:
-		LOG_ERROR("Configured for unsupported GPU vendor 0x%04x!\n", (unsigned int)gpuinfo.vendor);
-		return -1;
-	}
+	long expected_core = gpuinfo->core;
+	long expected_mem = gpuinfo->mem;
+
+	/* Get current stats */
+	game_mode_get_gpu(gpuinfo);
+	long original_core = gpuinfo->core;
+	long original_mem = gpuinfo->mem;
 
 	LOG_MSG("Configured with vendor:0x%04x device:%ld core:%ld mem:%ld (nv_perf_level:%ld)\n",
-	        (unsigned int)gpuinfo.vendor,
-	        gpuinfo.device,
+	        (unsigned int)gpuinfo->vendor,
+	        gpuinfo->device,
 	        expected_core,
 	        expected_mem,
-	        gpuinfo.nv_perf_level);
+	        gpuinfo->nv_perf_level);
 
 	/* Start gamemode and check the new values */
 	gamemode_request_start();
 
-	if (game_mode_get_gpu(&gpuinfo) != 0) {
+	if (game_mode_get_gpu(gpuinfo) != 0) {
 		LOG_ERROR("Could not get current GPU info, see above!\n");
 		gamemode_request_end();
+		game_mode_free_gpu(&gpuinfo);
 		return -1;
 	}
 
-	if (gpuinfo.core != expected_core || gpuinfo.mem != expected_mem) {
+	if (gpuinfo->core != expected_core || gpuinfo->mem != expected_mem) {
 		LOG_ERROR(
 		    "Current GPU clocks during gamemode do not match requested values!\n"
 		    "\tcore - expected:%ld was:%ld | mem - expected:%ld was:%ld\n",
 		    expected_core,
-		    gpuinfo.core,
+		    gpuinfo->core,
 		    expected_mem,
-		    gpuinfo.mem);
+		    gpuinfo->mem);
 		gpustatus = -1;
 	}
 
 	/* End gamemode and check the values have returned */
 	gamemode_request_end();
 
-	if (game_mode_get_gpu(&gpuinfo) != 0) {
+	if (game_mode_get_gpu(gpuinfo) != 0) {
 		LOG_ERROR("Could not get current GPU info, see above!\n");
+		game_mode_free_gpu(&gpuinfo);
 		return -1;
 	}
 
-	if (gpuinfo.core != original_core || gpuinfo.mem != original_mem) {
+	if (gpuinfo->core != original_core || gpuinfo->mem != original_mem) {
 		LOG_ERROR(
 		    "Current GPU clocks after gamemode do not matcch original values!\n"
 		    "\tcore - original:%ld was:%ld | mem - original:%ld was:%ld\n",
 		    original_core,
-		    gpuinfo.core,
+		    gpuinfo->core,
 		    original_mem,
-		    gpuinfo.mem);
+		    gpuinfo->mem);
 		gpustatus = -1;
 	}
 

+ 1 - 3
example/gamemode.ini

@@ -43,9 +43,7 @@ inhibit_screensaver=1
 ; Setting this to the keyphrase "accept-responsibility" will allow gamemode to apply GPU optimisations such as overclocks
 ;apply_gpu_optimisations=0
 
-; You must set these to tell gamemode the Vendor of your graphics card, as well it's device number on the system (usually 0)
-; Vendor must be one of 0x10de (NVIDIA), 0x1002 (AMD) or 0x8086 (Intel)
-;gpu_vendor=0x0000
+; The DRM device number on the system (usually 0), ie. the number in /sys/class/drm/card0/
 ;gpu_device=0
 
 ; Nvidia specific settings (these are Mhz offsets from the baseline, ie. 0 applies no change)