~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/src/gpu_info_util/SystemInfo_vulkan.cpp

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
 
3
// Use of this source code is governed by a BSD-style license that can be
 
4
// found in the LICENSE file.
 
5
//
 
6
 
 
7
// SystemInfo_vulkan.cpp: Generic vulkan implementation of SystemInfo.h
 
8
 
 
9
#include <dlfcn.h>
 
10
#include <vulkan/vulkan.h>
 
11
#include "gpu_info_util/SystemInfo_internal.h"
 
12
 
 
13
#include <cstring>
 
14
#include <fstream>
 
15
 
 
16
#include "common/angleutils.h"
 
17
#include "common/debug.h"
 
18
 
 
19
namespace angle
 
20
{
 
21
class VulkanLibrary final : NonCopyable
 
22
{
 
23
  public:
 
24
    VulkanLibrary() {}
 
25
    ~VulkanLibrary()
 
26
    {
 
27
        if (mInstance != VK_NULL_HANDLE)
 
28
        {
 
29
            PFN_vkDestroyInstance pfnDestroyInstance =
 
30
                reinterpret_cast<PFN_vkDestroyInstance>(dlsym(mLibVulkan, "vkDestroyInstance"));
 
31
            if (pfnDestroyInstance)
 
32
            {
 
33
                pfnDestroyInstance(mInstance, nullptr);
 
34
            }
 
35
        }
 
36
        if (mLibVulkan)
 
37
            dlclose(mLibVulkan);
 
38
    }
 
39
    VkInstance getVulkanInstance()
 
40
    {
 
41
        // Find the system's Vulkan library and open it:
 
42
        mLibVulkan = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
 
43
        if (!mLibVulkan)
 
44
        {
 
45
            // If Vulkan doesn't exist, bail-out early:
 
46
            return VK_NULL_HANDLE;
 
47
        }
 
48
 
 
49
        // Determine the available Vulkan instance version:
 
50
        uint32_t instanceVersion = VK_API_VERSION_1_0;
 
51
#if defined(VK_VERSION_1_1)
 
52
        PFN_vkEnumerateInstanceVersion pfnEnumerateInstanceVersion =
 
53
            reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
 
54
                dlsym(mLibVulkan, "vkEnumerateInstanceVersion"));
 
55
        if (!pfnEnumerateInstanceVersion ||
 
56
            pfnEnumerateInstanceVersion(&instanceVersion) != VK_SUCCESS)
 
57
        {
 
58
            instanceVersion = VK_API_VERSION_1_0;
 
59
        }
 
60
#endif  // VK_VERSION_1_1
 
61
 
 
62
        // Create a Vulkan instance:
 
63
        VkApplicationInfo appInfo;
 
64
        appInfo.sType              = VK_STRUCTURE_TYPE_APPLICATION_INFO;
 
65
        appInfo.pNext              = nullptr;
 
66
        appInfo.pApplicationName   = "";
 
67
        appInfo.applicationVersion = 1;
 
68
        appInfo.pEngineName        = "";
 
69
        appInfo.engineVersion      = 1;
 
70
        appInfo.apiVersion         = instanceVersion;
 
71
 
 
72
        VkInstanceCreateInfo createInstanceInfo;
 
73
        createInstanceInfo.sType                   = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
 
74
        createInstanceInfo.pNext                   = nullptr;
 
75
        createInstanceInfo.flags                   = 0;
 
76
        createInstanceInfo.pApplicationInfo        = &appInfo;
 
77
        createInstanceInfo.enabledLayerCount       = 0;
 
78
        createInstanceInfo.ppEnabledLayerNames     = nullptr;
 
79
        createInstanceInfo.enabledExtensionCount   = 0;
 
80
        createInstanceInfo.ppEnabledExtensionNames = nullptr;
 
81
 
 
82
        PFN_vkCreateInstance pfnCreateInstance =
 
83
            reinterpret_cast<PFN_vkCreateInstance>(dlsym(mLibVulkan, "vkCreateInstance"));
 
84
        if (!pfnCreateInstance ||
 
85
            pfnCreateInstance(&createInstanceInfo, nullptr, &mInstance) != VK_SUCCESS)
 
86
        {
 
87
            return VK_NULL_HANDLE;
 
88
        }
 
89
 
 
90
        return mInstance;
 
91
    }
 
92
    void *gpa(std::string fn) { return dlsym(mLibVulkan, fn.c_str()); }
 
93
#define GPA(ob, type, fn) reinterpret_cast<type>(ob.gpa(fn))
 
94
 
 
95
  private:
 
96
    void *mLibVulkan     = nullptr;
 
97
    VkInstance mInstance = VK_NULL_HANDLE;
 
98
};
 
99
 
 
100
ANGLE_FORMAT_PRINTF(1, 2)
 
101
std::string FormatString(const char *fmt, ...)
 
102
{
 
103
    va_list vararg;
 
104
    va_start(vararg, fmt);
 
105
 
 
106
    std::vector<char> buffer(512);
 
107
    size_t len = FormatStringIntoVector(fmt, vararg, buffer);
 
108
    va_end(vararg);
 
109
 
 
110
    return std::string(&buffer[0], len);
 
111
}
 
112
 
 
113
bool GetSystemInfoVulkan(SystemInfo *info)
 
114
{
 
115
    // This implementation builds on top of the Vulkan API, but cannot assume the existence of the
 
116
    // Vulkan library.  ANGLE can be installed on versions of Android as old as Ice Cream Sandwich.
 
117
    // Therefore, we need to use dlopen()/dlsym() in order to see if Vulkan is installed on the
 
118
    // system, and if so, to use it:
 
119
    VulkanLibrary vkLibrary;
 
120
    VkInstance instance = vkLibrary.getVulkanInstance();
 
121
    if (instance == VK_NULL_HANDLE)
 
122
    {
 
123
        // If Vulkan doesn't exist, bail-out early:
 
124
        return false;
 
125
    }
 
126
 
 
127
    // Enumerate the Vulkan physical devices, which are ANGLE gpus:
 
128
    PFN_vkEnumeratePhysicalDevices pfnEnumeratePhysicalDevices =
 
129
        GPA(vkLibrary, PFN_vkEnumeratePhysicalDevices, "vkEnumeratePhysicalDevices");
 
130
    PFN_vkGetPhysicalDeviceProperties pfnGetPhysicalDeviceProperties =
 
131
        GPA(vkLibrary, PFN_vkGetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties");
 
132
    uint32_t physicalDeviceCount = 0;
 
133
    if (!pfnEnumeratePhysicalDevices ||
 
134
        pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr) != VK_SUCCESS)
 
135
    {
 
136
        return false;
 
137
    }
 
138
    std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
 
139
    if (pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()) !=
 
140
        VK_SUCCESS)
 
141
    {
 
142
        return false;
 
143
    }
 
144
 
 
145
    // If we get to here, we will likely provide a valid answer (unless an unknown vendorID):
 
146
    info->gpus.resize(physicalDeviceCount);
 
147
 
 
148
    for (uint32_t i = 0; i < physicalDeviceCount; i++)
 
149
    {
 
150
        VkPhysicalDeviceProperties properties;
 
151
        pfnGetPhysicalDeviceProperties(physicalDevices[i], &properties);
 
152
        // Fill in data for a given physical device (a.k.a. gpu):
 
153
        GPUDeviceInfo &gpu = info->gpus[i];
 
154
        gpu.vendorId       = properties.vendorID;
 
155
        gpu.deviceId       = properties.deviceID;
 
156
        // Need to parse/re-format properties.driverVersion.
 
157
        //
 
158
        // TODO(ianelliott): Determine the formatting used for each vendor
 
159
        // (http://anglebug.com/2677)
 
160
        switch (properties.vendorID)
 
161
        {
 
162
            case kVendorID_AMD:
 
163
                gpu.driverVendor                = "Advanced Micro Devices, Inc";
 
164
                gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
 
165
                gpu.detailedDriverVersion.major = properties.driverVersion;
 
166
                break;
 
167
            case kVendorID_ARM:
 
168
                gpu.driverVendor                = "Arm Holdings";
 
169
                gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
 
170
                gpu.detailedDriverVersion.major = properties.driverVersion;
 
171
                break;
 
172
            case kVendorID_Broadcom:
 
173
                gpu.driverVendor                = "Broadcom";
 
174
                gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
 
175
                gpu.detailedDriverVersion.major = properties.driverVersion;
 
176
                break;
 
177
            case kVendorID_ImgTec:
 
178
                gpu.driverVendor                = "Imagination Technologies Limited";
 
179
                gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
 
180
                gpu.detailedDriverVersion.major = properties.driverVersion;
 
181
                break;
 
182
            case kVendorID_Intel:
 
183
                gpu.driverVendor                = "Intel Corporation";
 
184
                gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
 
185
                gpu.detailedDriverVersion.major = properties.driverVersion;
 
186
                break;
 
187
            case kVendorID_Kazan:
 
188
                gpu.driverVendor                = "Kazan Software";
 
189
                gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
 
190
                gpu.detailedDriverVersion.major = properties.driverVersion;
 
191
                break;
 
192
            case kVendorID_NVIDIA:
 
193
                gpu.driverVendor  = "NVIDIA Corporation";
 
194
                gpu.driverVersion = FormatString("%d.%d.%d.%d", properties.driverVersion >> 22,
 
195
                                                 (properties.driverVersion >> 14) & 0XFF,
 
196
                                                 (properties.driverVersion >> 6) & 0XFF,
 
197
                                                 properties.driverVersion & 0x3F);
 
198
                gpu.detailedDriverVersion.major    = properties.driverVersion >> 22;
 
199
                gpu.detailedDriverVersion.minor    = (properties.driverVersion >> 14) & 0xFF;
 
200
                gpu.detailedDriverVersion.subMinor = (properties.driverVersion >> 6) & 0xFF;
 
201
                gpu.detailedDriverVersion.patch    = properties.driverVersion & 0x3F;
 
202
                break;
 
203
            case kVendorID_Qualcomm:
 
204
                gpu.driverVendor = "Qualcomm Technologies, Inc";
 
205
                if (properties.driverVersion & 0x80000000)
 
206
                {
 
207
                    gpu.driverVersion = FormatString("%d.%d.%d", properties.driverVersion >> 22,
 
208
                                                     (properties.driverVersion >> 12) & 0X3FF,
 
209
                                                     properties.driverVersion & 0xFFF);
 
210
                    gpu.detailedDriverVersion.major    = properties.driverVersion >> 22;
 
211
                    gpu.detailedDriverVersion.minor    = (properties.driverVersion >> 12) & 0x3FF;
 
212
                    gpu.detailedDriverVersion.subMinor = properties.driverVersion & 0xFFF;
 
213
                }
 
214
                else
 
215
                {
 
216
                    gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
 
217
                    gpu.detailedDriverVersion.major = properties.driverVersion;
 
218
                }
 
219
                break;
 
220
            case kVendorID_VeriSilicon:
 
221
                gpu.driverVendor                = "VeriSilicon";
 
222
                gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
 
223
                gpu.detailedDriverVersion.major = properties.driverVersion;
 
224
                break;
 
225
            case kVendorID_Vivante:
 
226
                gpu.driverVendor                = "Vivante";
 
227
                gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
 
228
                gpu.detailedDriverVersion.major = properties.driverVersion;
 
229
                break;
 
230
            default:
 
231
                return false;
 
232
        }
 
233
        gpu.driverDate = "";
 
234
    }
 
235
 
 
236
    return true;
 
237
}
 
238
 
 
239
}  // namespace angle