From a8b734c8779be6affa9a341cbee58670a3dbcef9 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 20 May 2024 16:45:23 +0800 Subject: [PATCH] GPU: change option `--gpu-force-vulkan` to `--gpu-detection-method` --- completions/bash | 2 +- doc/json_schema.json | 14 +++++++--- src/data/help.json | 15 +++++++---- src/detection/gpu/gpu.c | 50 ++++++++++++++++++----------------- src/detection/gpu/gpu_linux.c | 18 +++++++------ src/fastfetch.c | 3 +++ src/modules/gpu/gpu.c | 47 +++++++++++++++++++++++++++----- src/modules/gpu/option.h | 11 +++++++- 8 files changed, 110 insertions(+), 50 deletions(-) diff --git a/completions/bash b/completions/bash index d3d6964c7..9ae14e00d 100644 --- a/completions/bash +++ b/completions/bash @@ -197,7 +197,7 @@ __fastfetch_completion() "--disk-show-subvolumes" "--gpu-hide-integrated" "--gpu-hide-discrete" - "--gpu-force-vulkan" + "--gpu-force-method" "--disk-show-unknown" "--bluetooth-show-disconnected" ) diff --git a/doc/json_schema.json b/doc/json_schema.json index 91ae40437..51b3301d8 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -1455,10 +1455,16 @@ "type": "boolean", "default": false }, - "forceVulkan": { - "description": "Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`", - "type": "boolean", - "default": false + "detectionMethod": { + "description": "Force using a specified method to detect GPUs", + "type": "string", + "enum": [ + "auto", + "pci", + "vulkan", + "opengl" + ], + "default": "auto" }, "hideType": { "description": "Specify the type of GPUs should not be printed", diff --git a/src/data/help.json b/src/data/help.json index 7e3631e35..3baa6b00a 100644 --- a/src/data/help.json +++ b/src/data/help.json @@ -1197,13 +1197,18 @@ } }, { - "long": "gpu-force-vulkan", - "desc": "Force using vulkan to detect GPUs", - "remark": "Vulkan supports video memory usage detection", + "long": "gpu-detection-method", + "desc": "Force using a specified method to detect GPUs", "arg": { - "type": "bool", + "type": "enum", "optional": true, - "default": false + "enum": { + "auto": "DRM (Linux only) -> PCI (Linux, FreeBSD and other platform specific methods) -> Vulkan -> OpenGL", + "pci": "PCI -> Vulkan -> OpenGL", + "vulkan": "Vulkan -> OpenGL", + "opengl": "OpenGL" + }, + "default": "auto" } }, { diff --git a/src/detection/gpu/gpu.c b/src/detection/gpu/gpu.c index 4f70d3452..b75ac7679 100644 --- a/src/detection/gpu/gpu.c +++ b/src/detection/gpu/gpu.c @@ -46,9 +46,9 @@ const char* detectByOpenGL(FFlist* gpus) { FFGPUResult* gpu = (FFGPUResult*) ffListAdd(gpus); gpu->type = FF_GPU_TYPE_UNKNOWN; - ffStrbufInitMove(&gpu->vendor, &result.vendor); + ffStrbufInit(&gpu->vendor); ffStrbufInitMove(&gpu->name, &result.renderer); - ffStrbufInit(&gpu->driver); + ffStrbufInitMove(&gpu->driver, &result.vendor); ffStrbufInitF(&gpu->platformApi, "OpenGL %s", result.version.chars); gpu->temperature = FF_GPU_TEMP_UNSET; gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; @@ -56,22 +56,18 @@ const char* detectByOpenGL(FFlist* gpus) gpu->dedicated = gpu->shared = (FFGPUMemory){0, 0}; gpu->deviceId = 0; - if (ffStrbufIgnCaseEqualS(&gpu->vendor, "Mesa")) - ffStrbufClear(&gpu->vendor); - - if (!gpu->vendor.length) + if (ffStrbufContainS(&gpu->name, "Apple")) { - if (ffStrbufContainS(&gpu->name, "Apple")) - ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE); - else if (ffStrbufContainS(&gpu->name, "Intel")) - ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL); - else if (ffStrbufContainS(&gpu->name, "AMD") || ffStrbufContainS(&gpu->name, "ATI")) - ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD); - else if (ffStrbufContainS(&gpu->name, "NVIDIA")) - ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA); - } - if (ffStrbufEqualS(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE)) + ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE); gpu->type = FF_GPU_TYPE_INTEGRATED; + } + else if (ffStrbufContainS(&gpu->name, "Intel")) + ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL); + else if (ffStrbufContainS(&gpu->name, "AMD") || ffStrbufContainS(&gpu->name, "ATI")) + ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD); + else if (ffStrbufContainS(&gpu->name, "NVIDIA")) + ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA); + } ffStrbufDestroy(&result.version); @@ -83,20 +79,26 @@ const char* detectByOpenGL(FFlist* gpus) const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result) { - if (!options->forceVulkan) + if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_PCI) { const char* error = ffDetectGPUImpl(options, result); if (!error && result->length > 0) return NULL; } - FFVulkanResult* vulkan = ffDetectVulkan(); - if (!vulkan->error && vulkan->gpus.length > 0) + if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_VULKAN) { - ffListDestroy(result); - ffListInitMove(result, &vulkan->gpus); - return NULL; + FFVulkanResult* vulkan = ffDetectVulkan(); + if (!vulkan->error && vulkan->gpus.length > 0) + { + ffListDestroy(result); + ffListInitMove(result, &vulkan->gpus); + return NULL; + } + } + if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_OPENGL) + { + if (detectByOpenGL(result) == NULL) + return NULL; } - if (detectByOpenGL(result) == NULL) - return NULL; return "GPU detection failed"; } diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index bc58f6c34..9372882b3 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -460,14 +460,16 @@ static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus) const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) { - #ifdef FF_HAVE_DIRECTX_HEADERS - const char* ffGPUDetectByDirectX(const FFGPUOptions* options, FFlist* gpus); - if (ffGPUDetectByDirectX(options, gpus) == NULL) + if (options->detectionMethod == FF_GPU_DETECTION_METHOD_AUTO) + { + #ifdef FF_HAVE_DIRECTX_HEADERS + const char* ffGPUDetectByDirectX(const FFGPUOptions* options, FFlist* gpus); + if (ffGPUDetectByDirectX(options, gpus) == NULL) + return NULL; + #endif + + if (drmDetectGPUs(options, gpus) == NULL && gpus->length > 0) return NULL; - #endif - - if (drmDetectGPUs(options, gpus) == NULL && gpus->length > 0) - return NULL; - + } return pciDetectGPUs(options, gpus); } diff --git a/src/fastfetch.c b/src/fastfetch.c index 722c61462..cfe2d6185 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -234,10 +234,13 @@ static bool printSpecificCommandHelp(const char* command) } } + yyjson_doc_free(doc); return true; } } } + + yyjson_doc_free(doc); return false; } diff --git a/src/modules/gpu/gpu.c b/src/modules/gpu/gpu.c index 3cb55a04c..5a9f4b4f3 100644 --- a/src/modules/gpu/gpu.c +++ b/src/modules/gpu/gpu.c @@ -144,9 +144,15 @@ bool ffParseGPUCommandOptions(FFGPUOptions* options, const char* key, const char return true; } - if (ffStrEqualsIgnCase(subKey, "force-vulkan")) + if (ffStrEqualsIgnCase(subKey, "detection-method")) { - options->forceVulkan = ffOptionParseBoolean(value); + options->detectionMethod = ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "auto", FF_GPU_DETECTION_METHOD_AUTO }, + { "pci", FF_GPU_DETECTION_METHOD_PCI }, + { "vulkan", FF_GPU_DETECTION_METHOD_VULKAN }, + { "opengl", FF_GPU_DETECTION_METHOD_OPENGL }, + {}, + }); return true; } @@ -191,9 +197,20 @@ void ffParseGPUJsonObject(FFGPUOptions* options, yyjson_val* module) continue; } - if (ffStrEqualsIgnCase(key, "forceVulkan")) + if (ffStrEqualsIgnCase(key, "detectionMethod")) { - options->forceVulkan = yyjson_get_bool(val); + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "auto", FF_GPU_DETECTION_METHOD_AUTO }, + { "pci", FF_GPU_DETECTION_METHOD_PCI }, + { "vulkan", FF_GPU_DETECTION_METHOD_VULKAN }, + { "opengl", FF_GPU_DETECTION_METHOD_OPENGL }, + {}, + }); + if (error) + ffPrintError(FF_GPU_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Invalid %s value: %s", key, error); + else + options->detectionMethod = (FFGPUDetectionMethod) value; continue; } @@ -230,8 +247,24 @@ void ffGenerateGPUJsonConfig(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_ if (options->driverSpecific != defaultOptions.driverSpecific) yyjson_mut_obj_add_bool(doc, module, "driverSpecific", options->driverSpecific); - if (options->forceVulkan != defaultOptions.forceVulkan) - yyjson_mut_obj_add_bool(doc, module, "forceVulkan", options->forceVulkan); + if (options->detectionMethod != defaultOptions.detectionMethod) + { + switch (options->detectionMethod) + { + case FF_GPU_DETECTION_METHOD_AUTO: + yyjson_mut_obj_add_str(doc, module, "detectionMethod", "auto"); + break; + case FF_GPU_DETECTION_METHOD_PCI: + yyjson_mut_obj_add_str(doc, module, "detectionMethod", "pci"); + break; + case FF_GPU_DETECTION_METHOD_VULKAN: + yyjson_mut_obj_add_str(doc, module, "detectionMethod", "vulkan"); + break; + case FF_GPU_DETECTION_METHOD_OPENGL: + yyjson_mut_obj_add_str(doc, module, "detectionMethod", "opengl"); + break; + } + } ffTempsGenerateJsonConfig(doc, module, defaultOptions.temp, defaultOptions.tempConfig, options->temp, options->tempConfig); @@ -366,7 +399,7 @@ void ffInitGPUOptions(FFGPUOptions* options) ffOptionInitModuleArg(&options->moduleArgs); options->driverSpecific = false; - options->forceVulkan = false; + options->detectionMethod = FF_GPU_DETECTION_METHOD_AUTO; options->temp = false; options->hideType = FF_GPU_TYPE_UNKNOWN; options->tempConfig = (FFColorRangeConfig) { 60, 80 }; diff --git a/src/modules/gpu/option.h b/src/modules/gpu/option.h index a68b8ad3a..405b7b11e 100644 --- a/src/modules/gpu/option.h +++ b/src/modules/gpu/option.h @@ -12,15 +12,24 @@ typedef enum FFGPUType FF_GPU_TYPE_DISCRETE, } FFGPUType; +typedef enum FFGPUDetectionMethod +{ + FF_GPU_DETECTION_METHOD_AUTO, + FF_GPU_DETECTION_METHOD_PCI, + FF_GPU_DETECTION_METHOD_VULKAN, + FF_GPU_DETECTION_METHOD_OPENGL, +} FFGPUDetectionMethod; + typedef struct FFGPUOptions { FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; FFGPUType hideType; + FFGPUDetectionMethod detectionMethod; bool temp; bool driverSpecific; - bool forceVulkan; + bool forceMethod; FFColorRangeConfig tempConfig; FFColorRangeConfig percent; } FFGPUOptions;