Edit

kc3-lang/angle/src/gpu_info_util/SystemInfo_libpci.cpp

Branch :

  • Show log

    Commit

  • Author : David Stevens
    Date : 2021-04-12 15:29:26
    Hash : 0615bbde
    Message : Ignore subclass when finding GPU PCI devices When enumerating PCI devices to find GPUs, only filter on the base class. This allows devices with class PCI_CLASS_DISPLAY_OTHER to be found. Bug: b/178748337 Change-Id: Ia0cd29dddc49a16428da16c1ef1b94040c1221f7 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2817973 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>

  • src/gpu_info_util/SystemInfo_libpci.cpp
  • //
    // Copyright 2013 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // SystemInfo_libpci.cpp: implementation of the libPCI-specific parts of SystemInfo.h
    
    #include "gpu_info_util/SystemInfo_internal.h"
    
    #include <dlfcn.h>
    #include <pci/pci.h>
    #include <unistd.h>
    
    #include "common/angleutils.h"
    #include "common/debug.h"
    
    #if !defined(GPU_INFO_USE_LIBPCI)
    #    error SystemInfo_libpci.cpp compiled without GPU_INFO_USE_LIBPCI
    #endif
    
    namespace angle
    {
    
    namespace
    {
    
    struct LibPCI : private angle::NonCopyable
    {
        LibPCI()
        {
            if (access("/sys/bus/pci/", F_OK) != 0 && access("/sys/bs/pci_express/", F_OK) != 0)
            {
                return;
            }
    
            mHandle = dlopen("libpci.so.3", RTLD_LAZY);
    
            if (mHandle == nullptr)
            {
                mHandle = dlopen("libpci.so", RTLD_LAZY);
            }
    
            if (mHandle == nullptr)
            {
                return;
            }
    
            mValid =
                (Alloc = reinterpret_cast<decltype(Alloc)>(dlsym(mHandle, "pci_alloc"))) != nullptr &&
                (Init = reinterpret_cast<decltype(Init)>(dlsym(mHandle, "pci_init"))) != nullptr &&
                (Cleanup = reinterpret_cast<decltype(Cleanup)>(dlsym(mHandle, "pci_cleanup"))) !=
                    nullptr &&
                (ScanBus = reinterpret_cast<decltype(ScanBus)>(dlsym(mHandle, "pci_scan_bus"))) !=
                    nullptr &&
                (FillInfo = reinterpret_cast<decltype(FillInfo)>(dlsym(mHandle, "pci_fill_info"))) !=
                    nullptr &&
                (LookupName = reinterpret_cast<decltype(LookupName)>(
                     dlsym(mHandle, "pci_lookup_name"))) != nullptr &&
                (PCIReadByte = reinterpret_cast<decltype(PCIReadByte)>(
                     dlsym(mHandle, "pci_read_byte"))) != nullptr;
        }
    
        bool IsValid() const { return mValid; }
    
        ~LibPCI()
        {
            if (mHandle != nullptr)
            {
                dlclose(mHandle);
            }
        }
    
        decltype(&::pci_alloc) Alloc            = nullptr;
        decltype(&::pci_init) Init              = nullptr;
        decltype(&::pci_cleanup) Cleanup        = nullptr;
        decltype(&::pci_scan_bus) ScanBus       = nullptr;
        decltype(&::pci_fill_info) FillInfo     = nullptr;
        decltype(&::pci_lookup_name) LookupName = nullptr;
        decltype(&::pci_read_byte) PCIReadByte  = nullptr;
    
      private:
        void *mHandle = nullptr;
        bool mValid   = false;
    };
    
    }  // anonymous namespace
    
    // Adds an entry per PCI GPU found and fills the device and vendor ID.
    bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices)
    {
        LibPCI pci;
        if (!pci.IsValid())
        {
            return false;
        }
    
        pci_access *access = pci.Alloc();
        ASSERT(access != nullptr);
        pci.Init(access);
        pci.ScanBus(access);
    
        for (pci_dev *device = access->devices; device != nullptr; device = device->next)
        {
            pci.FillInfo(device, PCI_FILL_IDENT | PCI_FILL_CLASS);
    
            // Skip non-GPU devices
            if (device->device_class >> 8 != PCI_BASE_CLASS_DISPLAY)
            {
                continue;
            }
    
            // Skip unknown devices
            if (device->vendor_id == 0 || device->device_id == 0)
            {
                continue;
            }
    
            GPUDeviceInfo info;
            info.vendorId   = device->vendor_id;
            info.deviceId   = device->device_id;
            info.revisionId = pci.PCIReadByte(device, PCI_REVISION_ID);
    
            devices->push_back(info);
        }
    
        pci.Cleanup(access);
    
        return true;
    }
    }  // namespace angle