From b8d0b1ceb59a567c2b2e37582e6c266d96f539a1 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 12 Jan 2023 13:34:39 +0100 Subject: [PATCH] loader: extend DRI_PRIME to support =N DRI_PRIME=1 isn't useful on machines with more than 2 GPUs. This commit adds support to DRI_PRIME=N syntax meaning: select the Nth GPU (not counting the default GPU). So on a 3 GPUs system where drmGetDevices2 returns the following: /dev/dri/renderD130 [default] /dev/dri/renderD129 /dev/dri/renderD128 DRI_PRIME=1 would select D129 (as is already the case without this commit), DRI_PRIME=2 would select D128. Reviewed-by: Adam Jackson Part-of: --- src/loader/loader.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/loader/loader.c b/src/loader/loader.c index dce7030..6b4fc9f 100644 --- a/src/loader/loader.c +++ b/src/loader/loader.c @@ -328,11 +328,12 @@ bool loader_get_user_preferred_fd(int *fd_render_gpu, int *original_fd) int i, num_devices, fd = -1; struct { enum { - PRIME_IS_ONE, + PRIME_IS_INTEGER, PRIME_IS_VID_DID, PRIME_IS_PCI_TAG } semantics; union { + int as_integer; struct { uint16_t v, d; } as_vendor_device_ids; @@ -357,10 +358,15 @@ bool loader_get_user_preferred_fd(int *fd_render_gpu, int *original_fd) prime.v.as_vendor_device_ids.v = vendor_id; prime.v.as_vendor_device_ids.d = device_id; } else { - if (strcmp(prime.str, "1") == 0) { - prime.semantics = PRIME_IS_ONE; - } else { + int i = atoi(prime.str); + if (i < 0 || strcmp(prime.str, "0") == 0) { + printf("Invalid value (%d) for DRI_PRIME. Should be > 0\n", i); + goto err; + } else if (i == 0) { prime.semantics = PRIME_IS_PCI_TAG; + } else { + prime.semantics = PRIME_IS_INTEGER; + prime.v.as_integer = i; } } } @@ -373,6 +379,14 @@ bool loader_get_user_preferred_fd(int *fd_render_gpu, int *original_fd) if (num_devices <= 0) goto err; + if (prime.semantics == PRIME_IS_INTEGER && + prime.v.as_integer >= num_devices) { + printf("Inconsistent value (%d) for DRI_PRIME. Should be < %d " + "(GPU devices count). Using: %d\n", + prime.v.as_integer, num_devices, num_devices - 1); + prime.v.as_integer = num_devices - 1; + } + for (i = 0; i < num_devices; i++) { if (!(devices[i]->available_nodes & 1 << DRM_NODE_RENDER)) continue; @@ -385,10 +399,15 @@ bool loader_get_user_preferred_fd(int *fd_render_gpu, int *original_fd) * vendor_id:device_id */ switch (prime.semantics) { - case PRIME_IS_ONE: { + case PRIME_IS_INTEGER: { /* Skip the default device */ if (drm_device_matches_tag(devices[i], default_tag)) continue; + prime.v.as_integer--; + + /* Skip more GPUs? */ + if (prime.v.as_integer) + continue; break; } @@ -405,9 +424,9 @@ bool loader_get_user_preferred_fd(int *fd_render_gpu, int *original_fd) continue; } case PRIME_IS_PCI_TAG: { - if (!drm_device_matches_tag(devices[i], prime.str)) { + if (!drm_device_matches_tag(devices[i], prime.str)) continue; - } + break; } } -- 2.7.4