Skip to content

Commit

Permalink
GPU (Linux): refactor code to support non-apple SOCs
Browse files Browse the repository at this point in the history
  • Loading branch information
CarterLi committed Sep 24, 2024
1 parent 5dbd6b9 commit 2b82449
Showing 1 changed file with 50 additions and 26 deletions.
76 changes: 50 additions & 26 deletions src/detection/gpu/gpu_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
uint32_t vendorId, deviceId, subVendorId, subDeviceId;
uint8_t classId, subclassId;
if (sscanf(buffer->chars + strlen("pci:"), "v%8" SCNx32 "d%8" SCNx32 "sv%8" SCNx32 "sd%8" SCNx32 "bc%2" SCNx8 "sc%2" SCNx8, &vendorId, &deviceId, &subVendorId, &subDeviceId, &classId, &subclassId) != 6)
return "Invalid modalias string";
return "Failed to parse pci modalias";

if (classId != 0x03 /*PCI_BASE_CLASS_DISPLAY*/)
return "Not a GPU device";
Expand Down Expand Up @@ -398,25 +398,11 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf

#if __aarch64__

FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, const char* drmKey)
FF_MAYBE_UNUSED static const char* drmDetectAsahiSpecific(FFGPUResult* gpu, const char* name, FFstrbuf* buffer, const char* drmKey)
{
uint32_t index = ffStrbufFirstIndexS(buffer, "apple,agx-t");
if (index == buffer->length) return "display-subsystem?";
index += (uint32_t) strlen("apple,agx-t");

FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->deviceId = strtoul(buffer->chars + index, NULL, 10);
ffStrbufInitStatic(&gpu->name, ffCPUAppleCodeToName((uint32_t) gpu->deviceId));
ffStrbufInitStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
ffStrbufInit(&gpu->driver);
ffStrbufInitF(&gpu->platformApi, "DRM (%s)", drmKey);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->type = FF_GPU_TYPE_INTEGRATED;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
if (sscanf(name, "agx-t%lu", &gpu->deviceId) == 1)
ffStrbufSetStatic(&gpu->name, ffCPUAppleCodeToName((uint32_t) gpu->deviceId));
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);

#if FF_HAVE_DRM
ffStrbufSetS(buffer, "/dev/dri/");
Expand All @@ -431,7 +417,7 @@ FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, F
.size = sizeof(paramsGlobal),
}) >= 0)
{
ffStrbufSetF(&gpu->driver, "asahi %u", paramsGlobal.unstable_uabi_version);
ffStrbufAppendF(&gpu->driver, " %u", paramsGlobal.unstable_uabi_version);

// FIXME: They will introduce ABI breaking changes. Always check the latest version
// https://www.reddit.com/r/AsahiLinux/comments/1ei2qiv/comment/lgm0v5s/
Expand Down Expand Up @@ -466,18 +452,56 @@ FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, F
}
}
}
#endif

return NULL;
}
#endif

static const char* detectOf(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, const char* drmKey)
{
char compatible[256]; // vendor,model-name
if (sscanf(buffer->chars + strlen("of:"), "NgpuT%*[^C]C%256[^C]", compatible) != 1)
return "Failed to parse of modalias or not a GPU device";

if (!gpu->driver.length)
char* name = strchr(compatible, ',');
if (name)
{
pciDetectDriver(&gpu->driver, drmDir, buffer, drmKey);
if (!gpu->name.length)
ffStrbufSetF(&gpu->name, "Apple Silicon T%u", (uint32_t) gpu->deviceId);
*name = '\0';
++name;
}

FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->deviceId = 0;
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->vendor);
ffStrbufInit(&gpu->driver);
ffStrbufInitF(&gpu->platformApi, "DRM (%s)", drmKey);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->type = FF_GPU_TYPE_INTEGRATED;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;

pciDetectDriver(&gpu->driver, drmDir, buffer, drmKey);

#ifdef __aarch64__
if (ffStrbufEqualS(&gpu->driver, "asahi"))
drmDetectAsahiSpecific(gpu, name, buffer, drmKey);
#endif

if (!gpu->name.length)
ffStrbufSetS(&gpu->name, name ? name : compatible);
if (!gpu->vendor.length && name)
{
compatible[0] = (char) toupper(compatible[0]);
ffStrbufSetS(&gpu->vendor, compatible);
}

return NULL;
}
#endif

static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
{
Expand Down Expand Up @@ -509,7 +533,7 @@ static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
detectPci(options, gpus, &buffer, &drmDir, entry->d_name);
#ifdef __aarch64__
else if (ffStrbufStartsWithS(&buffer, "of:"))
detectAsahi(gpus, &buffer, &drmDir, entry->d_name);
detectOf(gpus, &buffer, &drmDir, entry->d_name);
#endif

ffStrbufSubstrBefore(&drmDir, drmDirLength);
Expand Down

0 comments on commit 2b82449

Please sign in to comment.