1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // vulkan_icd.cpp : Helper for creating vulkan instances & selecting physical device.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "common/vulkan/vulkan_icd.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include <functional>
12*8975f5c5SAndroid Build Coastguard Worker #include <vector>
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker #include "common/Optional.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/bitset_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker namespace
20*8975f5c5SAndroid Build Coastguard Worker {
ResetEnvironmentVar(const char * variableName,const Optional<std::string> & value)21*8975f5c5SAndroid Build Coastguard Worker void ResetEnvironmentVar(const char *variableName, const Optional<std::string> &value)
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker if (!value.valid())
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker return;
26*8975f5c5SAndroid Build Coastguard Worker }
27*8975f5c5SAndroid Build Coastguard Worker
28*8975f5c5SAndroid Build Coastguard Worker if (value.value().empty())
29*8975f5c5SAndroid Build Coastguard Worker {
30*8975f5c5SAndroid Build Coastguard Worker angle::UnsetEnvironmentVar(variableName);
31*8975f5c5SAndroid Build Coastguard Worker }
32*8975f5c5SAndroid Build Coastguard Worker else
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker angle::SetEnvironmentVar(variableName, value.value().c_str());
35*8975f5c5SAndroid Build Coastguard Worker }
36*8975f5c5SAndroid Build Coastguard Worker }
37*8975f5c5SAndroid Build Coastguard Worker } // namespace
38*8975f5c5SAndroid Build Coastguard Worker
39*8975f5c5SAndroid Build Coastguard Worker namespace angle
40*8975f5c5SAndroid Build Coastguard Worker {
41*8975f5c5SAndroid Build Coastguard Worker
42*8975f5c5SAndroid Build Coastguard Worker namespace vk
43*8975f5c5SAndroid Build Coastguard Worker {
44*8975f5c5SAndroid Build Coastguard Worker
45*8975f5c5SAndroid Build Coastguard Worker namespace
46*8975f5c5SAndroid Build Coastguard Worker {
47*8975f5c5SAndroid Build Coastguard Worker
WrapICDEnvironment(const char * icdEnvironment)48*8975f5c5SAndroid Build Coastguard Worker [[maybe_unused]] const std::string WrapICDEnvironment(const char *icdEnvironment)
49*8975f5c5SAndroid Build Coastguard Worker {
50*8975f5c5SAndroid Build Coastguard Worker // The libraries are bundled into the module directory
51*8975f5c5SAndroid Build Coastguard Worker std::string moduleDir = angle::GetModuleDirectory();
52*8975f5c5SAndroid Build Coastguard Worker std::string ret = ConcatenatePath(moduleDir, icdEnvironment);
53*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_MACOS)
54*8975f5c5SAndroid Build Coastguard Worker std::string moduleDirWithLibraries = ConcatenatePath(moduleDir, "Libraries");
55*8975f5c5SAndroid Build Coastguard Worker ret += ":" + ConcatenatePath(moduleDirWithLibraries, icdEnvironment);
56*8975f5c5SAndroid Build Coastguard Worker #endif
57*8975f5c5SAndroid Build Coastguard Worker return ret;
58*8975f5c5SAndroid Build Coastguard Worker }
59*8975f5c5SAndroid Build Coastguard Worker
60*8975f5c5SAndroid Build Coastguard Worker [[maybe_unused]] constexpr char kLoaderLayersPathEnv[] = "VK_LAYER_PATH";
61*8975f5c5SAndroid Build Coastguard Worker [[maybe_unused]] constexpr char kLayerEnablesEnv[] = "VK_LAYER_ENABLES";
62*8975f5c5SAndroid Build Coastguard Worker
63*8975f5c5SAndroid Build Coastguard Worker constexpr char kLoaderICDFilenamesEnv[] = "VK_ICD_FILENAMES";
64*8975f5c5SAndroid Build Coastguard Worker constexpr char kANGLEPreferredDeviceEnv[] = "ANGLE_PREFERRED_DEVICE";
65*8975f5c5SAndroid Build Coastguard Worker constexpr char kValidationLayersCustomSTypeListEnv[] = "VK_LAYER_CUSTOM_STYPE_LIST";
66*8975f5c5SAndroid Build Coastguard Worker constexpr char kNoDeviceSelect[] = "NODEVICE_SELECT";
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kMockVendorID = 0xba5eba11;
69*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kMockDeviceID = 0xf005ba11;
70*8975f5c5SAndroid Build Coastguard Worker constexpr char kMockDeviceName[] = "Vulkan Mock Device";
71*8975f5c5SAndroid Build Coastguard Worker
72*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kGoogleVendorID = 0x1AE0;
73*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kSwiftShaderDeviceID = 0xC0DE;
74*8975f5c5SAndroid Build Coastguard Worker constexpr char kSwiftShaderDeviceName[] = "SwiftShader Device";
75*8975f5c5SAndroid Build Coastguard Worker
76*8975f5c5SAndroid Build Coastguard Worker using ICDFilterFunc = std::function<bool(const VkPhysicalDeviceProperties &)>;
77*8975f5c5SAndroid Build Coastguard Worker
GetFilterForICD(vk::ICD preferredICD)78*8975f5c5SAndroid Build Coastguard Worker ICDFilterFunc GetFilterForICD(vk::ICD preferredICD)
79*8975f5c5SAndroid Build Coastguard Worker {
80*8975f5c5SAndroid Build Coastguard Worker switch (preferredICD)
81*8975f5c5SAndroid Build Coastguard Worker {
82*8975f5c5SAndroid Build Coastguard Worker case vk::ICD::Mock:
83*8975f5c5SAndroid Build Coastguard Worker return [](const VkPhysicalDeviceProperties &deviceProperties) {
84*8975f5c5SAndroid Build Coastguard Worker return ((deviceProperties.vendorID == kMockVendorID) &&
85*8975f5c5SAndroid Build Coastguard Worker (deviceProperties.deviceID == kMockDeviceID) &&
86*8975f5c5SAndroid Build Coastguard Worker (strcmp(deviceProperties.deviceName, kMockDeviceName) == 0));
87*8975f5c5SAndroid Build Coastguard Worker };
88*8975f5c5SAndroid Build Coastguard Worker case vk::ICD::SwiftShader:
89*8975f5c5SAndroid Build Coastguard Worker return [](const VkPhysicalDeviceProperties &deviceProperties) {
90*8975f5c5SAndroid Build Coastguard Worker return ((deviceProperties.vendorID == kGoogleVendorID) &&
91*8975f5c5SAndroid Build Coastguard Worker (deviceProperties.deviceID == kSwiftShaderDeviceID) &&
92*8975f5c5SAndroid Build Coastguard Worker (strncmp(deviceProperties.deviceName, kSwiftShaderDeviceName,
93*8975f5c5SAndroid Build Coastguard Worker strlen(kSwiftShaderDeviceName)) == 0));
94*8975f5c5SAndroid Build Coastguard Worker };
95*8975f5c5SAndroid Build Coastguard Worker default:
96*8975f5c5SAndroid Build Coastguard Worker const std::string anglePreferredDevice =
97*8975f5c5SAndroid Build Coastguard Worker angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
98*8975f5c5SAndroid Build Coastguard Worker return [anglePreferredDevice](const VkPhysicalDeviceProperties &deviceProperties) {
99*8975f5c5SAndroid Build Coastguard Worker return (anglePreferredDevice == deviceProperties.deviceName);
100*8975f5c5SAndroid Build Coastguard Worker };
101*8975f5c5SAndroid Build Coastguard Worker }
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker
104*8975f5c5SAndroid Build Coastguard Worker } // namespace
105*8975f5c5SAndroid Build Coastguard Worker
106*8975f5c5SAndroid Build Coastguard Worker // If we're loading the vulkan layers, we could be running from any random directory.
107*8975f5c5SAndroid Build Coastguard Worker // Change to the executable directory so we can find the layers, then change back to the
108*8975f5c5SAndroid Build Coastguard Worker // previous directory to be safe we don't disrupt the application.
ScopedVkLoaderEnvironment(bool enableDebugLayers,vk::ICD icd)109*8975f5c5SAndroid Build Coastguard Worker ScopedVkLoaderEnvironment::ScopedVkLoaderEnvironment(bool enableDebugLayers, vk::ICD icd)
110*8975f5c5SAndroid Build Coastguard Worker : mEnableDebugLayers(enableDebugLayers),
111*8975f5c5SAndroid Build Coastguard Worker mICD(icd),
112*8975f5c5SAndroid Build Coastguard Worker mChangedCWD(false),
113*8975f5c5SAndroid Build Coastguard Worker mChangedICDEnv(false),
114*8975f5c5SAndroid Build Coastguard Worker mChangedNoDeviceSelect(false)
115*8975f5c5SAndroid Build Coastguard Worker {
116*8975f5c5SAndroid Build Coastguard Worker // Changing CWD and setting environment variables makes no sense on Android,
117*8975f5c5SAndroid Build Coastguard Worker // since this code is a part of Java application there.
118*8975f5c5SAndroid Build Coastguard Worker // Android Vulkan loader doesn't need this either.
119*8975f5c5SAndroid Build Coastguard Worker #if !defined(ANGLE_PLATFORM_ANDROID) && !defined(ANGLE_PLATFORM_GGP)
120*8975f5c5SAndroid Build Coastguard Worker if (icd == vk::ICD::Mock)
121*8975f5c5SAndroid Build Coastguard Worker {
122*8975f5c5SAndroid Build Coastguard Worker if (!setICDEnvironment(WrapICDEnvironment(ANGLE_VK_MOCK_ICD_JSON).c_str()))
123*8975f5c5SAndroid Build Coastguard Worker {
124*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error setting environment for Mock/Null Driver.";
125*8975f5c5SAndroid Build Coastguard Worker }
126*8975f5c5SAndroid Build Coastguard Worker }
127*8975f5c5SAndroid Build Coastguard Worker # if defined(ANGLE_VK_SWIFTSHADER_ICD_JSON)
128*8975f5c5SAndroid Build Coastguard Worker else if (icd == vk::ICD::SwiftShader)
129*8975f5c5SAndroid Build Coastguard Worker {
130*8975f5c5SAndroid Build Coastguard Worker if (!setICDEnvironment(WrapICDEnvironment(ANGLE_VK_SWIFTSHADER_ICD_JSON).c_str()))
131*8975f5c5SAndroid Build Coastguard Worker {
132*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error setting environment for SwiftShader.";
133*8975f5c5SAndroid Build Coastguard Worker }
134*8975f5c5SAndroid Build Coastguard Worker }
135*8975f5c5SAndroid Build Coastguard Worker # endif // defined(ANGLE_VK_SWIFTSHADER_ICD_JSON)
136*8975f5c5SAndroid Build Coastguard Worker
137*8975f5c5SAndroid Build Coastguard Worker # if !defined(ANGLE_PLATFORM_MACOS)
138*8975f5c5SAndroid Build Coastguard Worker if (mEnableDebugLayers || icd != vk::ICD::Default)
139*8975f5c5SAndroid Build Coastguard Worker {
140*8975f5c5SAndroid Build Coastguard Worker const auto &cwd = angle::GetCWD();
141*8975f5c5SAndroid Build Coastguard Worker if (!cwd.valid())
142*8975f5c5SAndroid Build Coastguard Worker {
143*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error getting CWD for Vulkan layers init.";
144*8975f5c5SAndroid Build Coastguard Worker mEnableDebugLayers = false;
145*8975f5c5SAndroid Build Coastguard Worker mICD = vk::ICD::Default;
146*8975f5c5SAndroid Build Coastguard Worker }
147*8975f5c5SAndroid Build Coastguard Worker else
148*8975f5c5SAndroid Build Coastguard Worker {
149*8975f5c5SAndroid Build Coastguard Worker mPreviousCWD = cwd.value();
150*8975f5c5SAndroid Build Coastguard Worker std::string moduleDir = angle::GetModuleDirectory();
151*8975f5c5SAndroid Build Coastguard Worker mChangedCWD = angle::SetCWD(moduleDir.c_str());
152*8975f5c5SAndroid Build Coastguard Worker if (!mChangedCWD)
153*8975f5c5SAndroid Build Coastguard Worker {
154*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error setting CWD for Vulkan layers init.";
155*8975f5c5SAndroid Build Coastguard Worker mEnableDebugLayers = false;
156*8975f5c5SAndroid Build Coastguard Worker mICD = vk::ICD::Default;
157*8975f5c5SAndroid Build Coastguard Worker }
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker }
160*8975f5c5SAndroid Build Coastguard Worker # endif // defined(ANGLE_PLATFORM_MACOS)
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker // Override environment variable to use the ANGLE layers.
163*8975f5c5SAndroid Build Coastguard Worker if (mEnableDebugLayers)
164*8975f5c5SAndroid Build Coastguard Worker {
165*8975f5c5SAndroid Build Coastguard Worker # if defined(ANGLE_VK_LAYERS_DIR)
166*8975f5c5SAndroid Build Coastguard Worker if (!angle::PrependPathToEnvironmentVar(kLoaderLayersPathEnv, ANGLE_VK_LAYERS_DIR))
167*8975f5c5SAndroid Build Coastguard Worker {
168*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error setting environment for Vulkan layers init.";
169*8975f5c5SAndroid Build Coastguard Worker mEnableDebugLayers = false;
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker # endif // defined(ANGLE_VK_LAYERS_DIR)
172*8975f5c5SAndroid Build Coastguard Worker }
173*8975f5c5SAndroid Build Coastguard Worker #endif // !defined(ANGLE_PLATFORM_ANDROID)
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker if (IsMSan() || IsASan())
176*8975f5c5SAndroid Build Coastguard Worker {
177*8975f5c5SAndroid Build Coastguard Worker // device select layer cause memory sanitizer false positive, so disable
178*8975f5c5SAndroid Build Coastguard Worker // it for msan build.
179*8975f5c5SAndroid Build Coastguard Worker mPreviousNoDeviceSelectEnv = angle::GetEnvironmentVar(kNoDeviceSelect);
180*8975f5c5SAndroid Build Coastguard Worker angle::SetEnvironmentVar(kNoDeviceSelect, "1");
181*8975f5c5SAndroid Build Coastguard Worker mChangedNoDeviceSelect = true;
182*8975f5c5SAndroid Build Coastguard Worker }
183*8975f5c5SAndroid Build Coastguard Worker }
184*8975f5c5SAndroid Build Coastguard Worker
~ScopedVkLoaderEnvironment()185*8975f5c5SAndroid Build Coastguard Worker ScopedVkLoaderEnvironment::~ScopedVkLoaderEnvironment()
186*8975f5c5SAndroid Build Coastguard Worker {
187*8975f5c5SAndroid Build Coastguard Worker if (mChangedCWD)
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker #if !defined(ANGLE_PLATFORM_ANDROID)
190*8975f5c5SAndroid Build Coastguard Worker ASSERT(mPreviousCWD.valid());
191*8975f5c5SAndroid Build Coastguard Worker angle::SetCWD(mPreviousCWD.value().c_str());
192*8975f5c5SAndroid Build Coastguard Worker #endif // !defined(ANGLE_PLATFORM_ANDROID)
193*8975f5c5SAndroid Build Coastguard Worker }
194*8975f5c5SAndroid Build Coastguard Worker if (mChangedICDEnv)
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker ResetEnvironmentVar(kLoaderICDFilenamesEnv, mPreviousICDEnv);
197*8975f5c5SAndroid Build Coastguard Worker }
198*8975f5c5SAndroid Build Coastguard Worker
199*8975f5c5SAndroid Build Coastguard Worker ResetEnvironmentVar(kValidationLayersCustomSTypeListEnv, mPreviousCustomExtensionsEnv);
200*8975f5c5SAndroid Build Coastguard Worker
201*8975f5c5SAndroid Build Coastguard Worker if (mChangedNoDeviceSelect)
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker ResetEnvironmentVar(kNoDeviceSelect, mPreviousNoDeviceSelectEnv);
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker }
206*8975f5c5SAndroid Build Coastguard Worker
setICDEnvironment(const char * icd)207*8975f5c5SAndroid Build Coastguard Worker bool ScopedVkLoaderEnvironment::setICDEnvironment(const char *icd)
208*8975f5c5SAndroid Build Coastguard Worker {
209*8975f5c5SAndroid Build Coastguard Worker // Override environment variable to use built Mock ICD
210*8975f5c5SAndroid Build Coastguard Worker // ANGLE_VK_ICD_JSON gets set to the built mock ICD in BUILD.gn
211*8975f5c5SAndroid Build Coastguard Worker mPreviousICDEnv = angle::GetEnvironmentVar(kLoaderICDFilenamesEnv);
212*8975f5c5SAndroid Build Coastguard Worker mChangedICDEnv = angle::SetEnvironmentVar(kLoaderICDFilenamesEnv, icd);
213*8975f5c5SAndroid Build Coastguard Worker
214*8975f5c5SAndroid Build Coastguard Worker if (!mChangedICDEnv)
215*8975f5c5SAndroid Build Coastguard Worker {
216*8975f5c5SAndroid Build Coastguard Worker mICD = vk::ICD::Default;
217*8975f5c5SAndroid Build Coastguard Worker }
218*8975f5c5SAndroid Build Coastguard Worker return mChangedICDEnv;
219*8975f5c5SAndroid Build Coastguard Worker }
220*8975f5c5SAndroid Build Coastguard Worker
ChoosePhysicalDevice(PFN_vkGetPhysicalDeviceProperties pGetPhysicalDeviceProperties,const std::vector<VkPhysicalDevice> & physicalDevices,vk::ICD preferredICD,uint32_t preferredVendorID,uint32_t preferredDeviceID,VkPhysicalDevice * physicalDeviceOut,VkPhysicalDeviceProperties * physicalDevicePropertiesOut)221*8975f5c5SAndroid Build Coastguard Worker void ChoosePhysicalDevice(PFN_vkGetPhysicalDeviceProperties pGetPhysicalDeviceProperties,
222*8975f5c5SAndroid Build Coastguard Worker const std::vector<VkPhysicalDevice> &physicalDevices,
223*8975f5c5SAndroid Build Coastguard Worker vk::ICD preferredICD,
224*8975f5c5SAndroid Build Coastguard Worker uint32_t preferredVendorID,
225*8975f5c5SAndroid Build Coastguard Worker uint32_t preferredDeviceID,
226*8975f5c5SAndroid Build Coastguard Worker VkPhysicalDevice *physicalDeviceOut,
227*8975f5c5SAndroid Build Coastguard Worker VkPhysicalDeviceProperties *physicalDevicePropertiesOut)
228*8975f5c5SAndroid Build Coastguard Worker {
229*8975f5c5SAndroid Build Coastguard Worker ASSERT(!physicalDevices.empty());
230*8975f5c5SAndroid Build Coastguard Worker
231*8975f5c5SAndroid Build Coastguard Worker ICDFilterFunc filter = GetFilterForICD(preferredICD);
232*8975f5c5SAndroid Build Coastguard Worker
233*8975f5c5SAndroid Build Coastguard Worker const bool shouldChooseByID = (preferredVendorID != 0 || preferredDeviceID != 0);
234*8975f5c5SAndroid Build Coastguard Worker
235*8975f5c5SAndroid Build Coastguard Worker for (const VkPhysicalDevice &physicalDevice : physicalDevices)
236*8975f5c5SAndroid Build Coastguard Worker {
237*8975f5c5SAndroid Build Coastguard Worker pGetPhysicalDeviceProperties(physicalDevice, physicalDevicePropertiesOut);
238*8975f5c5SAndroid Build Coastguard Worker
239*8975f5c5SAndroid Build Coastguard Worker if (physicalDevicePropertiesOut->apiVersion < kMinimumVulkanAPIVersion)
240*8975f5c5SAndroid Build Coastguard Worker {
241*8975f5c5SAndroid Build Coastguard Worker // Skip any devices that don't support our minimum API version. This
242*8975f5c5SAndroid Build Coastguard Worker // takes precedence over all other considerations.
243*8975f5c5SAndroid Build Coastguard Worker continue;
244*8975f5c5SAndroid Build Coastguard Worker }
245*8975f5c5SAndroid Build Coastguard Worker
246*8975f5c5SAndroid Build Coastguard Worker if (filter(*physicalDevicePropertiesOut))
247*8975f5c5SAndroid Build Coastguard Worker {
248*8975f5c5SAndroid Build Coastguard Worker *physicalDeviceOut = physicalDevice;
249*8975f5c5SAndroid Build Coastguard Worker return;
250*8975f5c5SAndroid Build Coastguard Worker }
251*8975f5c5SAndroid Build Coastguard Worker
252*8975f5c5SAndroid Build Coastguard Worker if (shouldChooseByID)
253*8975f5c5SAndroid Build Coastguard Worker {
254*8975f5c5SAndroid Build Coastguard Worker // NOTE: If the system has multiple GPUs with the same vendor and
255*8975f5c5SAndroid Build Coastguard Worker // device IDs, this will arbitrarily select one of them.
256*8975f5c5SAndroid Build Coastguard Worker bool matchVendorID = true;
257*8975f5c5SAndroid Build Coastguard Worker bool matchDeviceID = true;
258*8975f5c5SAndroid Build Coastguard Worker
259*8975f5c5SAndroid Build Coastguard Worker if (preferredVendorID != 0 &&
260*8975f5c5SAndroid Build Coastguard Worker preferredVendorID != physicalDevicePropertiesOut->vendorID)
261*8975f5c5SAndroid Build Coastguard Worker {
262*8975f5c5SAndroid Build Coastguard Worker matchVendorID = false;
263*8975f5c5SAndroid Build Coastguard Worker }
264*8975f5c5SAndroid Build Coastguard Worker
265*8975f5c5SAndroid Build Coastguard Worker if (preferredDeviceID != 0 &&
266*8975f5c5SAndroid Build Coastguard Worker preferredDeviceID != physicalDevicePropertiesOut->deviceID)
267*8975f5c5SAndroid Build Coastguard Worker {
268*8975f5c5SAndroid Build Coastguard Worker matchDeviceID = false;
269*8975f5c5SAndroid Build Coastguard Worker }
270*8975f5c5SAndroid Build Coastguard Worker
271*8975f5c5SAndroid Build Coastguard Worker if (matchVendorID && matchDeviceID)
272*8975f5c5SAndroid Build Coastguard Worker {
273*8975f5c5SAndroid Build Coastguard Worker *physicalDeviceOut = physicalDevice;
274*8975f5c5SAndroid Build Coastguard Worker return;
275*8975f5c5SAndroid Build Coastguard Worker }
276*8975f5c5SAndroid Build Coastguard Worker }
277*8975f5c5SAndroid Build Coastguard Worker }
278*8975f5c5SAndroid Build Coastguard Worker
279*8975f5c5SAndroid Build Coastguard Worker Optional<VkPhysicalDevice> integratedDevice;
280*8975f5c5SAndroid Build Coastguard Worker VkPhysicalDeviceProperties integratedDeviceProperties;
281*8975f5c5SAndroid Build Coastguard Worker for (const VkPhysicalDevice &physicalDevice : physicalDevices)
282*8975f5c5SAndroid Build Coastguard Worker {
283*8975f5c5SAndroid Build Coastguard Worker pGetPhysicalDeviceProperties(physicalDevice, physicalDevicePropertiesOut);
284*8975f5c5SAndroid Build Coastguard Worker
285*8975f5c5SAndroid Build Coastguard Worker if (physicalDevicePropertiesOut->apiVersion < kMinimumVulkanAPIVersion)
286*8975f5c5SAndroid Build Coastguard Worker {
287*8975f5c5SAndroid Build Coastguard Worker // Skip any devices that don't support our minimum API version. This
288*8975f5c5SAndroid Build Coastguard Worker // takes precedence over all other considerations.
289*8975f5c5SAndroid Build Coastguard Worker continue;
290*8975f5c5SAndroid Build Coastguard Worker }
291*8975f5c5SAndroid Build Coastguard Worker
292*8975f5c5SAndroid Build Coastguard Worker // If discrete GPU exists, uses it by default.
293*8975f5c5SAndroid Build Coastguard Worker if (physicalDevicePropertiesOut->deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
294*8975f5c5SAndroid Build Coastguard Worker {
295*8975f5c5SAndroid Build Coastguard Worker *physicalDeviceOut = physicalDevice;
296*8975f5c5SAndroid Build Coastguard Worker return;
297*8975f5c5SAndroid Build Coastguard Worker }
298*8975f5c5SAndroid Build Coastguard Worker if (physicalDevicePropertiesOut->deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
299*8975f5c5SAndroid Build Coastguard Worker !integratedDevice.valid())
300*8975f5c5SAndroid Build Coastguard Worker {
301*8975f5c5SAndroid Build Coastguard Worker integratedDevice = physicalDevice;
302*8975f5c5SAndroid Build Coastguard Worker integratedDeviceProperties = *physicalDevicePropertiesOut;
303*8975f5c5SAndroid Build Coastguard Worker continue;
304*8975f5c5SAndroid Build Coastguard Worker }
305*8975f5c5SAndroid Build Coastguard Worker }
306*8975f5c5SAndroid Build Coastguard Worker
307*8975f5c5SAndroid Build Coastguard Worker // If only integrated GPU exists, use it by default.
308*8975f5c5SAndroid Build Coastguard Worker if (integratedDevice.valid())
309*8975f5c5SAndroid Build Coastguard Worker {
310*8975f5c5SAndroid Build Coastguard Worker *physicalDeviceOut = integratedDevice.value();
311*8975f5c5SAndroid Build Coastguard Worker *physicalDevicePropertiesOut = integratedDeviceProperties;
312*8975f5c5SAndroid Build Coastguard Worker return;
313*8975f5c5SAndroid Build Coastguard Worker }
314*8975f5c5SAndroid Build Coastguard Worker
315*8975f5c5SAndroid Build Coastguard Worker WARN() << "Preferred device ICD not found. Using default physicalDevice instead.";
316*8975f5c5SAndroid Build Coastguard Worker // Fallback to the first device.
317*8975f5c5SAndroid Build Coastguard Worker *physicalDeviceOut = physicalDevices[0];
318*8975f5c5SAndroid Build Coastguard Worker pGetPhysicalDeviceProperties(*physicalDeviceOut, physicalDevicePropertiesOut);
319*8975f5c5SAndroid Build Coastguard Worker }
320*8975f5c5SAndroid Build Coastguard Worker
321*8975f5c5SAndroid Build Coastguard Worker } // namespace vk
322*8975f5c5SAndroid Build Coastguard Worker
323*8975f5c5SAndroid Build Coastguard Worker } // namespace angle
324