iinsertNameHere / catnap

A highly customizable systemfetch written in nim
https://catnap-fetch.xyz
MIT License
113 stars 9 forks source link

[Question]: How should we go about detecting integrated and dedicated GPU? #121

Open Opposite34 opened 1 month ago

Opposite34 commented 1 month ago

Ask your Question:

According to how PR #90 works, it selects the first item in the list from and output that's similar to lspci | grep VGA:

for line in lspci.split('\n'):
        if line.split(' ')[1] == "VGA":
            vga = line
            break

However, as also highlight in the PR, this will more often than not output the integrated GPU rather than the dedicated GPU depending on which one is the first in the PCI bus number. How should we go about showing them properly?

Additional context:

It seems like the way neofetch apparently do this is to just ignore intel when querying for dedicated GPU (line ~2528 of the link above):

for gpu in "${gpus[@]}"; do
                # GPU shorthand tests.
                [[ "$gpu_type" == "dedicated" && "$gpu" == *Intel* ]] || \
                [[ "$gpu_type" == "integrated" && ! "$gpu" == *Intel* ]] && \
                    { unset -v gpu; continue; }

However, Intel Arc exists as a dedicated GPU, so this option doesn't cover all the cases... (seems like even hyfetch also still does this though...)

The way screenfetch does it is via checking for GPU with nvidia-smi and glxinfo first before checking lspci (e.g. glxinfo | grep OpenGL will show the GPU in use for OpenGL) (line ~1697)

Personally I think letting the user prioritize which of the GPU vendor to show in the config / or show the list of all the GPUs (I think fastfetch does this) would be a proper solution, but maybe it is too manual? Ultimately I think this is yours to decide.

iinsertNameHere commented 1 month ago

Thanks for the really good question. I haven't thought about that at all yet. I think the best solution would be to collect all GPUs and then compare them with a list of known dedicated GPUs. Alternatively, you could also filter for integrated GPUs. If the GPU is not in the list, the first of the GPUs will be used by default.

CarterLi commented 1 month ago

which of the GPU vendor to show in the config / or show the list of all the GPUs (I think fastfetch does this)

No. Fastfetch also tries to detect the GPU type.

Both Vulkan (vulkaninfo --summary, check deviceType) and OpenGL (no CLI tool available afaik) report GPU type.

GLX report GPU type if open source Mesa driver is used. If glxinfo -B reports Unified memory: yes, the GPU is integrated. The problem of OpenGL is that OpenGL reports only one GPU, which defaults to the integrated one. __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo -B can be used to force GLX running on discrete GPU.

All of these graphic APIs will wake up supended GPUs, which make them very slow on laptop with discrete GPU.

Besides these graphic APIs, there is another way to detect the type of AMD GPU: https://www.kernel.org/doc/html/v5.10/gpu/amdgpu.html#hwmon-interfaces. If /sys/class/drm/card?/device/hwmon/in1_input exists it's a integrated GPU. This method is reliable and very fast. Other than AMD cards, fastfetch checks their brand name. For an Intel GPU, it is discrete if its name contains Arc.

Let me know if you find better ways.

Opposite34 commented 1 month ago

which of the GPU vendor to show in the config / or show the list of all the GPUs (I think fastfetch does this)

No. Fastfetch also tries to detect the GPU type.

Both Vulkan (vulkaninfo --summary, check deviceType) and OpenGL (no CLI tool available afaik) report GPU type.

GLX report GPU type if open source Mesa driver is used. If glxinfo -B reports Unified memory: yes, the GPU is integrated. The problem of OpenGL is that OpenGL reports only one GPU, which defaults to the integrated one. __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo -B can be used to force GLX running on discrete GPU.

All of these graphic APIs will wake up supended GPUs, which make them very slow on laptop with discrete GPU.

Oh that is interesting. It waking up the GPU is quite a downside...

Besides these graphic APIs, there is another way to detect the type of AMD GPU: https://www.kernel.org/doc/html/v5.10/gpu/amdgpu.html#hwmon-interfaces. If /sys/class/drm/card?/device/hwmon/in1_input exists it's a discrete GPU. This method is reliable and very fast. Other than AMD cards, fastfetch checks their brand name. For an Intel GPU, it is discrete if its name contains Arc.

So, in summary of what you're saying, a way to do this is to save a list for the GPUs from lspci | grep VGA, and label them as such:

I think that probably works, as I also couldn't think of a better option myself...

CarterLi commented 1 month ago

If it's an NVIDIA GPU, just label it as a dedicated GPU

NVIDIA does have integrated GPUs. The most famous one is GM20B used by Nintendo Switch. Fastfetch tests if its brand name contains GeForce, Quadro or Tesla.

it's an AMD GPU, check for /sys/class/drm/card${cardnum}/device/hwmon/in1_input if it's dedicated or not. (out of curiosity, does the cardnummatch the pci bus number from lspci? If it does that would make it easy to detect it)

You should use lspci -D. It should print something like 0000:00:01.0 VGA compatible controller: XXX. 0000:00:01.0 is the PCI bus address. Find the file at /sys/bus/pci/devices/0000:00:01.0/hwmon/in1_input. Also correct my last post: if this file exists, it's an APU (integrated AMD GPU)