xref: /aosp_15_r20/frameworks/native/vulkan/libvulkan/driver.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2016 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include "driver.h"
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <dlfcn.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <malloc.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <stdlib.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <string.h>
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker #include <SurfaceFlingerProperties.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <android/dlext.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <configstore/Utils.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <graphicsenv/GraphicsEnv.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <sys/prctl.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <vndksupport/linker.h>
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker #include <algorithm>
39*38e8c45fSAndroid Build Coastguard Worker #include <array>
40*38e8c45fSAndroid Build Coastguard Worker #include <climits>
41*38e8c45fSAndroid Build Coastguard Worker #include <new>
42*38e8c45fSAndroid Build Coastguard Worker #include <vector>
43*38e8c45fSAndroid Build Coastguard Worker 
44*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_libvulkan_flags.h>
45*38e8c45fSAndroid Build Coastguard Worker #include "stubhal.h"
46*38e8c45fSAndroid Build Coastguard Worker 
47*38e8c45fSAndroid Build Coastguard Worker using namespace android::hardware::configstore;
48*38e8c45fSAndroid Build Coastguard Worker using namespace android::hardware::configstore::V1_0;
49*38e8c45fSAndroid Build Coastguard Worker using namespace com::android::graphics::libvulkan;
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker extern "C" android_namespace_t* android_get_exported_namespace(const char*);
52*38e8c45fSAndroid Build Coastguard Worker 
53*38e8c45fSAndroid Build Coastguard Worker // #define ENABLE_ALLOC_CALLSTACKS 1
54*38e8c45fSAndroid Build Coastguard Worker #if ENABLE_ALLOC_CALLSTACKS
55*38e8c45fSAndroid Build Coastguard Worker #include <utils/CallStack.h>
56*38e8c45fSAndroid Build Coastguard Worker #define ALOGD_CALLSTACK(...)                             \
57*38e8c45fSAndroid Build Coastguard Worker     do {                                                 \
58*38e8c45fSAndroid Build Coastguard Worker         ALOGD(__VA_ARGS__);                              \
59*38e8c45fSAndroid Build Coastguard Worker         android::CallStack callstack;                    \
60*38e8c45fSAndroid Build Coastguard Worker         callstack.update();                              \
61*38e8c45fSAndroid Build Coastguard Worker         callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, "  "); \
62*38e8c45fSAndroid Build Coastguard Worker     } while (false)
63*38e8c45fSAndroid Build Coastguard Worker #else
64*38e8c45fSAndroid Build Coastguard Worker #define ALOGD_CALLSTACK(...) \
65*38e8c45fSAndroid Build Coastguard Worker     do {                     \
66*38e8c45fSAndroid Build Coastguard Worker     } while (false)
67*38e8c45fSAndroid Build Coastguard Worker #endif
68*38e8c45fSAndroid Build Coastguard Worker 
69*38e8c45fSAndroid Build Coastguard Worker namespace vulkan {
70*38e8c45fSAndroid Build Coastguard Worker namespace driver {
71*38e8c45fSAndroid Build Coastguard Worker 
72*38e8c45fSAndroid Build Coastguard Worker namespace {
73*38e8c45fSAndroid Build Coastguard Worker 
74*38e8c45fSAndroid Build Coastguard Worker class Hal {
75*38e8c45fSAndroid Build Coastguard Worker    public:
76*38e8c45fSAndroid Build Coastguard Worker     static bool Open();
77*38e8c45fSAndroid Build Coastguard Worker 
Get()78*38e8c45fSAndroid Build Coastguard Worker     static const Hal& Get() { return hal_; }
Device()79*38e8c45fSAndroid Build Coastguard Worker     static const hwvulkan_device_t& Device() { return *Get().dev_; }
80*38e8c45fSAndroid Build Coastguard Worker 
GetDebugReportIndex() const81*38e8c45fSAndroid Build Coastguard Worker     int GetDebugReportIndex() const { return debug_report_index_; }
82*38e8c45fSAndroid Build Coastguard Worker 
83*38e8c45fSAndroid Build Coastguard Worker    private:
Hal()84*38e8c45fSAndroid Build Coastguard Worker     Hal() : dev_(nullptr), debug_report_index_(-1) {}
85*38e8c45fSAndroid Build Coastguard Worker     Hal(const Hal&) = delete;
86*38e8c45fSAndroid Build Coastguard Worker     Hal& operator=(const Hal&) = delete;
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker     bool ShouldUnloadBuiltinDriver();
89*38e8c45fSAndroid Build Coastguard Worker     void UnloadBuiltinDriver();
90*38e8c45fSAndroid Build Coastguard Worker     bool InitDebugReportIndex();
91*38e8c45fSAndroid Build Coastguard Worker 
92*38e8c45fSAndroid Build Coastguard Worker     static Hal hal_;
93*38e8c45fSAndroid Build Coastguard Worker 
94*38e8c45fSAndroid Build Coastguard Worker     const hwvulkan_device_t* dev_;
95*38e8c45fSAndroid Build Coastguard Worker     int debug_report_index_;
96*38e8c45fSAndroid Build Coastguard Worker };
97*38e8c45fSAndroid Build Coastguard Worker 
98*38e8c45fSAndroid Build Coastguard Worker class CreateInfoWrapper {
99*38e8c45fSAndroid Build Coastguard Worker    public:
100*38e8c45fSAndroid Build Coastguard Worker     CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
101*38e8c45fSAndroid Build Coastguard Worker                       uint32_t icd_api_version,
102*38e8c45fSAndroid Build Coastguard Worker                       const VkAllocationCallbacks& allocator);
103*38e8c45fSAndroid Build Coastguard Worker     CreateInfoWrapper(VkPhysicalDevice physical_dev,
104*38e8c45fSAndroid Build Coastguard Worker                       const VkDeviceCreateInfo& create_info,
105*38e8c45fSAndroid Build Coastguard Worker                       uint32_t icd_api_version,
106*38e8c45fSAndroid Build Coastguard Worker                       const VkAllocationCallbacks& allocator);
107*38e8c45fSAndroid Build Coastguard Worker     ~CreateInfoWrapper();
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker     VkResult Validate();
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
112*38e8c45fSAndroid Build Coastguard Worker     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker     explicit operator const VkInstanceCreateInfo*() const;
115*38e8c45fSAndroid Build Coastguard Worker     explicit operator const VkDeviceCreateInfo*() const;
116*38e8c45fSAndroid Build Coastguard Worker 
117*38e8c45fSAndroid Build Coastguard Worker    private:
118*38e8c45fSAndroid Build Coastguard Worker     struct ExtensionFilter {
119*38e8c45fSAndroid Build Coastguard Worker         VkExtensionProperties* exts;
120*38e8c45fSAndroid Build Coastguard Worker         uint32_t ext_count;
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker         const char** names;
123*38e8c45fSAndroid Build Coastguard Worker         uint32_t name_count;
ExtensionFiltervulkan::driver::__anonc4de0b6f0111::CreateInfoWrapper::ExtensionFilter124*38e8c45fSAndroid Build Coastguard Worker         ExtensionFilter()
125*38e8c45fSAndroid Build Coastguard Worker             : exts(nullptr), ext_count(0), names(nullptr), name_count(0) {}
126*38e8c45fSAndroid Build Coastguard Worker     };
127*38e8c45fSAndroid Build Coastguard Worker 
128*38e8c45fSAndroid Build Coastguard Worker     VkResult SanitizeApiVersion();
129*38e8c45fSAndroid Build Coastguard Worker     VkResult SanitizePNext();
130*38e8c45fSAndroid Build Coastguard Worker     VkResult SanitizeLayers();
131*38e8c45fSAndroid Build Coastguard Worker     VkResult SanitizeExtensions();
132*38e8c45fSAndroid Build Coastguard Worker 
133*38e8c45fSAndroid Build Coastguard Worker     VkResult QueryExtensionCount(uint32_t& count) const;
134*38e8c45fSAndroid Build Coastguard Worker     VkResult EnumerateExtensions(uint32_t& count,
135*38e8c45fSAndroid Build Coastguard Worker                                  VkExtensionProperties* props) const;
136*38e8c45fSAndroid Build Coastguard Worker     VkResult InitExtensionFilter();
137*38e8c45fSAndroid Build Coastguard Worker     void FilterExtension(const char* name);
138*38e8c45fSAndroid Build Coastguard Worker 
139*38e8c45fSAndroid Build Coastguard Worker     const bool is_instance_;
140*38e8c45fSAndroid Build Coastguard Worker     const VkAllocationCallbacks& allocator_;
141*38e8c45fSAndroid Build Coastguard Worker     const uint32_t loader_api_version_;
142*38e8c45fSAndroid Build Coastguard Worker     const uint32_t icd_api_version_;
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physical_dev_;
145*38e8c45fSAndroid Build Coastguard Worker 
146*38e8c45fSAndroid Build Coastguard Worker     union {
147*38e8c45fSAndroid Build Coastguard Worker         VkInstanceCreateInfo instance_info_;
148*38e8c45fSAndroid Build Coastguard Worker         VkDeviceCreateInfo dev_info_;
149*38e8c45fSAndroid Build Coastguard Worker     };
150*38e8c45fSAndroid Build Coastguard Worker 
151*38e8c45fSAndroid Build Coastguard Worker     VkApplicationInfo application_info_;
152*38e8c45fSAndroid Build Coastguard Worker 
153*38e8c45fSAndroid Build Coastguard Worker     ExtensionFilter extension_filter_;
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
156*38e8c45fSAndroid Build Coastguard Worker     std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
157*38e8c45fSAndroid Build Coastguard Worker };
158*38e8c45fSAndroid Build Coastguard Worker 
159*38e8c45fSAndroid Build Coastguard Worker Hal Hal::hal_;
160*38e8c45fSAndroid Build Coastguard Worker 
161*38e8c45fSAndroid Build Coastguard Worker const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
162*38e8c45fSAndroid Build Coastguard Worker     "ro.hardware.vulkan",
163*38e8c45fSAndroid Build Coastguard Worker     "ro.board.platform",
164*38e8c45fSAndroid Build Coastguard Worker }};
165*38e8c45fSAndroid Build Coastguard Worker constexpr int LIB_DL_FLAGS = RTLD_LOCAL | RTLD_NOW;
166*38e8c45fSAndroid Build Coastguard Worker constexpr char RO_VULKAN_APEX_PROPERTY[] = "ro.vulkan.apex";
167*38e8c45fSAndroid Build Coastguard Worker 
168*38e8c45fSAndroid Build Coastguard Worker // LoadDriver returns:
169*38e8c45fSAndroid Build Coastguard Worker // * 0 when succeed, or
170*38e8c45fSAndroid Build Coastguard Worker // * -ENOENT when fail to open binary libraries, or
171*38e8c45fSAndroid Build Coastguard Worker // * -EINVAL when fail to find HAL_MODULE_INFO_SYM_AS_STR or
172*38e8c45fSAndroid Build Coastguard Worker //   HWVULKAN_HARDWARE_MODULE_ID in the library.
LoadDriver(android_namespace_t * library_namespace,const char * ns_name,const hwvulkan_module_t ** module)173*38e8c45fSAndroid Build Coastguard Worker int LoadDriver(android_namespace_t* library_namespace,
174*38e8c45fSAndroid Build Coastguard Worker                const char* ns_name,
175*38e8c45fSAndroid Build Coastguard Worker                const hwvulkan_module_t** module) {
176*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
177*38e8c45fSAndroid Build Coastguard Worker 
178*38e8c45fSAndroid Build Coastguard Worker     void* so = nullptr;
179*38e8c45fSAndroid Build Coastguard Worker     for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
180*38e8c45fSAndroid Build Coastguard Worker         std::string lib_name = android::base::GetProperty(key, "");
181*38e8c45fSAndroid Build Coastguard Worker         if (lib_name.empty())
182*38e8c45fSAndroid Build Coastguard Worker             continue;
183*38e8c45fSAndroid Build Coastguard Worker 
184*38e8c45fSAndroid Build Coastguard Worker         lib_name = "vulkan." + lib_name + ".so";
185*38e8c45fSAndroid Build Coastguard Worker         if (library_namespace) {
186*38e8c45fSAndroid Build Coastguard Worker             // load updated driver
187*38e8c45fSAndroid Build Coastguard Worker             const android_dlextinfo dlextinfo = {
188*38e8c45fSAndroid Build Coastguard Worker                 .flags = ANDROID_DLEXT_USE_NAMESPACE,
189*38e8c45fSAndroid Build Coastguard Worker                 .library_namespace = library_namespace,
190*38e8c45fSAndroid Build Coastguard Worker             };
191*38e8c45fSAndroid Build Coastguard Worker             so = android_dlopen_ext(lib_name.c_str(), LIB_DL_FLAGS, &dlextinfo);
192*38e8c45fSAndroid Build Coastguard Worker             if (!so) {
193*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Could not load %s from %s namespace: %s.",
194*38e8c45fSAndroid Build Coastguard Worker                       lib_name.c_str(), ns_name, dlerror());
195*38e8c45fSAndroid Build Coastguard Worker             }
196*38e8c45fSAndroid Build Coastguard Worker         } else {
197*38e8c45fSAndroid Build Coastguard Worker             // load built-in driver
198*38e8c45fSAndroid Build Coastguard Worker             so = android_load_sphal_library(lib_name.c_str(), LIB_DL_FLAGS);
199*38e8c45fSAndroid Build Coastguard Worker         }
200*38e8c45fSAndroid Build Coastguard Worker         if (so)
201*38e8c45fSAndroid Build Coastguard Worker             break;
202*38e8c45fSAndroid Build Coastguard Worker     }
203*38e8c45fSAndroid Build Coastguard Worker     if (!so)
204*38e8c45fSAndroid Build Coastguard Worker         return -ENOENT;
205*38e8c45fSAndroid Build Coastguard Worker 
206*38e8c45fSAndroid Build Coastguard Worker     auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
207*38e8c45fSAndroid Build Coastguard Worker     if (!hmi) {
208*38e8c45fSAndroid Build Coastguard Worker         ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
209*38e8c45fSAndroid Build Coastguard Worker         dlclose(so);
210*38e8c45fSAndroid Build Coastguard Worker         return -EINVAL;
211*38e8c45fSAndroid Build Coastguard Worker     }
212*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
213*38e8c45fSAndroid Build Coastguard Worker         ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
214*38e8c45fSAndroid Build Coastguard Worker         dlclose(so);
215*38e8c45fSAndroid Build Coastguard Worker         return -EINVAL;
216*38e8c45fSAndroid Build Coastguard Worker     }
217*38e8c45fSAndroid Build Coastguard Worker     hmi->dso = so;
218*38e8c45fSAndroid Build Coastguard Worker     *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
219*38e8c45fSAndroid Build Coastguard Worker     return 0;
220*38e8c45fSAndroid Build Coastguard Worker }
221*38e8c45fSAndroid Build Coastguard Worker 
LoadDriverFromApex(const hwvulkan_module_t ** module)222*38e8c45fSAndroid Build Coastguard Worker int LoadDriverFromApex(const hwvulkan_module_t** module) {
223*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
224*38e8c45fSAndroid Build Coastguard Worker 
225*38e8c45fSAndroid Build Coastguard Worker     auto apex_name = android::base::GetProperty(RO_VULKAN_APEX_PROPERTY, "");
226*38e8c45fSAndroid Build Coastguard Worker     if (apex_name == "") {
227*38e8c45fSAndroid Build Coastguard Worker         return -ENOENT;
228*38e8c45fSAndroid Build Coastguard Worker     }
229*38e8c45fSAndroid Build Coastguard Worker     // Get linker namespace for Vulkan APEX
230*38e8c45fSAndroid Build Coastguard Worker     std::replace(apex_name.begin(), apex_name.end(), '.', '_');
231*38e8c45fSAndroid Build Coastguard Worker     auto ns = android_get_exported_namespace(apex_name.c_str());
232*38e8c45fSAndroid Build Coastguard Worker     if (!ns) {
233*38e8c45fSAndroid Build Coastguard Worker         return -ENOENT;
234*38e8c45fSAndroid Build Coastguard Worker     }
235*38e8c45fSAndroid Build Coastguard Worker     android::GraphicsEnv::getInstance().setDriverToLoad(
236*38e8c45fSAndroid Build Coastguard Worker         android::GpuStatsInfo::Driver::VULKAN);
237*38e8c45fSAndroid Build Coastguard Worker     return LoadDriver(ns, apex_name.c_str(), module);
238*38e8c45fSAndroid Build Coastguard Worker }
239*38e8c45fSAndroid Build Coastguard Worker 
LoadBuiltinDriver(const hwvulkan_module_t ** module)240*38e8c45fSAndroid Build Coastguard Worker int LoadBuiltinDriver(const hwvulkan_module_t** module) {
241*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
242*38e8c45fSAndroid Build Coastguard Worker 
243*38e8c45fSAndroid Build Coastguard Worker     android::GraphicsEnv::getInstance().setDriverToLoad(
244*38e8c45fSAndroid Build Coastguard Worker         android::GpuStatsInfo::Driver::VULKAN);
245*38e8c45fSAndroid Build Coastguard Worker     return LoadDriver(nullptr, nullptr, module);
246*38e8c45fSAndroid Build Coastguard Worker }
247*38e8c45fSAndroid Build Coastguard Worker 
LoadUpdatedDriver(const hwvulkan_module_t ** module)248*38e8c45fSAndroid Build Coastguard Worker int LoadUpdatedDriver(const hwvulkan_module_t** module) {
249*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
250*38e8c45fSAndroid Build Coastguard Worker 
251*38e8c45fSAndroid Build Coastguard Worker     auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
252*38e8c45fSAndroid Build Coastguard Worker     if (!ns)
253*38e8c45fSAndroid Build Coastguard Worker         return -ENOENT;
254*38e8c45fSAndroid Build Coastguard Worker     android::GraphicsEnv::getInstance().setDriverToLoad(
255*38e8c45fSAndroid Build Coastguard Worker         android::GpuStatsInfo::Driver::VULKAN_UPDATED);
256*38e8c45fSAndroid Build Coastguard Worker     int result = LoadDriver(ns, "updatable gfx driver", module);
257*38e8c45fSAndroid Build Coastguard Worker     if (result != 0) {
258*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL(
259*38e8c45fSAndroid Build Coastguard Worker             "couldn't find an updated Vulkan implementation from %s",
260*38e8c45fSAndroid Build Coastguard Worker             android::GraphicsEnv::getInstance().getDriverPath().c_str());
261*38e8c45fSAndroid Build Coastguard Worker     }
262*38e8c45fSAndroid Build Coastguard Worker     return result;
263*38e8c45fSAndroid Build Coastguard Worker }
264*38e8c45fSAndroid Build Coastguard Worker 
Open()265*38e8c45fSAndroid Build Coastguard Worker bool Hal::Open() {
266*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
267*38e8c45fSAndroid Build Coastguard Worker 
268*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t openTime = systemTime();
269*38e8c45fSAndroid Build Coastguard Worker 
270*38e8c45fSAndroid Build Coastguard Worker     if (hal_.ShouldUnloadBuiltinDriver()) {
271*38e8c45fSAndroid Build Coastguard Worker         hal_.UnloadBuiltinDriver();
272*38e8c45fSAndroid Build Coastguard Worker     }
273*38e8c45fSAndroid Build Coastguard Worker 
274*38e8c45fSAndroid Build Coastguard Worker     if (hal_.dev_)
275*38e8c45fSAndroid Build Coastguard Worker         return true;
276*38e8c45fSAndroid Build Coastguard Worker 
277*38e8c45fSAndroid Build Coastguard Worker     // Use a stub device unless we successfully open a real HAL device.
278*38e8c45fSAndroid Build Coastguard Worker     hal_.dev_ = &stubhal::kDevice;
279*38e8c45fSAndroid Build Coastguard Worker 
280*38e8c45fSAndroid Build Coastguard Worker     int result;
281*38e8c45fSAndroid Build Coastguard Worker     const hwvulkan_module_t* module = nullptr;
282*38e8c45fSAndroid Build Coastguard Worker 
283*38e8c45fSAndroid Build Coastguard Worker     result = LoadUpdatedDriver(&module);
284*38e8c45fSAndroid Build Coastguard Worker     if (result == -ENOENT) {
285*38e8c45fSAndroid Build Coastguard Worker         result = LoadDriverFromApex(&module);
286*38e8c45fSAndroid Build Coastguard Worker     }
287*38e8c45fSAndroid Build Coastguard Worker     if (result == -ENOENT) {
288*38e8c45fSAndroid Build Coastguard Worker         result = LoadBuiltinDriver(&module);
289*38e8c45fSAndroid Build Coastguard Worker     }
290*38e8c45fSAndroid Build Coastguard Worker     if (result != 0) {
291*38e8c45fSAndroid Build Coastguard Worker         android::GraphicsEnv::getInstance().setDriverLoaded(
292*38e8c45fSAndroid Build Coastguard Worker             android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime);
293*38e8c45fSAndroid Build Coastguard Worker         ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
294*38e8c45fSAndroid Build Coastguard Worker         return true;
295*38e8c45fSAndroid Build Coastguard Worker     }
296*38e8c45fSAndroid Build Coastguard Worker 
297*38e8c45fSAndroid Build Coastguard Worker 
298*38e8c45fSAndroid Build Coastguard Worker     hwvulkan_device_t* device;
299*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("hwvulkan module open");
300*38e8c45fSAndroid Build Coastguard Worker     result =
301*38e8c45fSAndroid Build Coastguard Worker         module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
302*38e8c45fSAndroid Build Coastguard Worker                                      reinterpret_cast<hw_device_t**>(&device));
303*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
304*38e8c45fSAndroid Build Coastguard Worker     if (result != 0) {
305*38e8c45fSAndroid Build Coastguard Worker         android::GraphicsEnv::getInstance().setDriverLoaded(
306*38e8c45fSAndroid Build Coastguard Worker             android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime);
307*38e8c45fSAndroid Build Coastguard Worker         // Any device with a Vulkan HAL should be able to open the device.
308*38e8c45fSAndroid Build Coastguard Worker         ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
309*38e8c45fSAndroid Build Coastguard Worker               result);
310*38e8c45fSAndroid Build Coastguard Worker         return false;
311*38e8c45fSAndroid Build Coastguard Worker     }
312*38e8c45fSAndroid Build Coastguard Worker 
313*38e8c45fSAndroid Build Coastguard Worker     hal_.dev_ = device;
314*38e8c45fSAndroid Build Coastguard Worker 
315*38e8c45fSAndroid Build Coastguard Worker     hal_.InitDebugReportIndex();
316*38e8c45fSAndroid Build Coastguard Worker 
317*38e8c45fSAndroid Build Coastguard Worker     android::GraphicsEnv::getInstance().setDriverLoaded(
318*38e8c45fSAndroid Build Coastguard Worker         android::GpuStatsInfo::Api::API_VK, true, systemTime() - openTime);
319*38e8c45fSAndroid Build Coastguard Worker 
320*38e8c45fSAndroid Build Coastguard Worker     return true;
321*38e8c45fSAndroid Build Coastguard Worker }
322*38e8c45fSAndroid Build Coastguard Worker 
ShouldUnloadBuiltinDriver()323*38e8c45fSAndroid Build Coastguard Worker bool Hal::ShouldUnloadBuiltinDriver() {
324*38e8c45fSAndroid Build Coastguard Worker     // Should not unload since the driver was not loaded
325*38e8c45fSAndroid Build Coastguard Worker     if (!hal_.dev_)
326*38e8c45fSAndroid Build Coastguard Worker         return false;
327*38e8c45fSAndroid Build Coastguard Worker 
328*38e8c45fSAndroid Build Coastguard Worker     // Should not unload if stubhal is used on the device
329*38e8c45fSAndroid Build Coastguard Worker     if (hal_.dev_ == &stubhal::kDevice)
330*38e8c45fSAndroid Build Coastguard Worker         return false;
331*38e8c45fSAndroid Build Coastguard Worker 
332*38e8c45fSAndroid Build Coastguard Worker     // Unload the driver if updated driver is chosen
333*38e8c45fSAndroid Build Coastguard Worker     if (android::GraphicsEnv::getInstance().getDriverNamespace())
334*38e8c45fSAndroid Build Coastguard Worker         return true;
335*38e8c45fSAndroid Build Coastguard Worker 
336*38e8c45fSAndroid Build Coastguard Worker     return false;
337*38e8c45fSAndroid Build Coastguard Worker }
338*38e8c45fSAndroid Build Coastguard Worker 
UnloadBuiltinDriver()339*38e8c45fSAndroid Build Coastguard Worker void Hal::UnloadBuiltinDriver() {
340*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
341*38e8c45fSAndroid Build Coastguard Worker 
342*38e8c45fSAndroid Build Coastguard Worker     ALOGD("Unload builtin Vulkan driver.");
343*38e8c45fSAndroid Build Coastguard Worker 
344*38e8c45fSAndroid Build Coastguard Worker     if (hal_.dev_->common.close != nullptr)
345*38e8c45fSAndroid Build Coastguard Worker     {
346*38e8c45fSAndroid Build Coastguard Worker         // Close the opened device
347*38e8c45fSAndroid Build Coastguard Worker         int err = hal_.dev_->common.close(
348*38e8c45fSAndroid Build Coastguard Worker             const_cast<struct hw_device_t*>(&hal_.dev_->common));
349*38e8c45fSAndroid Build Coastguard Worker         ALOG_ASSERT(!err, "hw_device_t::close() failed.");
350*38e8c45fSAndroid Build Coastguard Worker     }
351*38e8c45fSAndroid Build Coastguard Worker 
352*38e8c45fSAndroid Build Coastguard Worker     // Close the opened shared library in the hw_module_t
353*38e8c45fSAndroid Build Coastguard Worker     android_unload_sphal_library(hal_.dev_->common.module->dso);
354*38e8c45fSAndroid Build Coastguard Worker 
355*38e8c45fSAndroid Build Coastguard Worker     hal_.dev_ = nullptr;
356*38e8c45fSAndroid Build Coastguard Worker     hal_.debug_report_index_ = -1;
357*38e8c45fSAndroid Build Coastguard Worker }
358*38e8c45fSAndroid Build Coastguard Worker 
InitDebugReportIndex()359*38e8c45fSAndroid Build Coastguard Worker bool Hal::InitDebugReportIndex() {
360*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
361*38e8c45fSAndroid Build Coastguard Worker 
362*38e8c45fSAndroid Build Coastguard Worker     uint32_t count;
363*38e8c45fSAndroid Build Coastguard Worker     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
364*38e8c45fSAndroid Build Coastguard Worker         VK_SUCCESS) {
365*38e8c45fSAndroid Build Coastguard Worker         ALOGE("failed to get HAL instance extension count");
366*38e8c45fSAndroid Build Coastguard Worker         return false;
367*38e8c45fSAndroid Build Coastguard Worker     }
368*38e8c45fSAndroid Build Coastguard Worker 
369*38e8c45fSAndroid Build Coastguard Worker     VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
370*38e8c45fSAndroid Build Coastguard Worker         malloc(sizeof(VkExtensionProperties) * count));
371*38e8c45fSAndroid Build Coastguard Worker     if (!exts) {
372*38e8c45fSAndroid Build Coastguard Worker         ALOGE("failed to allocate HAL instance extension array");
373*38e8c45fSAndroid Build Coastguard Worker         return false;
374*38e8c45fSAndroid Build Coastguard Worker     }
375*38e8c45fSAndroid Build Coastguard Worker 
376*38e8c45fSAndroid Build Coastguard Worker     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
377*38e8c45fSAndroid Build Coastguard Worker         VK_SUCCESS) {
378*38e8c45fSAndroid Build Coastguard Worker         ALOGE("failed to enumerate HAL instance extensions");
379*38e8c45fSAndroid Build Coastguard Worker         free(exts);
380*38e8c45fSAndroid Build Coastguard Worker         return false;
381*38e8c45fSAndroid Build Coastguard Worker     }
382*38e8c45fSAndroid Build Coastguard Worker 
383*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < count; i++) {
384*38e8c45fSAndroid Build Coastguard Worker         if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
385*38e8c45fSAndroid Build Coastguard Worker             0) {
386*38e8c45fSAndroid Build Coastguard Worker             debug_report_index_ = static_cast<int>(i);
387*38e8c45fSAndroid Build Coastguard Worker             break;
388*38e8c45fSAndroid Build Coastguard Worker         }
389*38e8c45fSAndroid Build Coastguard Worker     }
390*38e8c45fSAndroid Build Coastguard Worker 
391*38e8c45fSAndroid Build Coastguard Worker     free(exts);
392*38e8c45fSAndroid Build Coastguard Worker 
393*38e8c45fSAndroid Build Coastguard Worker     return true;
394*38e8c45fSAndroid Build Coastguard Worker }
395*38e8c45fSAndroid Build Coastguard Worker 
CreateInfoWrapper(const VkInstanceCreateInfo & create_info,uint32_t icd_api_version,const VkAllocationCallbacks & allocator)396*38e8c45fSAndroid Build Coastguard Worker CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
397*38e8c45fSAndroid Build Coastguard Worker                                      uint32_t icd_api_version,
398*38e8c45fSAndroid Build Coastguard Worker                                      const VkAllocationCallbacks& allocator)
399*38e8c45fSAndroid Build Coastguard Worker     : is_instance_(true),
400*38e8c45fSAndroid Build Coastguard Worker       allocator_(allocator),
401*38e8c45fSAndroid Build Coastguard Worker       loader_api_version_(flags::vulkan_1_4_instance_api() ? VK_API_VERSION_1_4 : VK_API_VERSION_1_3),
402*38e8c45fSAndroid Build Coastguard Worker       icd_api_version_(icd_api_version),
403*38e8c45fSAndroid Build Coastguard Worker       physical_dev_(VK_NULL_HANDLE),
404*38e8c45fSAndroid Build Coastguard Worker       instance_info_(create_info),
405*38e8c45fSAndroid Build Coastguard Worker       extension_filter_() {}
406*38e8c45fSAndroid Build Coastguard Worker 
CreateInfoWrapper(VkPhysicalDevice physical_dev,const VkDeviceCreateInfo & create_info,uint32_t icd_api_version,const VkAllocationCallbacks & allocator)407*38e8c45fSAndroid Build Coastguard Worker CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
408*38e8c45fSAndroid Build Coastguard Worker                                      const VkDeviceCreateInfo& create_info,
409*38e8c45fSAndroid Build Coastguard Worker                                      uint32_t icd_api_version,
410*38e8c45fSAndroid Build Coastguard Worker                                      const VkAllocationCallbacks& allocator)
411*38e8c45fSAndroid Build Coastguard Worker     : is_instance_(false),
412*38e8c45fSAndroid Build Coastguard Worker       allocator_(allocator),
413*38e8c45fSAndroid Build Coastguard Worker       loader_api_version_(flags::vulkan_1_4_instance_api() ? VK_API_VERSION_1_4 : VK_API_VERSION_1_3),
414*38e8c45fSAndroid Build Coastguard Worker       icd_api_version_(icd_api_version),
415*38e8c45fSAndroid Build Coastguard Worker       physical_dev_(physical_dev),
416*38e8c45fSAndroid Build Coastguard Worker       dev_info_(create_info),
417*38e8c45fSAndroid Build Coastguard Worker       extension_filter_() {}
418*38e8c45fSAndroid Build Coastguard Worker 
~CreateInfoWrapper()419*38e8c45fSAndroid Build Coastguard Worker CreateInfoWrapper::~CreateInfoWrapper() {
420*38e8c45fSAndroid Build Coastguard Worker     allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
421*38e8c45fSAndroid Build Coastguard Worker     allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
422*38e8c45fSAndroid Build Coastguard Worker }
423*38e8c45fSAndroid Build Coastguard Worker 
Validate()424*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInfoWrapper::Validate() {
425*38e8c45fSAndroid Build Coastguard Worker     VkResult result = SanitizeApiVersion();
426*38e8c45fSAndroid Build Coastguard Worker     if (result == VK_SUCCESS)
427*38e8c45fSAndroid Build Coastguard Worker         result = SanitizePNext();
428*38e8c45fSAndroid Build Coastguard Worker     if (result == VK_SUCCESS)
429*38e8c45fSAndroid Build Coastguard Worker         result = SanitizeLayers();
430*38e8c45fSAndroid Build Coastguard Worker     if (result == VK_SUCCESS)
431*38e8c45fSAndroid Build Coastguard Worker         result = SanitizeExtensions();
432*38e8c45fSAndroid Build Coastguard Worker 
433*38e8c45fSAndroid Build Coastguard Worker     return result;
434*38e8c45fSAndroid Build Coastguard Worker }
435*38e8c45fSAndroid Build Coastguard Worker 
436*38e8c45fSAndroid Build Coastguard Worker const std::bitset<ProcHook::EXTENSION_COUNT>&
GetHookExtensions() const437*38e8c45fSAndroid Build Coastguard Worker CreateInfoWrapper::GetHookExtensions() const {
438*38e8c45fSAndroid Build Coastguard Worker     return hook_extensions_;
439*38e8c45fSAndroid Build Coastguard Worker }
440*38e8c45fSAndroid Build Coastguard Worker 
441*38e8c45fSAndroid Build Coastguard Worker const std::bitset<ProcHook::EXTENSION_COUNT>&
GetHalExtensions() const442*38e8c45fSAndroid Build Coastguard Worker CreateInfoWrapper::GetHalExtensions() const {
443*38e8c45fSAndroid Build Coastguard Worker     return hal_extensions_;
444*38e8c45fSAndroid Build Coastguard Worker }
445*38e8c45fSAndroid Build Coastguard Worker 
operator const VkInstanceCreateInfo*() const446*38e8c45fSAndroid Build Coastguard Worker CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
447*38e8c45fSAndroid Build Coastguard Worker     return &instance_info_;
448*38e8c45fSAndroid Build Coastguard Worker }
449*38e8c45fSAndroid Build Coastguard Worker 
operator const VkDeviceCreateInfo*() const450*38e8c45fSAndroid Build Coastguard Worker CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
451*38e8c45fSAndroid Build Coastguard Worker     return &dev_info_;
452*38e8c45fSAndroid Build Coastguard Worker }
453*38e8c45fSAndroid Build Coastguard Worker 
SanitizeApiVersion()454*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInfoWrapper::SanitizeApiVersion() {
455*38e8c45fSAndroid Build Coastguard Worker     if (!is_instance_ || !instance_info_.pApplicationInfo)
456*38e8c45fSAndroid Build Coastguard Worker         return VK_SUCCESS;
457*38e8c45fSAndroid Build Coastguard Worker 
458*38e8c45fSAndroid Build Coastguard Worker     if (icd_api_version_ > VK_API_VERSION_1_0 ||
459*38e8c45fSAndroid Build Coastguard Worker         instance_info_.pApplicationInfo->apiVersion < VK_API_VERSION_1_1)
460*38e8c45fSAndroid Build Coastguard Worker         return VK_SUCCESS;
461*38e8c45fSAndroid Build Coastguard Worker 
462*38e8c45fSAndroid Build Coastguard Worker     // override apiVersion to avoid error return from 1.0 icd
463*38e8c45fSAndroid Build Coastguard Worker     application_info_ = *instance_info_.pApplicationInfo;
464*38e8c45fSAndroid Build Coastguard Worker     application_info_.apiVersion = VK_API_VERSION_1_0;
465*38e8c45fSAndroid Build Coastguard Worker     instance_info_.pApplicationInfo = &application_info_;
466*38e8c45fSAndroid Build Coastguard Worker 
467*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
468*38e8c45fSAndroid Build Coastguard Worker }
469*38e8c45fSAndroid Build Coastguard Worker 
SanitizePNext()470*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInfoWrapper::SanitizePNext() {
471*38e8c45fSAndroid Build Coastguard Worker     const struct StructHeader {
472*38e8c45fSAndroid Build Coastguard Worker         VkStructureType type;
473*38e8c45fSAndroid Build Coastguard Worker         const void* next;
474*38e8c45fSAndroid Build Coastguard Worker     } * header;
475*38e8c45fSAndroid Build Coastguard Worker 
476*38e8c45fSAndroid Build Coastguard Worker     if (is_instance_) {
477*38e8c45fSAndroid Build Coastguard Worker         header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
478*38e8c45fSAndroid Build Coastguard Worker 
479*38e8c45fSAndroid Build Coastguard Worker         // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
480*38e8c45fSAndroid Build Coastguard Worker         while (header &&
481*38e8c45fSAndroid Build Coastguard Worker                header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
482*38e8c45fSAndroid Build Coastguard Worker             header = reinterpret_cast<const StructHeader*>(header->next);
483*38e8c45fSAndroid Build Coastguard Worker 
484*38e8c45fSAndroid Build Coastguard Worker         instance_info_.pNext = header;
485*38e8c45fSAndroid Build Coastguard Worker     } else {
486*38e8c45fSAndroid Build Coastguard Worker         header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
487*38e8c45fSAndroid Build Coastguard Worker 
488*38e8c45fSAndroid Build Coastguard Worker         // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
489*38e8c45fSAndroid Build Coastguard Worker         while (header &&
490*38e8c45fSAndroid Build Coastguard Worker                header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
491*38e8c45fSAndroid Build Coastguard Worker             header = reinterpret_cast<const StructHeader*>(header->next);
492*38e8c45fSAndroid Build Coastguard Worker 
493*38e8c45fSAndroid Build Coastguard Worker         dev_info_.pNext = header;
494*38e8c45fSAndroid Build Coastguard Worker     }
495*38e8c45fSAndroid Build Coastguard Worker 
496*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
497*38e8c45fSAndroid Build Coastguard Worker }
498*38e8c45fSAndroid Build Coastguard Worker 
SanitizeLayers()499*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInfoWrapper::SanitizeLayers() {
500*38e8c45fSAndroid Build Coastguard Worker     auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
501*38e8c45fSAndroid Build Coastguard Worker                                        : dev_info_.ppEnabledLayerNames;
502*38e8c45fSAndroid Build Coastguard Worker     auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
503*38e8c45fSAndroid Build Coastguard Worker                                        : dev_info_.enabledLayerCount;
504*38e8c45fSAndroid Build Coastguard Worker 
505*38e8c45fSAndroid Build Coastguard Worker     // remove all layers
506*38e8c45fSAndroid Build Coastguard Worker     layer_names = nullptr;
507*38e8c45fSAndroid Build Coastguard Worker     layer_count = 0;
508*38e8c45fSAndroid Build Coastguard Worker 
509*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
510*38e8c45fSAndroid Build Coastguard Worker }
511*38e8c45fSAndroid Build Coastguard Worker 
SanitizeExtensions()512*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInfoWrapper::SanitizeExtensions() {
513*38e8c45fSAndroid Build Coastguard Worker     auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
514*38e8c45fSAndroid Build Coastguard Worker                                      : dev_info_.ppEnabledExtensionNames;
515*38e8c45fSAndroid Build Coastguard Worker     auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
516*38e8c45fSAndroid Build Coastguard Worker                                      : dev_info_.enabledExtensionCount;
517*38e8c45fSAndroid Build Coastguard Worker 
518*38e8c45fSAndroid Build Coastguard Worker     VkResult result = InitExtensionFilter();
519*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
520*38e8c45fSAndroid Build Coastguard Worker         return result;
521*38e8c45fSAndroid Build Coastguard Worker 
522*38e8c45fSAndroid Build Coastguard Worker     if (is_instance_ && icd_api_version_ < loader_api_version_) {
523*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < ext_count; i++) {
524*38e8c45fSAndroid Build Coastguard Worker             // Upon api downgrade, skip the promoted instance extensions in the
525*38e8c45fSAndroid Build Coastguard Worker             // first pass to avoid duplicate extensions.
526*38e8c45fSAndroid Build Coastguard Worker             const std::optional<uint32_t> version =
527*38e8c45fSAndroid Build Coastguard Worker                 GetInstanceExtensionPromotedVersion(ext_names[i]);
528*38e8c45fSAndroid Build Coastguard Worker             if (version && *version > icd_api_version_ &&
529*38e8c45fSAndroid Build Coastguard Worker                 *version <= loader_api_version_)
530*38e8c45fSAndroid Build Coastguard Worker                 continue;
531*38e8c45fSAndroid Build Coastguard Worker 
532*38e8c45fSAndroid Build Coastguard Worker             FilterExtension(ext_names[i]);
533*38e8c45fSAndroid Build Coastguard Worker         }
534*38e8c45fSAndroid Build Coastguard Worker 
535*38e8c45fSAndroid Build Coastguard Worker         // Enable the required extensions to support core functionalities.
536*38e8c45fSAndroid Build Coastguard Worker         const auto promoted_extensions = GetPromotedInstanceExtensions(
537*38e8c45fSAndroid Build Coastguard Worker             icd_api_version_, loader_api_version_);
538*38e8c45fSAndroid Build Coastguard Worker         for (const auto& promoted_extension : promoted_extensions)
539*38e8c45fSAndroid Build Coastguard Worker             FilterExtension(promoted_extension);
540*38e8c45fSAndroid Build Coastguard Worker     } else {
541*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < ext_count; i++)
542*38e8c45fSAndroid Build Coastguard Worker             FilterExtension(ext_names[i]);
543*38e8c45fSAndroid Build Coastguard Worker     }
544*38e8c45fSAndroid Build Coastguard Worker 
545*38e8c45fSAndroid Build Coastguard Worker     // Enable device extensions that contain physical-device commands, so that
546*38e8c45fSAndroid Build Coastguard Worker     // vkGetInstanceProcAddr will return those physical-device commands.
547*38e8c45fSAndroid Build Coastguard Worker     if (is_instance_) {
548*38e8c45fSAndroid Build Coastguard Worker         hook_extensions_.set(ProcHook::KHR_swapchain);
549*38e8c45fSAndroid Build Coastguard Worker     }
550*38e8c45fSAndroid Build Coastguard Worker 
551*38e8c45fSAndroid Build Coastguard Worker     const uint32_t api_version =
552*38e8c45fSAndroid Build Coastguard Worker         is_instance_ ? loader_api_version_
553*38e8c45fSAndroid Build Coastguard Worker                      : std::min(icd_api_version_, loader_api_version_);
554*38e8c45fSAndroid Build Coastguard Worker     switch (api_version) {
555*38e8c45fSAndroid Build Coastguard Worker         case VK_API_VERSION_1_4:
556*38e8c45fSAndroid Build Coastguard Worker             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_4);
557*38e8c45fSAndroid Build Coastguard Worker             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_4);
558*38e8c45fSAndroid Build Coastguard Worker             [[clang::fallthrough]];
559*38e8c45fSAndroid Build Coastguard Worker         case VK_API_VERSION_1_3:
560*38e8c45fSAndroid Build Coastguard Worker             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_3);
561*38e8c45fSAndroid Build Coastguard Worker             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_3);
562*38e8c45fSAndroid Build Coastguard Worker             [[clang::fallthrough]];
563*38e8c45fSAndroid Build Coastguard Worker         case VK_API_VERSION_1_2:
564*38e8c45fSAndroid Build Coastguard Worker             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_2);
565*38e8c45fSAndroid Build Coastguard Worker             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_2);
566*38e8c45fSAndroid Build Coastguard Worker             [[clang::fallthrough]];
567*38e8c45fSAndroid Build Coastguard Worker         case VK_API_VERSION_1_1:
568*38e8c45fSAndroid Build Coastguard Worker             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
569*38e8c45fSAndroid Build Coastguard Worker             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
570*38e8c45fSAndroid Build Coastguard Worker             [[clang::fallthrough]];
571*38e8c45fSAndroid Build Coastguard Worker         case VK_API_VERSION_1_0:
572*38e8c45fSAndroid Build Coastguard Worker             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
573*38e8c45fSAndroid Build Coastguard Worker             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
574*38e8c45fSAndroid Build Coastguard Worker             break;
575*38e8c45fSAndroid Build Coastguard Worker         default:
576*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Unknown API version[%u]", api_version);
577*38e8c45fSAndroid Build Coastguard Worker             break;
578*38e8c45fSAndroid Build Coastguard Worker     }
579*38e8c45fSAndroid Build Coastguard Worker 
580*38e8c45fSAndroid Build Coastguard Worker     ext_names = extension_filter_.names;
581*38e8c45fSAndroid Build Coastguard Worker     ext_count = extension_filter_.name_count;
582*38e8c45fSAndroid Build Coastguard Worker 
583*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
584*38e8c45fSAndroid Build Coastguard Worker }
585*38e8c45fSAndroid Build Coastguard Worker 
QueryExtensionCount(uint32_t & count) const586*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
587*38e8c45fSAndroid Build Coastguard Worker     if (is_instance_) {
588*38e8c45fSAndroid Build Coastguard Worker         return Hal::Device().EnumerateInstanceExtensionProperties(
589*38e8c45fSAndroid Build Coastguard Worker             nullptr, &count, nullptr);
590*38e8c45fSAndroid Build Coastguard Worker     } else {
591*38e8c45fSAndroid Build Coastguard Worker         const auto& driver = GetData(physical_dev_).driver;
592*38e8c45fSAndroid Build Coastguard Worker         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
593*38e8c45fSAndroid Build Coastguard Worker                                                          &count, nullptr);
594*38e8c45fSAndroid Build Coastguard Worker     }
595*38e8c45fSAndroid Build Coastguard Worker }
596*38e8c45fSAndroid Build Coastguard Worker 
EnumerateExtensions(uint32_t & count,VkExtensionProperties * props) const597*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInfoWrapper::EnumerateExtensions(
598*38e8c45fSAndroid Build Coastguard Worker     uint32_t& count,
599*38e8c45fSAndroid Build Coastguard Worker     VkExtensionProperties* props) const {
600*38e8c45fSAndroid Build Coastguard Worker     if (is_instance_) {
601*38e8c45fSAndroid Build Coastguard Worker         return Hal::Device().EnumerateInstanceExtensionProperties(
602*38e8c45fSAndroid Build Coastguard Worker             nullptr, &count, props);
603*38e8c45fSAndroid Build Coastguard Worker     } else {
604*38e8c45fSAndroid Build Coastguard Worker         const auto& driver = GetData(physical_dev_).driver;
605*38e8c45fSAndroid Build Coastguard Worker         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
606*38e8c45fSAndroid Build Coastguard Worker                                                          &count, props);
607*38e8c45fSAndroid Build Coastguard Worker     }
608*38e8c45fSAndroid Build Coastguard Worker }
609*38e8c45fSAndroid Build Coastguard Worker 
InitExtensionFilter()610*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInfoWrapper::InitExtensionFilter() {
611*38e8c45fSAndroid Build Coastguard Worker     // query extension count
612*38e8c45fSAndroid Build Coastguard Worker     uint32_t count;
613*38e8c45fSAndroid Build Coastguard Worker     VkResult result = QueryExtensionCount(count);
614*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS || count == 0)
615*38e8c45fSAndroid Build Coastguard Worker         return result;
616*38e8c45fSAndroid Build Coastguard Worker 
617*38e8c45fSAndroid Build Coastguard Worker     auto& filter = extension_filter_;
618*38e8c45fSAndroid Build Coastguard Worker     filter.exts =
619*38e8c45fSAndroid Build Coastguard Worker         reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
620*38e8c45fSAndroid Build Coastguard Worker             allocator_.pUserData, sizeof(VkExtensionProperties) * count,
621*38e8c45fSAndroid Build Coastguard Worker             alignof(VkExtensionProperties),
622*38e8c45fSAndroid Build Coastguard Worker             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
623*38e8c45fSAndroid Build Coastguard Worker     if (!filter.exts)
624*38e8c45fSAndroid Build Coastguard Worker         return VK_ERROR_OUT_OF_HOST_MEMORY;
625*38e8c45fSAndroid Build Coastguard Worker 
626*38e8c45fSAndroid Build Coastguard Worker     // enumerate extensions
627*38e8c45fSAndroid Build Coastguard Worker     result = EnumerateExtensions(count, filter.exts);
628*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS && result != VK_INCOMPLETE)
629*38e8c45fSAndroid Build Coastguard Worker         return result;
630*38e8c45fSAndroid Build Coastguard Worker 
631*38e8c45fSAndroid Build Coastguard Worker     if (!count)
632*38e8c45fSAndroid Build Coastguard Worker         return VK_SUCCESS;
633*38e8c45fSAndroid Build Coastguard Worker 
634*38e8c45fSAndroid Build Coastguard Worker     filter.ext_count = count;
635*38e8c45fSAndroid Build Coastguard Worker 
636*38e8c45fSAndroid Build Coastguard Worker     // allocate name array
637*38e8c45fSAndroid Build Coastguard Worker     if (is_instance_) {
638*38e8c45fSAndroid Build Coastguard Worker         uint32_t enabled_ext_count = instance_info_.enabledExtensionCount;
639*38e8c45fSAndroid Build Coastguard Worker 
640*38e8c45fSAndroid Build Coastguard Worker         // It requires enabling additional promoted extensions to downgrade api,
641*38e8c45fSAndroid Build Coastguard Worker         // so we reserve enough space here.
642*38e8c45fSAndroid Build Coastguard Worker         if (icd_api_version_ < loader_api_version_) {
643*38e8c45fSAndroid Build Coastguard Worker             enabled_ext_count += CountPromotedInstanceExtensions(
644*38e8c45fSAndroid Build Coastguard Worker                 icd_api_version_, loader_api_version_);
645*38e8c45fSAndroid Build Coastguard Worker         }
646*38e8c45fSAndroid Build Coastguard Worker 
647*38e8c45fSAndroid Build Coastguard Worker         count = std::min(filter.ext_count, enabled_ext_count);
648*38e8c45fSAndroid Build Coastguard Worker     } else {
649*38e8c45fSAndroid Build Coastguard Worker         count = std::min(filter.ext_count, dev_info_.enabledExtensionCount);
650*38e8c45fSAndroid Build Coastguard Worker     }
651*38e8c45fSAndroid Build Coastguard Worker 
652*38e8c45fSAndroid Build Coastguard Worker     if (!count)
653*38e8c45fSAndroid Build Coastguard Worker         return VK_SUCCESS;
654*38e8c45fSAndroid Build Coastguard Worker 
655*38e8c45fSAndroid Build Coastguard Worker     filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
656*38e8c45fSAndroid Build Coastguard Worker         allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
657*38e8c45fSAndroid Build Coastguard Worker         VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
658*38e8c45fSAndroid Build Coastguard Worker     if (!filter.names)
659*38e8c45fSAndroid Build Coastguard Worker         return VK_ERROR_OUT_OF_HOST_MEMORY;
660*38e8c45fSAndroid Build Coastguard Worker 
661*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
662*38e8c45fSAndroid Build Coastguard Worker }
663*38e8c45fSAndroid Build Coastguard Worker 
FilterExtension(const char * name)664*38e8c45fSAndroid Build Coastguard Worker void CreateInfoWrapper::FilterExtension(const char* name) {
665*38e8c45fSAndroid Build Coastguard Worker     auto& filter = extension_filter_;
666*38e8c45fSAndroid Build Coastguard Worker 
667*38e8c45fSAndroid Build Coastguard Worker     ProcHook::Extension ext_bit = GetProcHookExtension(name);
668*38e8c45fSAndroid Build Coastguard Worker     if (is_instance_) {
669*38e8c45fSAndroid Build Coastguard Worker         switch (ext_bit) {
670*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_android_surface:
671*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_surface:
672*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_surface_protected_capabilities:
673*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_swapchain_colorspace:
674*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_get_surface_capabilities2:
675*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::GOOGLE_surfaceless_query:
676*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_surface_maintenance1:
677*38e8c45fSAndroid Build Coastguard Worker                 hook_extensions_.set(ext_bit);
678*38e8c45fSAndroid Build Coastguard Worker                 // return now as these extensions do not require HAL support
679*38e8c45fSAndroid Build Coastguard Worker                 return;
680*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_debug_report:
681*38e8c45fSAndroid Build Coastguard Worker                 // both we and HAL can take part in
682*38e8c45fSAndroid Build Coastguard Worker                 hook_extensions_.set(ext_bit);
683*38e8c45fSAndroid Build Coastguard Worker                 break;
684*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_get_physical_device_properties2:
685*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_device_group_creation:
686*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_external_memory_capabilities:
687*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_external_semaphore_capabilities:
688*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_external_fence_capabilities:
689*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_UNKNOWN:
690*38e8c45fSAndroid Build Coastguard Worker                 // Extensions we don't need to do anything about at this level
691*38e8c45fSAndroid Build Coastguard Worker                 break;
692*38e8c45fSAndroid Build Coastguard Worker 
693*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_bind_memory2:
694*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_incremental_present:
695*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_shared_presentable_image:
696*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_swapchain:
697*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_swapchain_mutable_format:
698*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_hdr_metadata:
699*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_swapchain_maintenance1:
700*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::ANDROID_external_memory_android_hardware_buffer:
701*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::ANDROID_native_buffer:
702*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::GOOGLE_display_timing:
703*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_external_fence_fd:
704*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_0:
705*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_1:
706*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_2:
707*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_3:
708*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_4:
709*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_COUNT:
710*38e8c45fSAndroid Build Coastguard Worker                 // Device and meta extensions. If we ever get here it's a bug in
711*38e8c45fSAndroid Build Coastguard Worker                 // our code. But enumerating them lets us avoid having a default
712*38e8c45fSAndroid Build Coastguard Worker                 // case, and default hides other bugs.
713*38e8c45fSAndroid Build Coastguard Worker                 ALOGE(
714*38e8c45fSAndroid Build Coastguard Worker                     "CreateInfoWrapper::FilterExtension: invalid instance "
715*38e8c45fSAndroid Build Coastguard Worker                     "extension '%s'. FIX ME",
716*38e8c45fSAndroid Build Coastguard Worker                     name);
717*38e8c45fSAndroid Build Coastguard Worker                 return;
718*38e8c45fSAndroid Build Coastguard Worker 
719*38e8c45fSAndroid Build Coastguard Worker             // Don't use a default case. Without it, -Wswitch will tell us
720*38e8c45fSAndroid Build Coastguard Worker             // at compile time if someone adds a new ProcHook extension but
721*38e8c45fSAndroid Build Coastguard Worker             // doesn't handle it above. That's a real bug that has
722*38e8c45fSAndroid Build Coastguard Worker             // not-immediately-obvious effects.
723*38e8c45fSAndroid Build Coastguard Worker             //
724*38e8c45fSAndroid Build Coastguard Worker             // default:
725*38e8c45fSAndroid Build Coastguard Worker             //     break;
726*38e8c45fSAndroid Build Coastguard Worker         }
727*38e8c45fSAndroid Build Coastguard Worker     } else {
728*38e8c45fSAndroid Build Coastguard Worker         switch (ext_bit) {
729*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_swapchain:
730*38e8c45fSAndroid Build Coastguard Worker                 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
731*38e8c45fSAndroid Build Coastguard Worker                 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
732*38e8c45fSAndroid Build Coastguard Worker                 ext_bit = ProcHook::ANDROID_native_buffer;
733*38e8c45fSAndroid Build Coastguard Worker                 break;
734*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_incremental_present:
735*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_shared_presentable_image:
736*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::GOOGLE_display_timing:
737*38e8c45fSAndroid Build Coastguard Worker                 hook_extensions_.set(ext_bit);
738*38e8c45fSAndroid Build Coastguard Worker                 // return now as these extensions do not require HAL support
739*38e8c45fSAndroid Build Coastguard Worker                 return;
740*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_swapchain_maintenance1:
741*38e8c45fSAndroid Build Coastguard Worker                 // map VK_KHR_swapchain_maintenance1 to KHR_external_fence_fd
742*38e8c45fSAndroid Build Coastguard Worker                 name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
743*38e8c45fSAndroid Build Coastguard Worker                 ext_bit = ProcHook::KHR_external_fence_fd;
744*38e8c45fSAndroid Build Coastguard Worker                 break;
745*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_hdr_metadata:
746*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_bind_memory2:
747*38e8c45fSAndroid Build Coastguard Worker                 hook_extensions_.set(ext_bit);
748*38e8c45fSAndroid Build Coastguard Worker                 break;
749*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::ANDROID_external_memory_android_hardware_buffer:
750*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_external_fence_fd:
751*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_swapchain_mutable_format:
752*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_UNKNOWN:
753*38e8c45fSAndroid Build Coastguard Worker                 // Extensions we don't need to do anything about at this level
754*38e8c45fSAndroid Build Coastguard Worker                 break;
755*38e8c45fSAndroid Build Coastguard Worker 
756*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_android_surface:
757*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_get_physical_device_properties2:
758*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_device_group_creation:
759*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_external_memory_capabilities:
760*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_external_semaphore_capabilities:
761*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_external_fence_capabilities:
762*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_get_surface_capabilities2:
763*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_surface:
764*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::KHR_surface_protected_capabilities:
765*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_debug_report:
766*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_swapchain_colorspace:
767*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXT_surface_maintenance1:
768*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::GOOGLE_surfaceless_query:
769*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::ANDROID_native_buffer:
770*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_0:
771*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_1:
772*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_2:
773*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_3:
774*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_CORE_1_4:
775*38e8c45fSAndroid Build Coastguard Worker             case ProcHook::EXTENSION_COUNT:
776*38e8c45fSAndroid Build Coastguard Worker                 // Instance and meta extensions. If we ever get here it's a bug
777*38e8c45fSAndroid Build Coastguard Worker                 // in our code. But enumerating them lets us avoid having a
778*38e8c45fSAndroid Build Coastguard Worker                 // default case, and default hides other bugs.
779*38e8c45fSAndroid Build Coastguard Worker                 ALOGE(
780*38e8c45fSAndroid Build Coastguard Worker                     "CreateInfoWrapper::FilterExtension: invalid device "
781*38e8c45fSAndroid Build Coastguard Worker                     "extension '%s'. FIX ME",
782*38e8c45fSAndroid Build Coastguard Worker                     name);
783*38e8c45fSAndroid Build Coastguard Worker                 return;
784*38e8c45fSAndroid Build Coastguard Worker 
785*38e8c45fSAndroid Build Coastguard Worker             // Don't use a default case. Without it, -Wswitch will tell us
786*38e8c45fSAndroid Build Coastguard Worker             // at compile time if someone adds a new ProcHook extension but
787*38e8c45fSAndroid Build Coastguard Worker             // doesn't handle it above. That's a real bug that has
788*38e8c45fSAndroid Build Coastguard Worker             // not-immediately-obvious effects.
789*38e8c45fSAndroid Build Coastguard Worker             //
790*38e8c45fSAndroid Build Coastguard Worker             // default:
791*38e8c45fSAndroid Build Coastguard Worker             //     break;
792*38e8c45fSAndroid Build Coastguard Worker         }
793*38e8c45fSAndroid Build Coastguard Worker     }
794*38e8c45fSAndroid Build Coastguard Worker 
795*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < filter.ext_count; i++) {
796*38e8c45fSAndroid Build Coastguard Worker         const VkExtensionProperties& props = filter.exts[i];
797*38e8c45fSAndroid Build Coastguard Worker         // ignore unknown extensions
798*38e8c45fSAndroid Build Coastguard Worker         if (strcmp(name, props.extensionName) != 0)
799*38e8c45fSAndroid Build Coastguard Worker             continue;
800*38e8c45fSAndroid Build Coastguard Worker 
801*38e8c45fSAndroid Build Coastguard Worker         if (ext_bit != ProcHook::EXTENSION_UNKNOWN &&
802*38e8c45fSAndroid Build Coastguard Worker                 hal_extensions_.test(ext_bit)) {
803*38e8c45fSAndroid Build Coastguard Worker             ALOGI("CreateInfoWrapper::FilterExtension: already have '%s'.", name);
804*38e8c45fSAndroid Build Coastguard Worker             continue;
805*38e8c45fSAndroid Build Coastguard Worker         }
806*38e8c45fSAndroid Build Coastguard Worker 
807*38e8c45fSAndroid Build Coastguard Worker         // Ignore duplicate extensions (see: b/288929054)
808*38e8c45fSAndroid Build Coastguard Worker         bool duplicate_entry = false;
809*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t j = 0; j < filter.name_count; j++) {
810*38e8c45fSAndroid Build Coastguard Worker             if (strcmp(name, filter.names[j]) == 0) {
811*38e8c45fSAndroid Build Coastguard Worker                 duplicate_entry = true;
812*38e8c45fSAndroid Build Coastguard Worker                 break;
813*38e8c45fSAndroid Build Coastguard Worker             }
814*38e8c45fSAndroid Build Coastguard Worker         }
815*38e8c45fSAndroid Build Coastguard Worker         if (duplicate_entry == true)
816*38e8c45fSAndroid Build Coastguard Worker             continue;
817*38e8c45fSAndroid Build Coastguard Worker 
818*38e8c45fSAndroid Build Coastguard Worker         filter.names[filter.name_count++] = name;
819*38e8c45fSAndroid Build Coastguard Worker         if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
820*38e8c45fSAndroid Build Coastguard Worker             if (ext_bit == ProcHook::ANDROID_native_buffer)
821*38e8c45fSAndroid Build Coastguard Worker                 hook_extensions_.set(ProcHook::KHR_swapchain);
822*38e8c45fSAndroid Build Coastguard Worker             if (ext_bit == ProcHook::KHR_external_fence_fd)
823*38e8c45fSAndroid Build Coastguard Worker                 hook_extensions_.set(ProcHook::EXT_swapchain_maintenance1);
824*38e8c45fSAndroid Build Coastguard Worker 
825*38e8c45fSAndroid Build Coastguard Worker             hal_extensions_.set(ext_bit);
826*38e8c45fSAndroid Build Coastguard Worker         }
827*38e8c45fSAndroid Build Coastguard Worker 
828*38e8c45fSAndroid Build Coastguard Worker         break;
829*38e8c45fSAndroid Build Coastguard Worker     }
830*38e8c45fSAndroid Build Coastguard Worker }
831*38e8c45fSAndroid Build Coastguard Worker 
DefaultAllocate(void *,size_t size,size_t alignment,VkSystemAllocationScope)832*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR void* DefaultAllocate(void*,
833*38e8c45fSAndroid Build Coastguard Worker                                  size_t size,
834*38e8c45fSAndroid Build Coastguard Worker                                  size_t alignment,
835*38e8c45fSAndroid Build Coastguard Worker                                  VkSystemAllocationScope) {
836*38e8c45fSAndroid Build Coastguard Worker     void* ptr = nullptr;
837*38e8c45fSAndroid Build Coastguard Worker     // Vulkan requires 'alignment' to be a power of two, but posix_memalign
838*38e8c45fSAndroid Build Coastguard Worker     // additionally requires that it be at least sizeof(void*).
839*38e8c45fSAndroid Build Coastguard Worker     int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
840*38e8c45fSAndroid Build Coastguard Worker     ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
841*38e8c45fSAndroid Build Coastguard Worker                     ret, ptr);
842*38e8c45fSAndroid Build Coastguard Worker     return ret == 0 ? ptr : nullptr;
843*38e8c45fSAndroid Build Coastguard Worker }
844*38e8c45fSAndroid Build Coastguard Worker 
DefaultReallocate(void *,void * ptr,size_t size,size_t alignment,VkSystemAllocationScope)845*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR void* DefaultReallocate(void*,
846*38e8c45fSAndroid Build Coastguard Worker                                    void* ptr,
847*38e8c45fSAndroid Build Coastguard Worker                                    size_t size,
848*38e8c45fSAndroid Build Coastguard Worker                                    size_t alignment,
849*38e8c45fSAndroid Build Coastguard Worker                                    VkSystemAllocationScope) {
850*38e8c45fSAndroid Build Coastguard Worker     if (size == 0) {
851*38e8c45fSAndroid Build Coastguard Worker         free(ptr);
852*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
853*38e8c45fSAndroid Build Coastguard Worker     }
854*38e8c45fSAndroid Build Coastguard Worker 
855*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/143295633): Right now we never shrink allocations; if the new
856*38e8c45fSAndroid Build Coastguard Worker     // request is smaller than the existing chunk, we just continue using it.
857*38e8c45fSAndroid Build Coastguard Worker     // Right now the loader never reallocs, so this doesn't matter. If that
858*38e8c45fSAndroid Build Coastguard Worker     // changes, or if this code is copied into some other project, this should
859*38e8c45fSAndroid Build Coastguard Worker     // probably have a heuristic to allocate-copy-free when doing so will save
860*38e8c45fSAndroid Build Coastguard Worker     // "enough" space.
861*38e8c45fSAndroid Build Coastguard Worker     size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
862*38e8c45fSAndroid Build Coastguard Worker     if (size <= old_size)
863*38e8c45fSAndroid Build Coastguard Worker         return ptr;
864*38e8c45fSAndroid Build Coastguard Worker 
865*38e8c45fSAndroid Build Coastguard Worker     void* new_ptr = nullptr;
866*38e8c45fSAndroid Build Coastguard Worker     if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
867*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
868*38e8c45fSAndroid Build Coastguard Worker     if (ptr) {
869*38e8c45fSAndroid Build Coastguard Worker         memcpy(new_ptr, ptr, std::min(old_size, size));
870*38e8c45fSAndroid Build Coastguard Worker         free(ptr);
871*38e8c45fSAndroid Build Coastguard Worker     }
872*38e8c45fSAndroid Build Coastguard Worker     return new_ptr;
873*38e8c45fSAndroid Build Coastguard Worker }
874*38e8c45fSAndroid Build Coastguard Worker 
DefaultFree(void *,void * ptr)875*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR void DefaultFree(void*, void* ptr) {
876*38e8c45fSAndroid Build Coastguard Worker     ALOGD_CALLSTACK("Free: %p", ptr);
877*38e8c45fSAndroid Build Coastguard Worker     free(ptr);
878*38e8c45fSAndroid Build Coastguard Worker }
879*38e8c45fSAndroid Build Coastguard Worker 
AllocateInstanceData(const VkAllocationCallbacks & allocator)880*38e8c45fSAndroid Build Coastguard Worker InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
881*38e8c45fSAndroid Build Coastguard Worker     void* data_mem = allocator.pfnAllocation(
882*38e8c45fSAndroid Build Coastguard Worker         allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
883*38e8c45fSAndroid Build Coastguard Worker         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
884*38e8c45fSAndroid Build Coastguard Worker     if (!data_mem)
885*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
886*38e8c45fSAndroid Build Coastguard Worker 
887*38e8c45fSAndroid Build Coastguard Worker     return new (data_mem) InstanceData(allocator);
888*38e8c45fSAndroid Build Coastguard Worker }
889*38e8c45fSAndroid Build Coastguard Worker 
FreeInstanceData(InstanceData * data,const VkAllocationCallbacks & allocator)890*38e8c45fSAndroid Build Coastguard Worker void FreeInstanceData(InstanceData* data,
891*38e8c45fSAndroid Build Coastguard Worker                       const VkAllocationCallbacks& allocator) {
892*38e8c45fSAndroid Build Coastguard Worker     data->~InstanceData();
893*38e8c45fSAndroid Build Coastguard Worker     allocator.pfnFree(allocator.pUserData, data);
894*38e8c45fSAndroid Build Coastguard Worker }
895*38e8c45fSAndroid Build Coastguard Worker 
AllocateDeviceData(const VkAllocationCallbacks & allocator,const DebugReportCallbackList & debug_report_callbacks)896*38e8c45fSAndroid Build Coastguard Worker DeviceData* AllocateDeviceData(
897*38e8c45fSAndroid Build Coastguard Worker     const VkAllocationCallbacks& allocator,
898*38e8c45fSAndroid Build Coastguard Worker     const DebugReportCallbackList& debug_report_callbacks) {
899*38e8c45fSAndroid Build Coastguard Worker     void* data_mem = allocator.pfnAllocation(
900*38e8c45fSAndroid Build Coastguard Worker         allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
901*38e8c45fSAndroid Build Coastguard Worker         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
902*38e8c45fSAndroid Build Coastguard Worker     if (!data_mem)
903*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
904*38e8c45fSAndroid Build Coastguard Worker 
905*38e8c45fSAndroid Build Coastguard Worker     return new (data_mem) DeviceData(allocator, debug_report_callbacks);
906*38e8c45fSAndroid Build Coastguard Worker }
907*38e8c45fSAndroid Build Coastguard Worker 
FreeDeviceData(DeviceData * data,const VkAllocationCallbacks & allocator)908*38e8c45fSAndroid Build Coastguard Worker void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
909*38e8c45fSAndroid Build Coastguard Worker     data->~DeviceData();
910*38e8c45fSAndroid Build Coastguard Worker     allocator.pfnFree(allocator.pUserData, data);
911*38e8c45fSAndroid Build Coastguard Worker }
912*38e8c45fSAndroid Build Coastguard Worker 
913*38e8c45fSAndroid Build Coastguard Worker }  // anonymous namespace
914*38e8c45fSAndroid Build Coastguard Worker 
OpenHAL()915*38e8c45fSAndroid Build Coastguard Worker bool OpenHAL() {
916*38e8c45fSAndroid Build Coastguard Worker     return Hal::Open();
917*38e8c45fSAndroid Build Coastguard Worker }
918*38e8c45fSAndroid Build Coastguard Worker 
GetDefaultAllocator()919*38e8c45fSAndroid Build Coastguard Worker const VkAllocationCallbacks& GetDefaultAllocator() {
920*38e8c45fSAndroid Build Coastguard Worker     static const VkAllocationCallbacks kDefaultAllocCallbacks = {
921*38e8c45fSAndroid Build Coastguard Worker         .pUserData = nullptr,
922*38e8c45fSAndroid Build Coastguard Worker         .pfnAllocation = DefaultAllocate,
923*38e8c45fSAndroid Build Coastguard Worker         .pfnReallocation = DefaultReallocate,
924*38e8c45fSAndroid Build Coastguard Worker         .pfnFree = DefaultFree,
925*38e8c45fSAndroid Build Coastguard Worker     };
926*38e8c45fSAndroid Build Coastguard Worker 
927*38e8c45fSAndroid Build Coastguard Worker     return kDefaultAllocCallbacks;
928*38e8c45fSAndroid Build Coastguard Worker }
929*38e8c45fSAndroid Build Coastguard Worker 
GetInstanceProcAddr(VkInstance instance,const char * pName)930*38e8c45fSAndroid Build Coastguard Worker PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
931*38e8c45fSAndroid Build Coastguard Worker     const ProcHook* hook = GetProcHook(pName);
932*38e8c45fSAndroid Build Coastguard Worker     if (!hook)
933*38e8c45fSAndroid Build Coastguard Worker         return Hal::Device().GetInstanceProcAddr(instance, pName);
934*38e8c45fSAndroid Build Coastguard Worker 
935*38e8c45fSAndroid Build Coastguard Worker     if (!instance) {
936*38e8c45fSAndroid Build Coastguard Worker         if (hook->type == ProcHook::GLOBAL)
937*38e8c45fSAndroid Build Coastguard Worker             return hook->proc;
938*38e8c45fSAndroid Build Coastguard Worker 
939*38e8c45fSAndroid Build Coastguard Worker         // v0 layers expect
940*38e8c45fSAndroid Build Coastguard Worker         //
941*38e8c45fSAndroid Build Coastguard Worker         //   vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
942*38e8c45fSAndroid Build Coastguard Worker         //
943*38e8c45fSAndroid Build Coastguard Worker         // to work.
944*38e8c45fSAndroid Build Coastguard Worker         if (strcmp(pName, "vkCreateDevice") == 0)
945*38e8c45fSAndroid Build Coastguard Worker             return hook->proc;
946*38e8c45fSAndroid Build Coastguard Worker 
947*38e8c45fSAndroid Build Coastguard Worker         ALOGE(
948*38e8c45fSAndroid Build Coastguard Worker             "internal vkGetInstanceProcAddr called for %s without an instance",
949*38e8c45fSAndroid Build Coastguard Worker             pName);
950*38e8c45fSAndroid Build Coastguard Worker 
951*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
952*38e8c45fSAndroid Build Coastguard Worker     }
953*38e8c45fSAndroid Build Coastguard Worker 
954*38e8c45fSAndroid Build Coastguard Worker     PFN_vkVoidFunction proc;
955*38e8c45fSAndroid Build Coastguard Worker 
956*38e8c45fSAndroid Build Coastguard Worker     switch (hook->type) {
957*38e8c45fSAndroid Build Coastguard Worker         case ProcHook::INSTANCE:
958*38e8c45fSAndroid Build Coastguard Worker             proc = (GetData(instance).hook_extensions[hook->extension])
959*38e8c45fSAndroid Build Coastguard Worker                        ? hook->proc
960*38e8c45fSAndroid Build Coastguard Worker                        : nullptr;
961*38e8c45fSAndroid Build Coastguard Worker             break;
962*38e8c45fSAndroid Build Coastguard Worker         case ProcHook::DEVICE:
963*38e8c45fSAndroid Build Coastguard Worker             proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0)
964*38e8c45fSAndroid Build Coastguard Worker                        ? hook->proc
965*38e8c45fSAndroid Build Coastguard Worker                        : hook->checked_proc;
966*38e8c45fSAndroid Build Coastguard Worker             break;
967*38e8c45fSAndroid Build Coastguard Worker         default:
968*38e8c45fSAndroid Build Coastguard Worker             ALOGE(
969*38e8c45fSAndroid Build Coastguard Worker                 "internal vkGetInstanceProcAddr called for %s with an instance",
970*38e8c45fSAndroid Build Coastguard Worker                 pName);
971*38e8c45fSAndroid Build Coastguard Worker             proc = nullptr;
972*38e8c45fSAndroid Build Coastguard Worker             break;
973*38e8c45fSAndroid Build Coastguard Worker     }
974*38e8c45fSAndroid Build Coastguard Worker 
975*38e8c45fSAndroid Build Coastguard Worker     return proc;
976*38e8c45fSAndroid Build Coastguard Worker }
977*38e8c45fSAndroid Build Coastguard Worker 
GetDeviceProcAddr(VkDevice device,const char * pName)978*38e8c45fSAndroid Build Coastguard Worker PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
979*38e8c45fSAndroid Build Coastguard Worker     const ProcHook* hook = GetProcHook(pName);
980*38e8c45fSAndroid Build Coastguard Worker     PFN_vkVoidFunction drv_func = GetData(device).driver.GetDeviceProcAddr(device, pName);
981*38e8c45fSAndroid Build Coastguard Worker 
982*38e8c45fSAndroid Build Coastguard Worker     if (!hook)
983*38e8c45fSAndroid Build Coastguard Worker         return drv_func;
984*38e8c45fSAndroid Build Coastguard Worker 
985*38e8c45fSAndroid Build Coastguard Worker     if (hook->type != ProcHook::DEVICE) {
986*38e8c45fSAndroid Build Coastguard Worker         ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
987*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
988*38e8c45fSAndroid Build Coastguard Worker     }
989*38e8c45fSAndroid Build Coastguard Worker 
990*38e8c45fSAndroid Build Coastguard Worker     // Don't hook if we don't have a device entry function below for the core function.
991*38e8c45fSAndroid Build Coastguard Worker     if (!drv_func && (hook->extension >= ProcHook::EXTENSION_CORE_1_0))
992*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
993*38e8c45fSAndroid Build Coastguard Worker 
994*38e8c45fSAndroid Build Coastguard Worker     return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
995*38e8c45fSAndroid Build Coastguard Worker                                                               : nullptr;
996*38e8c45fSAndroid Build Coastguard Worker }
997*38e8c45fSAndroid Build Coastguard Worker 
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)998*38e8c45fSAndroid Build Coastguard Worker VkResult EnumerateInstanceExtensionProperties(
999*38e8c45fSAndroid Build Coastguard Worker     const char* pLayerName,
1000*38e8c45fSAndroid Build Coastguard Worker     uint32_t* pPropertyCount,
1001*38e8c45fSAndroid Build Coastguard Worker     VkExtensionProperties* pProperties) {
1002*38e8c45fSAndroid Build Coastguard Worker     std::vector<VkExtensionProperties> loader_extensions;
1003*38e8c45fSAndroid Build Coastguard Worker     loader_extensions.push_back(
1004*38e8c45fSAndroid Build Coastguard Worker         {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION});
1005*38e8c45fSAndroid Build Coastguard Worker     loader_extensions.push_back(
1006*38e8c45fSAndroid Build Coastguard Worker         {VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME,
1007*38e8c45fSAndroid Build Coastguard Worker          VK_KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION});
1008*38e8c45fSAndroid Build Coastguard Worker     loader_extensions.push_back({
1009*38e8c45fSAndroid Build Coastguard Worker         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
1010*38e8c45fSAndroid Build Coastguard Worker         VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
1011*38e8c45fSAndroid Build Coastguard Worker     loader_extensions.push_back({
1012*38e8c45fSAndroid Build Coastguard Worker         VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
1013*38e8c45fSAndroid Build Coastguard Worker         VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
1014*38e8c45fSAndroid Build Coastguard Worker     loader_extensions.push_back(
1015*38e8c45fSAndroid Build Coastguard Worker         {VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
1016*38e8c45fSAndroid Build Coastguard Worker          VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
1017*38e8c45fSAndroid Build Coastguard Worker     loader_extensions.push_back({VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME,
1018*38e8c45fSAndroid Build Coastguard Worker                                  VK_GOOGLE_SURFACELESS_QUERY_SPEC_VERSION});
1019*38e8c45fSAndroid Build Coastguard Worker     loader_extensions.push_back({
1020*38e8c45fSAndroid Build Coastguard Worker         VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME,
1021*38e8c45fSAndroid Build Coastguard Worker         VK_EXT_SURFACE_MAINTENANCE_1_SPEC_VERSION});
1022*38e8c45fSAndroid Build Coastguard Worker 
1023*38e8c45fSAndroid Build Coastguard Worker     static const VkExtensionProperties loader_debug_report_extension = {
1024*38e8c45fSAndroid Build Coastguard Worker         VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
1025*38e8c45fSAndroid Build Coastguard Worker     };
1026*38e8c45fSAndroid Build Coastguard Worker 
1027*38e8c45fSAndroid Build Coastguard Worker     // enumerate our extensions first
1028*38e8c45fSAndroid Build Coastguard Worker     if (!pLayerName && pProperties) {
1029*38e8c45fSAndroid Build Coastguard Worker         uint32_t count = std::min(
1030*38e8c45fSAndroid Build Coastguard Worker             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
1031*38e8c45fSAndroid Build Coastguard Worker 
1032*38e8c45fSAndroid Build Coastguard Worker         std::copy_n(loader_extensions.data(), count, pProperties);
1033*38e8c45fSAndroid Build Coastguard Worker 
1034*38e8c45fSAndroid Build Coastguard Worker         if (count < loader_extensions.size()) {
1035*38e8c45fSAndroid Build Coastguard Worker             *pPropertyCount = count;
1036*38e8c45fSAndroid Build Coastguard Worker             return VK_INCOMPLETE;
1037*38e8c45fSAndroid Build Coastguard Worker         }
1038*38e8c45fSAndroid Build Coastguard Worker 
1039*38e8c45fSAndroid Build Coastguard Worker         pProperties += count;
1040*38e8c45fSAndroid Build Coastguard Worker         *pPropertyCount -= count;
1041*38e8c45fSAndroid Build Coastguard Worker 
1042*38e8c45fSAndroid Build Coastguard Worker         if (Hal::Get().GetDebugReportIndex() < 0) {
1043*38e8c45fSAndroid Build Coastguard Worker             if (!*pPropertyCount) {
1044*38e8c45fSAndroid Build Coastguard Worker                 *pPropertyCount = count;
1045*38e8c45fSAndroid Build Coastguard Worker                 return VK_INCOMPLETE;
1046*38e8c45fSAndroid Build Coastguard Worker             }
1047*38e8c45fSAndroid Build Coastguard Worker 
1048*38e8c45fSAndroid Build Coastguard Worker             pProperties[0] = loader_debug_report_extension;
1049*38e8c45fSAndroid Build Coastguard Worker             pProperties += 1;
1050*38e8c45fSAndroid Build Coastguard Worker             *pPropertyCount -= 1;
1051*38e8c45fSAndroid Build Coastguard Worker         }
1052*38e8c45fSAndroid Build Coastguard Worker     }
1053*38e8c45fSAndroid Build Coastguard Worker 
1054*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
1055*38e8c45fSAndroid Build Coastguard Worker     VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
1056*38e8c45fSAndroid Build Coastguard Worker         pLayerName, pPropertyCount, pProperties);
1057*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
1058*38e8c45fSAndroid Build Coastguard Worker 
1059*38e8c45fSAndroid Build Coastguard Worker     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
1060*38e8c45fSAndroid Build Coastguard Worker         int idx = Hal::Get().GetDebugReportIndex();
1061*38e8c45fSAndroid Build Coastguard Worker         if (idx < 0) {
1062*38e8c45fSAndroid Build Coastguard Worker             *pPropertyCount += 1;
1063*38e8c45fSAndroid Build Coastguard Worker         } else if (pProperties &&
1064*38e8c45fSAndroid Build Coastguard Worker                    static_cast<uint32_t>(idx) < *pPropertyCount) {
1065*38e8c45fSAndroid Build Coastguard Worker             pProperties[idx].specVersion =
1066*38e8c45fSAndroid Build Coastguard Worker                 std::min(pProperties[idx].specVersion,
1067*38e8c45fSAndroid Build Coastguard Worker                          loader_debug_report_extension.specVersion);
1068*38e8c45fSAndroid Build Coastguard Worker         }
1069*38e8c45fSAndroid Build Coastguard Worker 
1070*38e8c45fSAndroid Build Coastguard Worker         *pPropertyCount += loader_extensions.size();
1071*38e8c45fSAndroid Build Coastguard Worker     }
1072*38e8c45fSAndroid Build Coastguard Worker 
1073*38e8c45fSAndroid Build Coastguard Worker     return result;
1074*38e8c45fSAndroid Build Coastguard Worker }
1075*38e8c45fSAndroid Build Coastguard Worker 
QueryPresentationProperties(VkPhysicalDevice physicalDevice,VkPhysicalDevicePresentationPropertiesANDROID * presentation_properties)1076*38e8c45fSAndroid Build Coastguard Worker void QueryPresentationProperties(
1077*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1078*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevicePresentationPropertiesANDROID* presentation_properties) {
1079*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1080*38e8c45fSAndroid Build Coastguard Worker 
1081*38e8c45fSAndroid Build Coastguard Worker     // Request the android-specific presentation properties via GPDP2
1082*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceProperties2 properties = {
1083*38e8c45fSAndroid Build Coastguard Worker         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1084*38e8c45fSAndroid Build Coastguard Worker         presentation_properties,
1085*38e8c45fSAndroid Build Coastguard Worker         {},
1086*38e8c45fSAndroid Build Coastguard Worker     };
1087*38e8c45fSAndroid Build Coastguard Worker 
1088*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
1089*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wold-style-cast"
1090*38e8c45fSAndroid Build Coastguard Worker     presentation_properties->sType =
1091*38e8c45fSAndroid Build Coastguard Worker         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
1092*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
1093*38e8c45fSAndroid Build Coastguard Worker     presentation_properties->pNext = nullptr;
1094*38e8c45fSAndroid Build Coastguard Worker     presentation_properties->sharedImage = VK_FALSE;
1095*38e8c45fSAndroid Build Coastguard Worker 
1096*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1097*38e8c45fSAndroid Build Coastguard Worker 
1098*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceProperties2) {
1099*38e8c45fSAndroid Build Coastguard Worker         // >= 1.1 driver, supports core GPDP2 entrypoint.
1100*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
1101*38e8c45fSAndroid Build Coastguard Worker     } else if (driver.GetPhysicalDeviceProperties2KHR) {
1102*38e8c45fSAndroid Build Coastguard Worker         // Old driver, but may support presentation properties
1103*38e8c45fSAndroid Build Coastguard Worker         // if we have the GPDP2 extension. Otherwise, no presentation
1104*38e8c45fSAndroid Build Coastguard Worker         // properties supported.
1105*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceProperties2KHR(physicalDevice, &properties);
1106*38e8c45fSAndroid Build Coastguard Worker     }
1107*38e8c45fSAndroid Build Coastguard Worker }
1108*38e8c45fSAndroid Build Coastguard Worker 
GetAndroidNativeBufferSpecVersion9Support(VkPhysicalDevice physicalDevice,bool & support)1109*38e8c45fSAndroid Build Coastguard Worker VkResult GetAndroidNativeBufferSpecVersion9Support(
1110*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1111*38e8c45fSAndroid Build Coastguard Worker     bool& support) {
1112*38e8c45fSAndroid Build Coastguard Worker     support = false;
1113*38e8c45fSAndroid Build Coastguard Worker 
1114*38e8c45fSAndroid Build Coastguard Worker     const InstanceData& data = GetData(physicalDevice);
1115*38e8c45fSAndroid Build Coastguard Worker 
1116*38e8c45fSAndroid Build Coastguard Worker     // Call to get propertyCount
1117*38e8c45fSAndroid Build Coastguard Worker     uint32_t propertyCount = 0;
1118*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
1119*38e8c45fSAndroid Build Coastguard Worker     VkResult result = data.driver.EnumerateDeviceExtensionProperties(
1120*38e8c45fSAndroid Build Coastguard Worker         physicalDevice, nullptr, &propertyCount, nullptr);
1121*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
1122*38e8c45fSAndroid Build Coastguard Worker 
1123*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
1124*38e8c45fSAndroid Build Coastguard Worker         return result;
1125*38e8c45fSAndroid Build Coastguard Worker     }
1126*38e8c45fSAndroid Build Coastguard Worker 
1127*38e8c45fSAndroid Build Coastguard Worker     // Call to enumerate properties
1128*38e8c45fSAndroid Build Coastguard Worker     std::vector<VkExtensionProperties> properties(propertyCount);
1129*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
1130*38e8c45fSAndroid Build Coastguard Worker     result = data.driver.EnumerateDeviceExtensionProperties(
1131*38e8c45fSAndroid Build Coastguard Worker         physicalDevice, nullptr, &propertyCount, properties.data());
1132*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
1133*38e8c45fSAndroid Build Coastguard Worker 
1134*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
1135*38e8c45fSAndroid Build Coastguard Worker         return result;
1136*38e8c45fSAndroid Build Coastguard Worker     }
1137*38e8c45fSAndroid Build Coastguard Worker 
1138*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < propertyCount; i++) {
1139*38e8c45fSAndroid Build Coastguard Worker         auto& prop = properties[i];
1140*38e8c45fSAndroid Build Coastguard Worker 
1141*38e8c45fSAndroid Build Coastguard Worker         if (strcmp(prop.extensionName,
1142*38e8c45fSAndroid Build Coastguard Worker                    VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
1143*38e8c45fSAndroid Build Coastguard Worker             continue;
1144*38e8c45fSAndroid Build Coastguard Worker 
1145*38e8c45fSAndroid Build Coastguard Worker         if (prop.specVersion >= 9) {
1146*38e8c45fSAndroid Build Coastguard Worker             support = true;
1147*38e8c45fSAndroid Build Coastguard Worker             return result;
1148*38e8c45fSAndroid Build Coastguard Worker         }
1149*38e8c45fSAndroid Build Coastguard Worker     }
1150*38e8c45fSAndroid Build Coastguard Worker 
1151*38e8c45fSAndroid Build Coastguard Worker     return result;
1152*38e8c45fSAndroid Build Coastguard Worker }
1153*38e8c45fSAndroid Build Coastguard Worker 
CanSupportSwapchainMaintenance1Extension(VkPhysicalDevice physicalDevice)1154*38e8c45fSAndroid Build Coastguard Worker bool CanSupportSwapchainMaintenance1Extension(VkPhysicalDevice physicalDevice) {
1155*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1156*38e8c45fSAndroid Build Coastguard Worker     if (!driver.GetPhysicalDeviceExternalFenceProperties)
1157*38e8c45fSAndroid Build Coastguard Worker         return false;
1158*38e8c45fSAndroid Build Coastguard Worker 
1159*38e8c45fSAndroid Build Coastguard Worker     // Requires support for external fences imported from sync fds.
1160*38e8c45fSAndroid Build Coastguard Worker     // This is _almost_ universal on Android, but may be missing on
1161*38e8c45fSAndroid Build Coastguard Worker     // some extremely old drivers, or on strange implementations like
1162*38e8c45fSAndroid Build Coastguard Worker     // cuttlefish.
1163*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceExternalFenceInfo fenceInfo = {
1164*38e8c45fSAndroid Build Coastguard Worker         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
1165*38e8c45fSAndroid Build Coastguard Worker         nullptr,
1166*38e8c45fSAndroid Build Coastguard Worker         VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
1167*38e8c45fSAndroid Build Coastguard Worker     };
1168*38e8c45fSAndroid Build Coastguard Worker     VkExternalFenceProperties fenceProperties = {
1169*38e8c45fSAndroid Build Coastguard Worker         VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
1170*38e8c45fSAndroid Build Coastguard Worker         nullptr,
1171*38e8c45fSAndroid Build Coastguard Worker         0, 0, 0
1172*38e8c45fSAndroid Build Coastguard Worker     };
1173*38e8c45fSAndroid Build Coastguard Worker 
1174*38e8c45fSAndroid Build Coastguard Worker     GetPhysicalDeviceExternalFenceProperties(physicalDevice, &fenceInfo, &fenceProperties);
1175*38e8c45fSAndroid Build Coastguard Worker     if (fenceProperties.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT)
1176*38e8c45fSAndroid Build Coastguard Worker         return true;
1177*38e8c45fSAndroid Build Coastguard Worker 
1178*38e8c45fSAndroid Build Coastguard Worker     return false;
1179*38e8c45fSAndroid Build Coastguard Worker }
1180*38e8c45fSAndroid Build Coastguard Worker 
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1181*38e8c45fSAndroid Build Coastguard Worker VkResult EnumerateDeviceExtensionProperties(
1182*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1183*38e8c45fSAndroid Build Coastguard Worker     const char* pLayerName,
1184*38e8c45fSAndroid Build Coastguard Worker     uint32_t* pPropertyCount,
1185*38e8c45fSAndroid Build Coastguard Worker     VkExtensionProperties* pProperties) {
1186*38e8c45fSAndroid Build Coastguard Worker     const InstanceData& data = GetData(physicalDevice);
1187*38e8c45fSAndroid Build Coastguard Worker     // extensions that are unconditionally exposed by the loader
1188*38e8c45fSAndroid Build Coastguard Worker     std::vector<VkExtensionProperties> loader_extensions;
1189*38e8c45fSAndroid Build Coastguard Worker     loader_extensions.push_back({
1190*38e8c45fSAndroid Build Coastguard Worker         VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
1191*38e8c45fSAndroid Build Coastguard Worker         VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
1192*38e8c45fSAndroid Build Coastguard Worker 
1193*38e8c45fSAndroid Build Coastguard Worker     bool hdrBoardConfig = android::sysprop::has_HDR_display(false);
1194*38e8c45fSAndroid Build Coastguard Worker     if (hdrBoardConfig) {
1195*38e8c45fSAndroid Build Coastguard Worker         loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
1196*38e8c45fSAndroid Build Coastguard Worker                                      VK_EXT_HDR_METADATA_SPEC_VERSION});
1197*38e8c45fSAndroid Build Coastguard Worker     }
1198*38e8c45fSAndroid Build Coastguard Worker 
1199*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
1200*38e8c45fSAndroid Build Coastguard Worker     QueryPresentationProperties(physicalDevice, &presentation_properties);
1201*38e8c45fSAndroid Build Coastguard Worker     if (presentation_properties.sharedImage) {
1202*38e8c45fSAndroid Build Coastguard Worker         loader_extensions.push_back({
1203*38e8c45fSAndroid Build Coastguard Worker             VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
1204*38e8c45fSAndroid Build Coastguard Worker             VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
1205*38e8c45fSAndroid Build Coastguard Worker     }
1206*38e8c45fSAndroid Build Coastguard Worker 
1207*38e8c45fSAndroid Build Coastguard Worker     // conditionally add VK_GOOGLE_display_timing if present timestamps are
1208*38e8c45fSAndroid Build Coastguard Worker     // supported by the driver:
1209*38e8c45fSAndroid Build Coastguard Worker     if (android::base::GetBoolProperty("service.sf.present_timestamp", false)) {
1210*38e8c45fSAndroid Build Coastguard Worker         loader_extensions.push_back({
1211*38e8c45fSAndroid Build Coastguard Worker                 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
1212*38e8c45fSAndroid Build Coastguard Worker                 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
1213*38e8c45fSAndroid Build Coastguard Worker     }
1214*38e8c45fSAndroid Build Coastguard Worker 
1215*38e8c45fSAndroid Build Coastguard Worker     // Conditionally add VK_EXT_IMAGE_COMPRESSION_CONTROL* if feature and ANB
1216*38e8c45fSAndroid Build Coastguard Worker     // support is provided by the driver
1217*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT
1218*38e8c45fSAndroid Build Coastguard Worker         swapchainCompFeats = {};
1219*38e8c45fSAndroid Build Coastguard Worker     swapchainCompFeats.sType =
1220*38e8c45fSAndroid Build Coastguard Worker         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT;
1221*38e8c45fSAndroid Build Coastguard Worker     swapchainCompFeats.pNext = nullptr;
1222*38e8c45fSAndroid Build Coastguard Worker     swapchainCompFeats.imageCompressionControlSwapchain = false;
1223*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceImageCompressionControlFeaturesEXT imageCompFeats = {};
1224*38e8c45fSAndroid Build Coastguard Worker     imageCompFeats.sType =
1225*38e8c45fSAndroid Build Coastguard Worker         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;
1226*38e8c45fSAndroid Build Coastguard Worker     imageCompFeats.pNext = &swapchainCompFeats;
1227*38e8c45fSAndroid Build Coastguard Worker     imageCompFeats.imageCompressionControl = false;
1228*38e8c45fSAndroid Build Coastguard Worker 
1229*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceFeatures2 feats2 = {};
1230*38e8c45fSAndroid Build Coastguard Worker     feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1231*38e8c45fSAndroid Build Coastguard Worker     feats2.pNext = &imageCompFeats;
1232*38e8c45fSAndroid Build Coastguard Worker 
1233*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1234*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceFeatures2 ||
1235*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceFeatures2KHR) {
1236*38e8c45fSAndroid Build Coastguard Worker         GetPhysicalDeviceFeatures2(physicalDevice, &feats2);
1237*38e8c45fSAndroid Build Coastguard Worker     }
1238*38e8c45fSAndroid Build Coastguard Worker 
1239*38e8c45fSAndroid Build Coastguard Worker     bool anb9 = false;
1240*38e8c45fSAndroid Build Coastguard Worker     VkResult result =
1241*38e8c45fSAndroid Build Coastguard Worker         GetAndroidNativeBufferSpecVersion9Support(physicalDevice, anb9);
1242*38e8c45fSAndroid Build Coastguard Worker 
1243*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
1244*38e8c45fSAndroid Build Coastguard Worker         return result;
1245*38e8c45fSAndroid Build Coastguard Worker     }
1246*38e8c45fSAndroid Build Coastguard Worker 
1247*38e8c45fSAndroid Build Coastguard Worker     if (anb9 && imageCompFeats.imageCompressionControl) {
1248*38e8c45fSAndroid Build Coastguard Worker         loader_extensions.push_back(
1249*38e8c45fSAndroid Build Coastguard Worker             {VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME,
1250*38e8c45fSAndroid Build Coastguard Worker              VK_EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION});
1251*38e8c45fSAndroid Build Coastguard Worker     }
1252*38e8c45fSAndroid Build Coastguard Worker     if (anb9 && swapchainCompFeats.imageCompressionControlSwapchain) {
1253*38e8c45fSAndroid Build Coastguard Worker         loader_extensions.push_back(
1254*38e8c45fSAndroid Build Coastguard Worker             {VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME,
1255*38e8c45fSAndroid Build Coastguard Worker              VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION});
1256*38e8c45fSAndroid Build Coastguard Worker     }
1257*38e8c45fSAndroid Build Coastguard Worker 
1258*38e8c45fSAndroid Build Coastguard Worker     if (CanSupportSwapchainMaintenance1Extension(physicalDevice)) {
1259*38e8c45fSAndroid Build Coastguard Worker         loader_extensions.push_back({
1260*38e8c45fSAndroid Build Coastguard Worker                 VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME,
1261*38e8c45fSAndroid Build Coastguard Worker                 VK_EXT_SWAPCHAIN_MAINTENANCE_1_SPEC_VERSION});
1262*38e8c45fSAndroid Build Coastguard Worker     }
1263*38e8c45fSAndroid Build Coastguard Worker 
1264*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceProperties pDeviceProperties;
1265*38e8c45fSAndroid Build Coastguard Worker     data.driver.GetPhysicalDeviceProperties(physicalDevice, &pDeviceProperties);
1266*38e8c45fSAndroid Build Coastguard Worker     if (flags::swapchain_mutable_format_ext() &&
1267*38e8c45fSAndroid Build Coastguard Worker         pDeviceProperties.apiVersion >= VK_API_VERSION_1_2) {
1268*38e8c45fSAndroid Build Coastguard Worker         loader_extensions.push_back(
1269*38e8c45fSAndroid Build Coastguard Worker             {VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME,
1270*38e8c45fSAndroid Build Coastguard Worker              VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION});
1271*38e8c45fSAndroid Build Coastguard Worker     }
1272*38e8c45fSAndroid Build Coastguard Worker 
1273*38e8c45fSAndroid Build Coastguard Worker     // enumerate our extensions first
1274*38e8c45fSAndroid Build Coastguard Worker     if (!pLayerName && pProperties) {
1275*38e8c45fSAndroid Build Coastguard Worker         uint32_t count = std::min(
1276*38e8c45fSAndroid Build Coastguard Worker             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
1277*38e8c45fSAndroid Build Coastguard Worker 
1278*38e8c45fSAndroid Build Coastguard Worker         std::copy_n(loader_extensions.data(), count, pProperties);
1279*38e8c45fSAndroid Build Coastguard Worker 
1280*38e8c45fSAndroid Build Coastguard Worker         if (count < loader_extensions.size()) {
1281*38e8c45fSAndroid Build Coastguard Worker             *pPropertyCount = count;
1282*38e8c45fSAndroid Build Coastguard Worker             return VK_INCOMPLETE;
1283*38e8c45fSAndroid Build Coastguard Worker         }
1284*38e8c45fSAndroid Build Coastguard Worker 
1285*38e8c45fSAndroid Build Coastguard Worker         pProperties += count;
1286*38e8c45fSAndroid Build Coastguard Worker         *pPropertyCount -= count;
1287*38e8c45fSAndroid Build Coastguard Worker     }
1288*38e8c45fSAndroid Build Coastguard Worker 
1289*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
1290*38e8c45fSAndroid Build Coastguard Worker     result = data.driver.EnumerateDeviceExtensionProperties(
1291*38e8c45fSAndroid Build Coastguard Worker         physicalDevice, pLayerName, pPropertyCount, pProperties);
1292*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
1293*38e8c45fSAndroid Build Coastguard Worker 
1294*38e8c45fSAndroid Build Coastguard Worker     if (pProperties) {
1295*38e8c45fSAndroid Build Coastguard Worker         // map VK_ANDROID_native_buffer to VK_KHR_swapchain
1296*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < *pPropertyCount; i++) {
1297*38e8c45fSAndroid Build Coastguard Worker             auto& prop = pProperties[i];
1298*38e8c45fSAndroid Build Coastguard Worker 
1299*38e8c45fSAndroid Build Coastguard Worker             if (strcmp(prop.extensionName,
1300*38e8c45fSAndroid Build Coastguard Worker                        VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
1301*38e8c45fSAndroid Build Coastguard Worker                 continue;
1302*38e8c45fSAndroid Build Coastguard Worker 
1303*38e8c45fSAndroid Build Coastguard Worker             memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
1304*38e8c45fSAndroid Build Coastguard Worker                    sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
1305*38e8c45fSAndroid Build Coastguard Worker 
1306*38e8c45fSAndroid Build Coastguard Worker             if (prop.specVersion >= 8) {
1307*38e8c45fSAndroid Build Coastguard Worker                 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
1308*38e8c45fSAndroid Build Coastguard Worker             } else {
1309*38e8c45fSAndroid Build Coastguard Worker                 prop.specVersion = 68;
1310*38e8c45fSAndroid Build Coastguard Worker             }
1311*38e8c45fSAndroid Build Coastguard Worker         }
1312*38e8c45fSAndroid Build Coastguard Worker     }
1313*38e8c45fSAndroid Build Coastguard Worker 
1314*38e8c45fSAndroid Build Coastguard Worker     // restore loader extension count
1315*38e8c45fSAndroid Build Coastguard Worker     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
1316*38e8c45fSAndroid Build Coastguard Worker         *pPropertyCount += loader_extensions.size();
1317*38e8c45fSAndroid Build Coastguard Worker     }
1318*38e8c45fSAndroid Build Coastguard Worker 
1319*38e8c45fSAndroid Build Coastguard Worker     return result;
1320*38e8c45fSAndroid Build Coastguard Worker }
1321*38e8c45fSAndroid Build Coastguard Worker 
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)1322*38e8c45fSAndroid Build Coastguard Worker VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1323*38e8c45fSAndroid Build Coastguard Worker                         const VkAllocationCallbacks* pAllocator,
1324*38e8c45fSAndroid Build Coastguard Worker                         VkInstance* pInstance) {
1325*38e8c45fSAndroid Build Coastguard Worker     const VkAllocationCallbacks& data_allocator =
1326*38e8c45fSAndroid Build Coastguard Worker         (pAllocator) ? *pAllocator : GetDefaultAllocator();
1327*38e8c45fSAndroid Build Coastguard Worker 
1328*38e8c45fSAndroid Build Coastguard Worker     VkResult result = VK_SUCCESS;
1329*38e8c45fSAndroid Build Coastguard Worker     uint32_t icd_api_version = VK_API_VERSION_1_0;
1330*38e8c45fSAndroid Build Coastguard Worker     PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
1331*38e8c45fSAndroid Build Coastguard Worker         reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
1332*38e8c45fSAndroid Build Coastguard Worker             Hal::Device().GetInstanceProcAddr(nullptr,
1333*38e8c45fSAndroid Build Coastguard Worker                                               "vkEnumerateInstanceVersion"));
1334*38e8c45fSAndroid Build Coastguard Worker     if (pfn_enumerate_instance_version) {
1335*38e8c45fSAndroid Build Coastguard Worker         ATRACE_BEGIN("pfn_enumerate_instance_version");
1336*38e8c45fSAndroid Build Coastguard Worker         result = (*pfn_enumerate_instance_version)(&icd_api_version);
1337*38e8c45fSAndroid Build Coastguard Worker         ATRACE_END();
1338*38e8c45fSAndroid Build Coastguard Worker         if (result != VK_SUCCESS)
1339*38e8c45fSAndroid Build Coastguard Worker             return result;
1340*38e8c45fSAndroid Build Coastguard Worker 
1341*38e8c45fSAndroid Build Coastguard Worker         icd_api_version ^= VK_API_VERSION_PATCH(icd_api_version);
1342*38e8c45fSAndroid Build Coastguard Worker     }
1343*38e8c45fSAndroid Build Coastguard Worker 
1344*38e8c45fSAndroid Build Coastguard Worker     CreateInfoWrapper wrapper(*pCreateInfo, icd_api_version, data_allocator);
1345*38e8c45fSAndroid Build Coastguard Worker     result = wrapper.Validate();
1346*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
1347*38e8c45fSAndroid Build Coastguard Worker         return result;
1348*38e8c45fSAndroid Build Coastguard Worker 
1349*38e8c45fSAndroid Build Coastguard Worker     InstanceData* data = AllocateInstanceData(data_allocator);
1350*38e8c45fSAndroid Build Coastguard Worker     if (!data)
1351*38e8c45fSAndroid Build Coastguard Worker         return VK_ERROR_OUT_OF_HOST_MEMORY;
1352*38e8c45fSAndroid Build Coastguard Worker 
1353*38e8c45fSAndroid Build Coastguard Worker     data->hook_extensions |= wrapper.GetHookExtensions();
1354*38e8c45fSAndroid Build Coastguard Worker 
1355*38e8c45fSAndroid Build Coastguard Worker     // call into the driver
1356*38e8c45fSAndroid Build Coastguard Worker     VkInstance instance;
1357*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("driver.CreateInstance");
1358*38e8c45fSAndroid Build Coastguard Worker     result = Hal::Device().CreateInstance(
1359*38e8c45fSAndroid Build Coastguard Worker         static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
1360*38e8c45fSAndroid Build Coastguard Worker         &instance);
1361*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
1362*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS) {
1363*38e8c45fSAndroid Build Coastguard Worker         FreeInstanceData(data, data_allocator);
1364*38e8c45fSAndroid Build Coastguard Worker         return result;
1365*38e8c45fSAndroid Build Coastguard Worker     }
1366*38e8c45fSAndroid Build Coastguard Worker 
1367*38e8c45fSAndroid Build Coastguard Worker     // initialize InstanceDriverTable
1368*38e8c45fSAndroid Build Coastguard Worker     if (!SetData(instance, *data) ||
1369*38e8c45fSAndroid Build Coastguard Worker         !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
1370*38e8c45fSAndroid Build Coastguard Worker                          wrapper.GetHalExtensions())) {
1371*38e8c45fSAndroid Build Coastguard Worker         data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
1372*38e8c45fSAndroid Build Coastguard Worker             Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
1373*38e8c45fSAndroid Build Coastguard Worker         if (data->driver.DestroyInstance)
1374*38e8c45fSAndroid Build Coastguard Worker             data->driver.DestroyInstance(instance, pAllocator);
1375*38e8c45fSAndroid Build Coastguard Worker 
1376*38e8c45fSAndroid Build Coastguard Worker         FreeInstanceData(data, data_allocator);
1377*38e8c45fSAndroid Build Coastguard Worker 
1378*38e8c45fSAndroid Build Coastguard Worker         return VK_ERROR_INCOMPATIBLE_DRIVER;
1379*38e8c45fSAndroid Build Coastguard Worker     }
1380*38e8c45fSAndroid Build Coastguard Worker 
1381*38e8c45fSAndroid Build Coastguard Worker     data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
1382*38e8c45fSAndroid Build Coastguard Worker         Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
1383*38e8c45fSAndroid Build Coastguard Worker     if (!data->get_device_proc_addr) {
1384*38e8c45fSAndroid Build Coastguard Worker         data->driver.DestroyInstance(instance, pAllocator);
1385*38e8c45fSAndroid Build Coastguard Worker         FreeInstanceData(data, data_allocator);
1386*38e8c45fSAndroid Build Coastguard Worker 
1387*38e8c45fSAndroid Build Coastguard Worker         return VK_ERROR_INCOMPATIBLE_DRIVER;
1388*38e8c45fSAndroid Build Coastguard Worker     }
1389*38e8c45fSAndroid Build Coastguard Worker 
1390*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/259516419) avoid getting stats from hwui
1391*38e8c45fSAndroid Build Coastguard Worker     // const bool reportStats = (pCreateInfo->pApplicationInfo == nullptr )
1392*38e8c45fSAndroid Build Coastguard Worker     //         || (strcmp("android framework",
1393*38e8c45fSAndroid Build Coastguard Worker     //         pCreateInfo->pApplicationInfo->pEngineName) != 0);
1394*38e8c45fSAndroid Build Coastguard Worker     const bool reportStats = true;
1395*38e8c45fSAndroid Build Coastguard Worker     if (reportStats) {
1396*38e8c45fSAndroid Build Coastguard Worker         // Set stats for Vulkan api version requested with application info
1397*38e8c45fSAndroid Build Coastguard Worker         if (pCreateInfo->pApplicationInfo) {
1398*38e8c45fSAndroid Build Coastguard Worker             const uint32_t vulkanApiVersion =
1399*38e8c45fSAndroid Build Coastguard Worker                 pCreateInfo->pApplicationInfo->apiVersion;
1400*38e8c45fSAndroid Build Coastguard Worker             android::GraphicsEnv::getInstance().setTargetStats(
1401*38e8c45fSAndroid Build Coastguard Worker                 android::GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION,
1402*38e8c45fSAndroid Build Coastguard Worker                 vulkanApiVersion);
1403*38e8c45fSAndroid Build Coastguard Worker 
1404*38e8c45fSAndroid Build Coastguard Worker             if (pCreateInfo->pApplicationInfo->pEngineName) {
1405*38e8c45fSAndroid Build Coastguard Worker                 android::GraphicsEnv::getInstance().addVulkanEngineName(
1406*38e8c45fSAndroid Build Coastguard Worker                     pCreateInfo->pApplicationInfo->pEngineName);
1407*38e8c45fSAndroid Build Coastguard Worker             }
1408*38e8c45fSAndroid Build Coastguard Worker         }
1409*38e8c45fSAndroid Build Coastguard Worker 
1410*38e8c45fSAndroid Build Coastguard Worker         // Update stats for the extensions requested
1411*38e8c45fSAndroid Build Coastguard Worker         android::GraphicsEnv::getInstance().setVulkanInstanceExtensions(
1412*38e8c45fSAndroid Build Coastguard Worker             pCreateInfo->enabledExtensionCount,
1413*38e8c45fSAndroid Build Coastguard Worker             pCreateInfo->ppEnabledExtensionNames);
1414*38e8c45fSAndroid Build Coastguard Worker     }
1415*38e8c45fSAndroid Build Coastguard Worker 
1416*38e8c45fSAndroid Build Coastguard Worker     *pInstance = instance;
1417*38e8c45fSAndroid Build Coastguard Worker 
1418*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
1419*38e8c45fSAndroid Build Coastguard Worker }
1420*38e8c45fSAndroid Build Coastguard Worker 
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)1421*38e8c45fSAndroid Build Coastguard Worker void DestroyInstance(VkInstance instance,
1422*38e8c45fSAndroid Build Coastguard Worker                      const VkAllocationCallbacks* pAllocator) {
1423*38e8c45fSAndroid Build Coastguard Worker     InstanceData& data = GetData(instance);
1424*38e8c45fSAndroid Build Coastguard Worker     data.driver.DestroyInstance(instance, pAllocator);
1425*38e8c45fSAndroid Build Coastguard Worker 
1426*38e8c45fSAndroid Build Coastguard Worker     VkAllocationCallbacks local_allocator;
1427*38e8c45fSAndroid Build Coastguard Worker     if (!pAllocator) {
1428*38e8c45fSAndroid Build Coastguard Worker         local_allocator = data.allocator;
1429*38e8c45fSAndroid Build Coastguard Worker         pAllocator = &local_allocator;
1430*38e8c45fSAndroid Build Coastguard Worker     }
1431*38e8c45fSAndroid Build Coastguard Worker 
1432*38e8c45fSAndroid Build Coastguard Worker     FreeInstanceData(&data, *pAllocator);
1433*38e8c45fSAndroid Build Coastguard Worker }
1434*38e8c45fSAndroid Build Coastguard Worker 
CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1435*38e8c45fSAndroid Build Coastguard Worker VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1436*38e8c45fSAndroid Build Coastguard Worker                       const VkDeviceCreateInfo* pCreateInfo,
1437*38e8c45fSAndroid Build Coastguard Worker                       const VkAllocationCallbacks* pAllocator,
1438*38e8c45fSAndroid Build Coastguard Worker                       VkDevice* pDevice) {
1439*38e8c45fSAndroid Build Coastguard Worker     const InstanceData& instance_data = GetData(physicalDevice);
1440*38e8c45fSAndroid Build Coastguard Worker     const VkAllocationCallbacks& data_allocator =
1441*38e8c45fSAndroid Build Coastguard Worker         (pAllocator) ? *pAllocator : instance_data.allocator;
1442*38e8c45fSAndroid Build Coastguard Worker 
1443*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceProperties properties;
1444*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
1445*38e8c45fSAndroid Build Coastguard Worker     instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1446*38e8c45fSAndroid Build Coastguard Worker                                                      &properties);
1447*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
1448*38e8c45fSAndroid Build Coastguard Worker 
1449*38e8c45fSAndroid Build Coastguard Worker     CreateInfoWrapper wrapper(
1450*38e8c45fSAndroid Build Coastguard Worker         physicalDevice, *pCreateInfo,
1451*38e8c45fSAndroid Build Coastguard Worker         properties.apiVersion ^ VK_API_VERSION_PATCH(properties.apiVersion),
1452*38e8c45fSAndroid Build Coastguard Worker         data_allocator);
1453*38e8c45fSAndroid Build Coastguard Worker     VkResult result = wrapper.Validate();
1454*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
1455*38e8c45fSAndroid Build Coastguard Worker         return result;
1456*38e8c45fSAndroid Build Coastguard Worker 
1457*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("AllocateDeviceData");
1458*38e8c45fSAndroid Build Coastguard Worker     DeviceData* data = AllocateDeviceData(data_allocator,
1459*38e8c45fSAndroid Build Coastguard Worker                                           instance_data.debug_report_callbacks);
1460*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
1461*38e8c45fSAndroid Build Coastguard Worker     if (!data)
1462*38e8c45fSAndroid Build Coastguard Worker         return VK_ERROR_OUT_OF_HOST_MEMORY;
1463*38e8c45fSAndroid Build Coastguard Worker 
1464*38e8c45fSAndroid Build Coastguard Worker     data->hook_extensions |= wrapper.GetHookExtensions();
1465*38e8c45fSAndroid Build Coastguard Worker 
1466*38e8c45fSAndroid Build Coastguard Worker     // call into the driver
1467*38e8c45fSAndroid Build Coastguard Worker     VkDevice dev;
1468*38e8c45fSAndroid Build Coastguard Worker     ATRACE_BEGIN("driver.CreateDevice");
1469*38e8c45fSAndroid Build Coastguard Worker     result = instance_data.driver.CreateDevice(
1470*38e8c45fSAndroid Build Coastguard Worker         physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
1471*38e8c45fSAndroid Build Coastguard Worker         pAllocator, &dev);
1472*38e8c45fSAndroid Build Coastguard Worker     ATRACE_END();
1473*38e8c45fSAndroid Build Coastguard Worker     if (result != VK_SUCCESS) {
1474*38e8c45fSAndroid Build Coastguard Worker         FreeDeviceData(data, data_allocator);
1475*38e8c45fSAndroid Build Coastguard Worker         return result;
1476*38e8c45fSAndroid Build Coastguard Worker     }
1477*38e8c45fSAndroid Build Coastguard Worker 
1478*38e8c45fSAndroid Build Coastguard Worker     // initialize DeviceDriverTable
1479*38e8c45fSAndroid Build Coastguard Worker     if (!SetData(dev, *data) ||
1480*38e8c45fSAndroid Build Coastguard Worker         !InitDriverTable(dev, instance_data.get_device_proc_addr,
1481*38e8c45fSAndroid Build Coastguard Worker                          wrapper.GetHalExtensions())) {
1482*38e8c45fSAndroid Build Coastguard Worker         data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
1483*38e8c45fSAndroid Build Coastguard Worker             instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
1484*38e8c45fSAndroid Build Coastguard Worker         if (data->driver.DestroyDevice)
1485*38e8c45fSAndroid Build Coastguard Worker             data->driver.DestroyDevice(dev, pAllocator);
1486*38e8c45fSAndroid Build Coastguard Worker 
1487*38e8c45fSAndroid Build Coastguard Worker         FreeDeviceData(data, data_allocator);
1488*38e8c45fSAndroid Build Coastguard Worker 
1489*38e8c45fSAndroid Build Coastguard Worker         return VK_ERROR_INCOMPATIBLE_DRIVER;
1490*38e8c45fSAndroid Build Coastguard Worker     }
1491*38e8c45fSAndroid Build Coastguard Worker 
1492*38e8c45fSAndroid Build Coastguard Worker     // Confirming ANDROID_native_buffer implementation, whose set of
1493*38e8c45fSAndroid Build Coastguard Worker     // entrypoints varies according to the spec version.
1494*38e8c45fSAndroid Build Coastguard Worker     if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1495*38e8c45fSAndroid Build Coastguard Worker         !data->driver.GetSwapchainGrallocUsageANDROID &&
1496*38e8c45fSAndroid Build Coastguard Worker         !data->driver.GetSwapchainGrallocUsage2ANDROID &&
1497*38e8c45fSAndroid Build Coastguard Worker         !data->driver.GetSwapchainGrallocUsage3ANDROID &&
1498*38e8c45fSAndroid Build Coastguard Worker         !data->driver.GetSwapchainGrallocUsage4ANDROID) {
1499*38e8c45fSAndroid Build Coastguard Worker         ALOGE(
1500*38e8c45fSAndroid Build Coastguard Worker             "Driver's implementation of ANDROID_native_buffer is broken;"
1501*38e8c45fSAndroid Build Coastguard Worker             " must expose at least one of "
1502*38e8c45fSAndroid Build Coastguard Worker             "vkGetSwapchainGrallocUsageANDROID or "
1503*38e8c45fSAndroid Build Coastguard Worker             "vkGetSwapchainGrallocUsage2ANDROID or "
1504*38e8c45fSAndroid Build Coastguard Worker             "vkGetSwapchainGrallocUsage3ANDROID or "
1505*38e8c45fSAndroid Build Coastguard Worker             "vkGetSwapchainGrallocUsage4ANDROID");
1506*38e8c45fSAndroid Build Coastguard Worker 
1507*38e8c45fSAndroid Build Coastguard Worker         data->driver.DestroyDevice(dev, pAllocator);
1508*38e8c45fSAndroid Build Coastguard Worker         FreeDeviceData(data, data_allocator);
1509*38e8c45fSAndroid Build Coastguard Worker 
1510*38e8c45fSAndroid Build Coastguard Worker         return VK_ERROR_INCOMPATIBLE_DRIVER;
1511*38e8c45fSAndroid Build Coastguard Worker     }
1512*38e8c45fSAndroid Build Coastguard Worker 
1513*38e8c45fSAndroid Build Coastguard Worker     if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1514*38e8c45fSAndroid Build Coastguard Worker         // Log that the app is hitting software Vulkan implementation
1515*38e8c45fSAndroid Build Coastguard Worker         android::GraphicsEnv::getInstance().setTargetStats(
1516*38e8c45fSAndroid Build Coastguard Worker             android::GpuStatsInfo::Stats::CPU_VULKAN_IN_USE);
1517*38e8c45fSAndroid Build Coastguard Worker     }
1518*38e8c45fSAndroid Build Coastguard Worker 
1519*38e8c45fSAndroid Build Coastguard Worker     data->driver_device = dev;
1520*38e8c45fSAndroid Build Coastguard Worker     data->driver_physical_device = physicalDevice;
1521*38e8c45fSAndroid Build Coastguard Worker 
1522*38e8c45fSAndroid Build Coastguard Worker     *pDevice = dev;
1523*38e8c45fSAndroid Build Coastguard Worker 
1524*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/259516419) avoid getting stats from hwui
1525*38e8c45fSAndroid Build Coastguard Worker     const bool reportStats = true;
1526*38e8c45fSAndroid Build Coastguard Worker     if (reportStats) {
1527*38e8c45fSAndroid Build Coastguard Worker         android::GraphicsEnv::getInstance().setTargetStats(
1528*38e8c45fSAndroid Build Coastguard Worker             android::GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE);
1529*38e8c45fSAndroid Build Coastguard Worker 
1530*38e8c45fSAndroid Build Coastguard Worker         // Set stats for creating a Vulkan device and report features in use
1531*38e8c45fSAndroid Build Coastguard Worker         const VkPhysicalDeviceFeatures* pEnabledFeatures =
1532*38e8c45fSAndroid Build Coastguard Worker             pCreateInfo->pEnabledFeatures;
1533*38e8c45fSAndroid Build Coastguard Worker         if (!pEnabledFeatures) {
1534*38e8c45fSAndroid Build Coastguard Worker             // Use features from the chained VkPhysicalDeviceFeatures2
1535*38e8c45fSAndroid Build Coastguard Worker             // structure, if given
1536*38e8c45fSAndroid Build Coastguard Worker             const VkPhysicalDeviceFeatures2* features2 =
1537*38e8c45fSAndroid Build Coastguard Worker                 reinterpret_cast<const VkPhysicalDeviceFeatures2*>(
1538*38e8c45fSAndroid Build Coastguard Worker                     pCreateInfo->pNext);
1539*38e8c45fSAndroid Build Coastguard Worker             while (features2 &&
1540*38e8c45fSAndroid Build Coastguard Worker                    features2->sType !=
1541*38e8c45fSAndroid Build Coastguard Worker                        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) {
1542*38e8c45fSAndroid Build Coastguard Worker                 features2 = reinterpret_cast<const VkPhysicalDeviceFeatures2*>(
1543*38e8c45fSAndroid Build Coastguard Worker                     features2->pNext);
1544*38e8c45fSAndroid Build Coastguard Worker             }
1545*38e8c45fSAndroid Build Coastguard Worker             if (features2) {
1546*38e8c45fSAndroid Build Coastguard Worker                 pEnabledFeatures = &features2->features;
1547*38e8c45fSAndroid Build Coastguard Worker             }
1548*38e8c45fSAndroid Build Coastguard Worker         }
1549*38e8c45fSAndroid Build Coastguard Worker         const VkBool32* pFeatures =
1550*38e8c45fSAndroid Build Coastguard Worker             reinterpret_cast<const VkBool32*>(pEnabledFeatures);
1551*38e8c45fSAndroid Build Coastguard Worker         if (pFeatures) {
1552*38e8c45fSAndroid Build Coastguard Worker             // VkPhysicalDeviceFeatures consists of VkBool32 values, go over all
1553*38e8c45fSAndroid Build Coastguard Worker             // of them using pointer arithmetic here and save the features in a
1554*38e8c45fSAndroid Build Coastguard Worker             // 64-bit bitfield
1555*38e8c45fSAndroid Build Coastguard Worker             static_assert(
1556*38e8c45fSAndroid Build Coastguard Worker                 (sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32)) <= 64,
1557*38e8c45fSAndroid Build Coastguard Worker                 "VkPhysicalDeviceFeatures has too many elements for bitfield "
1558*38e8c45fSAndroid Build Coastguard Worker                 "packing");
1559*38e8c45fSAndroid Build Coastguard Worker             static_assert(
1560*38e8c45fSAndroid Build Coastguard Worker                 (sizeof(VkPhysicalDeviceFeatures) % sizeof(VkBool32)) == 0,
1561*38e8c45fSAndroid Build Coastguard Worker                 "VkPhysicalDeviceFeatures has invalid size for bitfield "
1562*38e8c45fSAndroid Build Coastguard Worker                 "packing");
1563*38e8c45fSAndroid Build Coastguard Worker             const int numFeatures =
1564*38e8c45fSAndroid Build Coastguard Worker                 sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
1565*38e8c45fSAndroid Build Coastguard Worker 
1566*38e8c45fSAndroid Build Coastguard Worker             uint64_t enableFeatureBits = 0;
1567*38e8c45fSAndroid Build Coastguard Worker             for (int i = 0; i < numFeatures; i++) {
1568*38e8c45fSAndroid Build Coastguard Worker                 if (pFeatures[i] != VK_FALSE) {
1569*38e8c45fSAndroid Build Coastguard Worker                     enableFeatureBits |= (uint64_t(1) << i);
1570*38e8c45fSAndroid Build Coastguard Worker                 }
1571*38e8c45fSAndroid Build Coastguard Worker             }
1572*38e8c45fSAndroid Build Coastguard Worker             android::GraphicsEnv::getInstance().setTargetStats(
1573*38e8c45fSAndroid Build Coastguard Worker                 android::GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED,
1574*38e8c45fSAndroid Build Coastguard Worker                 enableFeatureBits);
1575*38e8c45fSAndroid Build Coastguard Worker         }
1576*38e8c45fSAndroid Build Coastguard Worker 
1577*38e8c45fSAndroid Build Coastguard Worker         // Update stats for the extensions requested
1578*38e8c45fSAndroid Build Coastguard Worker         android::GraphicsEnv::getInstance().setVulkanDeviceExtensions(
1579*38e8c45fSAndroid Build Coastguard Worker             pCreateInfo->enabledExtensionCount,
1580*38e8c45fSAndroid Build Coastguard Worker             pCreateInfo->ppEnabledExtensionNames);
1581*38e8c45fSAndroid Build Coastguard Worker     }
1582*38e8c45fSAndroid Build Coastguard Worker 
1583*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
1584*38e8c45fSAndroid Build Coastguard Worker }
1585*38e8c45fSAndroid Build Coastguard Worker 
DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)1586*38e8c45fSAndroid Build Coastguard Worker void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1587*38e8c45fSAndroid Build Coastguard Worker     DeviceData& data = GetData(device);
1588*38e8c45fSAndroid Build Coastguard Worker     data.driver.DestroyDevice(device, pAllocator);
1589*38e8c45fSAndroid Build Coastguard Worker 
1590*38e8c45fSAndroid Build Coastguard Worker     VkAllocationCallbacks local_allocator;
1591*38e8c45fSAndroid Build Coastguard Worker     if (!pAllocator) {
1592*38e8c45fSAndroid Build Coastguard Worker         local_allocator = data.allocator;
1593*38e8c45fSAndroid Build Coastguard Worker         pAllocator = &local_allocator;
1594*38e8c45fSAndroid Build Coastguard Worker     }
1595*38e8c45fSAndroid Build Coastguard Worker 
1596*38e8c45fSAndroid Build Coastguard Worker     FreeDeviceData(&data, *pAllocator);
1597*38e8c45fSAndroid Build Coastguard Worker }
1598*38e8c45fSAndroid Build Coastguard Worker 
EnumeratePhysicalDevices(VkInstance instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)1599*38e8c45fSAndroid Build Coastguard Worker VkResult EnumeratePhysicalDevices(VkInstance instance,
1600*38e8c45fSAndroid Build Coastguard Worker                                   uint32_t* pPhysicalDeviceCount,
1601*38e8c45fSAndroid Build Coastguard Worker                                   VkPhysicalDevice* pPhysicalDevices) {
1602*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1603*38e8c45fSAndroid Build Coastguard Worker 
1604*38e8c45fSAndroid Build Coastguard Worker     const auto& data = GetData(instance);
1605*38e8c45fSAndroid Build Coastguard Worker 
1606*38e8c45fSAndroid Build Coastguard Worker     VkResult result = data.driver.EnumeratePhysicalDevices(
1607*38e8c45fSAndroid Build Coastguard Worker         instance, pPhysicalDeviceCount, pPhysicalDevices);
1608*38e8c45fSAndroid Build Coastguard Worker     if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1609*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1610*38e8c45fSAndroid Build Coastguard Worker             SetData(pPhysicalDevices[i], data);
1611*38e8c45fSAndroid Build Coastguard Worker     }
1612*38e8c45fSAndroid Build Coastguard Worker 
1613*38e8c45fSAndroid Build Coastguard Worker     return result;
1614*38e8c45fSAndroid Build Coastguard Worker }
1615*38e8c45fSAndroid Build Coastguard Worker 
EnumeratePhysicalDeviceGroups(VkInstance instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)1616*38e8c45fSAndroid Build Coastguard Worker VkResult EnumeratePhysicalDeviceGroups(
1617*38e8c45fSAndroid Build Coastguard Worker     VkInstance instance,
1618*38e8c45fSAndroid Build Coastguard Worker     uint32_t* pPhysicalDeviceGroupCount,
1619*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
1620*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1621*38e8c45fSAndroid Build Coastguard Worker 
1622*38e8c45fSAndroid Build Coastguard Worker     VkResult result = VK_SUCCESS;
1623*38e8c45fSAndroid Build Coastguard Worker     const auto& data = GetData(instance);
1624*38e8c45fSAndroid Build Coastguard Worker 
1625*38e8c45fSAndroid Build Coastguard Worker     if (!data.driver.EnumeratePhysicalDeviceGroups &&
1626*38e8c45fSAndroid Build Coastguard Worker         !data.driver.EnumeratePhysicalDeviceGroupsKHR) {
1627*38e8c45fSAndroid Build Coastguard Worker         uint32_t device_count = 0;
1628*38e8c45fSAndroid Build Coastguard Worker         result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
1629*38e8c45fSAndroid Build Coastguard Worker         if (result < 0)
1630*38e8c45fSAndroid Build Coastguard Worker             return result;
1631*38e8c45fSAndroid Build Coastguard Worker 
1632*38e8c45fSAndroid Build Coastguard Worker         if (!pPhysicalDeviceGroupProperties) {
1633*38e8c45fSAndroid Build Coastguard Worker             *pPhysicalDeviceGroupCount = device_count;
1634*38e8c45fSAndroid Build Coastguard Worker             return result;
1635*38e8c45fSAndroid Build Coastguard Worker         }
1636*38e8c45fSAndroid Build Coastguard Worker 
1637*38e8c45fSAndroid Build Coastguard Worker         if (!device_count) {
1638*38e8c45fSAndroid Build Coastguard Worker             *pPhysicalDeviceGroupCount = 0;
1639*38e8c45fSAndroid Build Coastguard Worker             return result;
1640*38e8c45fSAndroid Build Coastguard Worker         }
1641*38e8c45fSAndroid Build Coastguard Worker         device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
1642*38e8c45fSAndroid Build Coastguard Worker         if (!device_count)
1643*38e8c45fSAndroid Build Coastguard Worker             return VK_INCOMPLETE;
1644*38e8c45fSAndroid Build Coastguard Worker 
1645*38e8c45fSAndroid Build Coastguard Worker         std::vector<VkPhysicalDevice> devices(device_count);
1646*38e8c45fSAndroid Build Coastguard Worker         *pPhysicalDeviceGroupCount = device_count;
1647*38e8c45fSAndroid Build Coastguard Worker         result =
1648*38e8c45fSAndroid Build Coastguard Worker             EnumeratePhysicalDevices(instance, &device_count, devices.data());
1649*38e8c45fSAndroid Build Coastguard Worker         if (result < 0)
1650*38e8c45fSAndroid Build Coastguard Worker             return result;
1651*38e8c45fSAndroid Build Coastguard Worker 
1652*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < device_count; ++i) {
1653*38e8c45fSAndroid Build Coastguard Worker             pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
1654*38e8c45fSAndroid Build Coastguard Worker             pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
1655*38e8c45fSAndroid Build Coastguard Worker             pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
1656*38e8c45fSAndroid Build Coastguard Worker         }
1657*38e8c45fSAndroid Build Coastguard Worker     } else {
1658*38e8c45fSAndroid Build Coastguard Worker         if (data.driver.EnumeratePhysicalDeviceGroups) {
1659*38e8c45fSAndroid Build Coastguard Worker             result = data.driver.EnumeratePhysicalDeviceGroups(
1660*38e8c45fSAndroid Build Coastguard Worker                 instance, pPhysicalDeviceGroupCount,
1661*38e8c45fSAndroid Build Coastguard Worker                 pPhysicalDeviceGroupProperties);
1662*38e8c45fSAndroid Build Coastguard Worker         } else {
1663*38e8c45fSAndroid Build Coastguard Worker             result = data.driver.EnumeratePhysicalDeviceGroupsKHR(
1664*38e8c45fSAndroid Build Coastguard Worker                 instance, pPhysicalDeviceGroupCount,
1665*38e8c45fSAndroid Build Coastguard Worker                 pPhysicalDeviceGroupProperties);
1666*38e8c45fSAndroid Build Coastguard Worker         }
1667*38e8c45fSAndroid Build Coastguard Worker         if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
1668*38e8c45fSAndroid Build Coastguard Worker             *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
1669*38e8c45fSAndroid Build Coastguard Worker             for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
1670*38e8c45fSAndroid Build Coastguard Worker                 for (uint32_t j = 0;
1671*38e8c45fSAndroid Build Coastguard Worker                      j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
1672*38e8c45fSAndroid Build Coastguard Worker                      j++) {
1673*38e8c45fSAndroid Build Coastguard Worker                     SetData(
1674*38e8c45fSAndroid Build Coastguard Worker                         pPhysicalDeviceGroupProperties[i].physicalDevices[j],
1675*38e8c45fSAndroid Build Coastguard Worker                         data);
1676*38e8c45fSAndroid Build Coastguard Worker                 }
1677*38e8c45fSAndroid Build Coastguard Worker             }
1678*38e8c45fSAndroid Build Coastguard Worker         }
1679*38e8c45fSAndroid Build Coastguard Worker     }
1680*38e8c45fSAndroid Build Coastguard Worker 
1681*38e8c45fSAndroid Build Coastguard Worker     return result;
1682*38e8c45fSAndroid Build Coastguard Worker }
1683*38e8c45fSAndroid Build Coastguard Worker 
GetDeviceQueue(VkDevice device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)1684*38e8c45fSAndroid Build Coastguard Worker void GetDeviceQueue(VkDevice device,
1685*38e8c45fSAndroid Build Coastguard Worker                     uint32_t queueFamilyIndex,
1686*38e8c45fSAndroid Build Coastguard Worker                     uint32_t queueIndex,
1687*38e8c45fSAndroid Build Coastguard Worker                     VkQueue* pQueue) {
1688*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1689*38e8c45fSAndroid Build Coastguard Worker 
1690*38e8c45fSAndroid Build Coastguard Worker     const auto& data = GetData(device);
1691*38e8c45fSAndroid Build Coastguard Worker 
1692*38e8c45fSAndroid Build Coastguard Worker     data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1693*38e8c45fSAndroid Build Coastguard Worker     SetData(*pQueue, data);
1694*38e8c45fSAndroid Build Coastguard Worker }
1695*38e8c45fSAndroid Build Coastguard Worker 
GetDeviceQueue2(VkDevice device,const VkDeviceQueueInfo2 * pQueueInfo,VkQueue * pQueue)1696*38e8c45fSAndroid Build Coastguard Worker void GetDeviceQueue2(VkDevice device,
1697*38e8c45fSAndroid Build Coastguard Worker                      const VkDeviceQueueInfo2* pQueueInfo,
1698*38e8c45fSAndroid Build Coastguard Worker                      VkQueue* pQueue) {
1699*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1700*38e8c45fSAndroid Build Coastguard Worker 
1701*38e8c45fSAndroid Build Coastguard Worker     const auto& data = GetData(device);
1702*38e8c45fSAndroid Build Coastguard Worker 
1703*38e8c45fSAndroid Build Coastguard Worker     data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
1704*38e8c45fSAndroid Build Coastguard Worker     if (*pQueue != VK_NULL_HANDLE) SetData(*pQueue, data);
1705*38e8c45fSAndroid Build Coastguard Worker }
1706*38e8c45fSAndroid Build Coastguard Worker 
AllocateCommandBuffers(VkDevice device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)1707*38e8c45fSAndroid Build Coastguard Worker VkResult AllocateCommandBuffers(
1708*38e8c45fSAndroid Build Coastguard Worker     VkDevice device,
1709*38e8c45fSAndroid Build Coastguard Worker     const VkCommandBufferAllocateInfo* pAllocateInfo,
1710*38e8c45fSAndroid Build Coastguard Worker     VkCommandBuffer* pCommandBuffers) {
1711*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1712*38e8c45fSAndroid Build Coastguard Worker 
1713*38e8c45fSAndroid Build Coastguard Worker     const auto& data = GetData(device);
1714*38e8c45fSAndroid Build Coastguard Worker 
1715*38e8c45fSAndroid Build Coastguard Worker     VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1716*38e8c45fSAndroid Build Coastguard Worker                                                          pCommandBuffers);
1717*38e8c45fSAndroid Build Coastguard Worker     if (result == VK_SUCCESS) {
1718*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1719*38e8c45fSAndroid Build Coastguard Worker             SetData(pCommandBuffers[i], data);
1720*38e8c45fSAndroid Build Coastguard Worker     }
1721*38e8c45fSAndroid Build Coastguard Worker 
1722*38e8c45fSAndroid Build Coastguard Worker     return result;
1723*38e8c45fSAndroid Build Coastguard Worker }
1724*38e8c45fSAndroid Build Coastguard Worker 
QueueSubmit(VkQueue queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)1725*38e8c45fSAndroid Build Coastguard Worker VkResult QueueSubmit(VkQueue queue,
1726*38e8c45fSAndroid Build Coastguard Worker                      uint32_t submitCount,
1727*38e8c45fSAndroid Build Coastguard Worker                      const VkSubmitInfo* pSubmits,
1728*38e8c45fSAndroid Build Coastguard Worker                      VkFence fence) {
1729*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1730*38e8c45fSAndroid Build Coastguard Worker 
1731*38e8c45fSAndroid Build Coastguard Worker     const auto& data = GetData(queue);
1732*38e8c45fSAndroid Build Coastguard Worker 
1733*38e8c45fSAndroid Build Coastguard Worker     return data.driver.QueueSubmit(queue, submitCount, pSubmits, fence);
1734*38e8c45fSAndroid Build Coastguard Worker }
1735*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)1736*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
1737*38e8c45fSAndroid Build Coastguard Worker                                 VkPhysicalDeviceFeatures2* pFeatures) {
1738*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1739*38e8c45fSAndroid Build Coastguard Worker 
1740*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1741*38e8c45fSAndroid Build Coastguard Worker 
1742*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceFeatures2) {
1743*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
1744*38e8c45fSAndroid Build Coastguard Worker     } else {
1745*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
1746*38e8c45fSAndroid Build Coastguard Worker     }
1747*38e8c45fSAndroid Build Coastguard Worker 
1748*38e8c45fSAndroid Build Coastguard Worker     // Conditionally add imageCompressionControlSwapchain if
1749*38e8c45fSAndroid Build Coastguard Worker     // imageCompressionControl is supported Check for imageCompressionControl in
1750*38e8c45fSAndroid Build Coastguard Worker     // the pChain
1751*38e8c45fSAndroid Build Coastguard Worker     bool imageCompressionControl = false;
1752*38e8c45fSAndroid Build Coastguard Worker     bool imageCompressionControlInChain = false;
1753*38e8c45fSAndroid Build Coastguard Worker     bool imageCompressionControlSwapchainInChain = false;
1754*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceFeatures2* pFeats = pFeatures;
1755*38e8c45fSAndroid Build Coastguard Worker     while (pFeats) {
1756*38e8c45fSAndroid Build Coastguard Worker         switch (pFeats->sType) {
1757*38e8c45fSAndroid Build Coastguard Worker             case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT: {
1758*38e8c45fSAndroid Build Coastguard Worker                 const VkPhysicalDeviceImageCompressionControlFeaturesEXT*
1759*38e8c45fSAndroid Build Coastguard Worker                     compressionFeat = reinterpret_cast<
1760*38e8c45fSAndroid Build Coastguard Worker                         const VkPhysicalDeviceImageCompressionControlFeaturesEXT*>(
1761*38e8c45fSAndroid Build Coastguard Worker                         pFeats);
1762*38e8c45fSAndroid Build Coastguard Worker                 imageCompressionControl =
1763*38e8c45fSAndroid Build Coastguard Worker                     compressionFeat->imageCompressionControl;
1764*38e8c45fSAndroid Build Coastguard Worker                 imageCompressionControlInChain = true;
1765*38e8c45fSAndroid Build Coastguard Worker             } break;
1766*38e8c45fSAndroid Build Coastguard Worker 
1767*38e8c45fSAndroid Build Coastguard Worker             case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT: {
1768*38e8c45fSAndroid Build Coastguard Worker                 VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*
1769*38e8c45fSAndroid Build Coastguard Worker                     compressionFeat = reinterpret_cast<
1770*38e8c45fSAndroid Build Coastguard Worker                         VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*>(
1771*38e8c45fSAndroid Build Coastguard Worker                         pFeats);
1772*38e8c45fSAndroid Build Coastguard Worker                 compressionFeat->imageCompressionControlSwapchain = false;
1773*38e8c45fSAndroid Build Coastguard Worker                 imageCompressionControlSwapchainInChain = true;
1774*38e8c45fSAndroid Build Coastguard Worker             } break;
1775*38e8c45fSAndroid Build Coastguard Worker 
1776*38e8c45fSAndroid Build Coastguard Worker             case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT: {
1777*38e8c45fSAndroid Build Coastguard Worker                 auto smf = reinterpret_cast<VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *>(
1778*38e8c45fSAndroid Build Coastguard Worker                         pFeats);
1779*38e8c45fSAndroid Build Coastguard Worker                 smf->swapchainMaintenance1 = true;
1780*38e8c45fSAndroid Build Coastguard Worker             } break;
1781*38e8c45fSAndroid Build Coastguard Worker 
1782*38e8c45fSAndroid Build Coastguard Worker             default:
1783*38e8c45fSAndroid Build Coastguard Worker                 break;
1784*38e8c45fSAndroid Build Coastguard Worker         }
1785*38e8c45fSAndroid Build Coastguard Worker         pFeats = reinterpret_cast<VkPhysicalDeviceFeatures2*>(pFeats->pNext);
1786*38e8c45fSAndroid Build Coastguard Worker     }
1787*38e8c45fSAndroid Build Coastguard Worker 
1788*38e8c45fSAndroid Build Coastguard Worker     if (!imageCompressionControlSwapchainInChain) {
1789*38e8c45fSAndroid Build Coastguard Worker         return;
1790*38e8c45fSAndroid Build Coastguard Worker     }
1791*38e8c45fSAndroid Build Coastguard Worker 
1792*38e8c45fSAndroid Build Coastguard Worker     // If not in pchain, explicitly query for imageCompressionControl
1793*38e8c45fSAndroid Build Coastguard Worker     if (!imageCompressionControlInChain) {
1794*38e8c45fSAndroid Build Coastguard Worker         VkPhysicalDeviceImageCompressionControlFeaturesEXT imageCompFeats = {};
1795*38e8c45fSAndroid Build Coastguard Worker         imageCompFeats.sType =
1796*38e8c45fSAndroid Build Coastguard Worker             VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;
1797*38e8c45fSAndroid Build Coastguard Worker         imageCompFeats.pNext = nullptr;
1798*38e8c45fSAndroid Build Coastguard Worker         imageCompFeats.imageCompressionControl = false;
1799*38e8c45fSAndroid Build Coastguard Worker 
1800*38e8c45fSAndroid Build Coastguard Worker         VkPhysicalDeviceFeatures2 feats2 = {};
1801*38e8c45fSAndroid Build Coastguard Worker         feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1802*38e8c45fSAndroid Build Coastguard Worker         feats2.pNext = &imageCompFeats;
1803*38e8c45fSAndroid Build Coastguard Worker 
1804*38e8c45fSAndroid Build Coastguard Worker         if (driver.GetPhysicalDeviceFeatures2) {
1805*38e8c45fSAndroid Build Coastguard Worker             driver.GetPhysicalDeviceFeatures2(physicalDevice, &feats2);
1806*38e8c45fSAndroid Build Coastguard Worker         } else {
1807*38e8c45fSAndroid Build Coastguard Worker             driver.GetPhysicalDeviceFeatures2KHR(physicalDevice, &feats2);
1808*38e8c45fSAndroid Build Coastguard Worker         }
1809*38e8c45fSAndroid Build Coastguard Worker 
1810*38e8c45fSAndroid Build Coastguard Worker         imageCompressionControl = imageCompFeats.imageCompressionControl;
1811*38e8c45fSAndroid Build Coastguard Worker     }
1812*38e8c45fSAndroid Build Coastguard Worker 
1813*38e8c45fSAndroid Build Coastguard Worker     // Only enumerate imageCompressionControlSwapchin if imageCompressionControl
1814*38e8c45fSAndroid Build Coastguard Worker     if (imageCompressionControl) {
1815*38e8c45fSAndroid Build Coastguard Worker         pFeats = pFeatures;
1816*38e8c45fSAndroid Build Coastguard Worker         while (pFeats) {
1817*38e8c45fSAndroid Build Coastguard Worker             switch (pFeats->sType) {
1818*38e8c45fSAndroid Build Coastguard Worker                 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT: {
1819*38e8c45fSAndroid Build Coastguard Worker                     VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*
1820*38e8c45fSAndroid Build Coastguard Worker                         compressionFeat = reinterpret_cast<
1821*38e8c45fSAndroid Build Coastguard Worker                             VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*>(
1822*38e8c45fSAndroid Build Coastguard Worker                             pFeats);
1823*38e8c45fSAndroid Build Coastguard Worker                     compressionFeat->imageCompressionControlSwapchain = true;
1824*38e8c45fSAndroid Build Coastguard Worker                 } break;
1825*38e8c45fSAndroid Build Coastguard Worker 
1826*38e8c45fSAndroid Build Coastguard Worker                 default:
1827*38e8c45fSAndroid Build Coastguard Worker                     break;
1828*38e8c45fSAndroid Build Coastguard Worker             }
1829*38e8c45fSAndroid Build Coastguard Worker             pFeats =
1830*38e8c45fSAndroid Build Coastguard Worker                 reinterpret_cast<VkPhysicalDeviceFeatures2*>(pFeats->pNext);
1831*38e8c45fSAndroid Build Coastguard Worker         }
1832*38e8c45fSAndroid Build Coastguard Worker     }
1833*38e8c45fSAndroid Build Coastguard Worker }
1834*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)1835*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1836*38e8c45fSAndroid Build Coastguard Worker                                   VkPhysicalDeviceProperties2* pProperties) {
1837*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1838*38e8c45fSAndroid Build Coastguard Worker 
1839*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1840*38e8c45fSAndroid Build Coastguard Worker 
1841*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceProperties2) {
1842*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceProperties2(physicalDevice, pProperties);
1843*38e8c45fSAndroid Build Coastguard Worker         return;
1844*38e8c45fSAndroid Build Coastguard Worker     }
1845*38e8c45fSAndroid Build Coastguard Worker 
1846*38e8c45fSAndroid Build Coastguard Worker     driver.GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
1847*38e8c45fSAndroid Build Coastguard Worker }
1848*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)1849*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceFormatProperties2(
1850*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1851*38e8c45fSAndroid Build Coastguard Worker     VkFormat format,
1852*38e8c45fSAndroid Build Coastguard Worker     VkFormatProperties2* pFormatProperties) {
1853*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1854*38e8c45fSAndroid Build Coastguard Worker 
1855*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1856*38e8c45fSAndroid Build Coastguard Worker 
1857*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceFormatProperties2) {
1858*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceFormatProperties2(physicalDevice, format,
1859*38e8c45fSAndroid Build Coastguard Worker                                                   pFormatProperties);
1860*38e8c45fSAndroid Build Coastguard Worker         return;
1861*38e8c45fSAndroid Build Coastguard Worker     }
1862*38e8c45fSAndroid Build Coastguard Worker 
1863*38e8c45fSAndroid Build Coastguard Worker     driver.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format,
1864*38e8c45fSAndroid Build Coastguard Worker                                                  pFormatProperties);
1865*38e8c45fSAndroid Build Coastguard Worker }
1866*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)1867*38e8c45fSAndroid Build Coastguard Worker VkResult GetPhysicalDeviceImageFormatProperties2(
1868*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1869*38e8c45fSAndroid Build Coastguard Worker     const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
1870*38e8c45fSAndroid Build Coastguard Worker     VkImageFormatProperties2* pImageFormatProperties) {
1871*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1872*38e8c45fSAndroid Build Coastguard Worker 
1873*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1874*38e8c45fSAndroid Build Coastguard Worker 
1875*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceImageFormatProperties2) {
1876*38e8c45fSAndroid Build Coastguard Worker         return driver.GetPhysicalDeviceImageFormatProperties2(
1877*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pImageFormatInfo, pImageFormatProperties);
1878*38e8c45fSAndroid Build Coastguard Worker     }
1879*38e8c45fSAndroid Build Coastguard Worker 
1880*38e8c45fSAndroid Build Coastguard Worker     return driver.GetPhysicalDeviceImageFormatProperties2KHR(
1881*38e8c45fSAndroid Build Coastguard Worker         physicalDevice, pImageFormatInfo, pImageFormatProperties);
1882*38e8c45fSAndroid Build Coastguard Worker }
1883*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)1884*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceQueueFamilyProperties2(
1885*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1886*38e8c45fSAndroid Build Coastguard Worker     uint32_t* pQueueFamilyPropertyCount,
1887*38e8c45fSAndroid Build Coastguard Worker     VkQueueFamilyProperties2* pQueueFamilyProperties) {
1888*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1889*38e8c45fSAndroid Build Coastguard Worker 
1890*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1891*38e8c45fSAndroid Build Coastguard Worker 
1892*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceQueueFamilyProperties2) {
1893*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceQueueFamilyProperties2(
1894*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
1895*38e8c45fSAndroid Build Coastguard Worker         return;
1896*38e8c45fSAndroid Build Coastguard Worker     }
1897*38e8c45fSAndroid Build Coastguard Worker 
1898*38e8c45fSAndroid Build Coastguard Worker     driver.GetPhysicalDeviceQueueFamilyProperties2KHR(
1899*38e8c45fSAndroid Build Coastguard Worker         physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
1900*38e8c45fSAndroid Build Coastguard Worker }
1901*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)1902*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceMemoryProperties2(
1903*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1904*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
1905*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1906*38e8c45fSAndroid Build Coastguard Worker 
1907*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1908*38e8c45fSAndroid Build Coastguard Worker 
1909*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceMemoryProperties2) {
1910*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceMemoryProperties2(physicalDevice,
1911*38e8c45fSAndroid Build Coastguard Worker                                                   pMemoryProperties);
1912*38e8c45fSAndroid Build Coastguard Worker         return;
1913*38e8c45fSAndroid Build Coastguard Worker     }
1914*38e8c45fSAndroid Build Coastguard Worker 
1915*38e8c45fSAndroid Build Coastguard Worker     driver.GetPhysicalDeviceMemoryProperties2KHR(physicalDevice,
1916*38e8c45fSAndroid Build Coastguard Worker                                                  pMemoryProperties);
1917*38e8c45fSAndroid Build Coastguard Worker }
1918*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)1919*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceSparseImageFormatProperties2(
1920*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1921*38e8c45fSAndroid Build Coastguard Worker     const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
1922*38e8c45fSAndroid Build Coastguard Worker     uint32_t* pPropertyCount,
1923*38e8c45fSAndroid Build Coastguard Worker     VkSparseImageFormatProperties2* pProperties) {
1924*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1925*38e8c45fSAndroid Build Coastguard Worker 
1926*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1927*38e8c45fSAndroid Build Coastguard Worker 
1928*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceSparseImageFormatProperties2) {
1929*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceSparseImageFormatProperties2(
1930*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pFormatInfo, pPropertyCount, pProperties);
1931*38e8c45fSAndroid Build Coastguard Worker         return;
1932*38e8c45fSAndroid Build Coastguard Worker     }
1933*38e8c45fSAndroid Build Coastguard Worker 
1934*38e8c45fSAndroid Build Coastguard Worker     driver.GetPhysicalDeviceSparseImageFormatProperties2KHR(
1935*38e8c45fSAndroid Build Coastguard Worker         physicalDevice, pFormatInfo, pPropertyCount, pProperties);
1936*38e8c45fSAndroid Build Coastguard Worker }
1937*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)1938*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceExternalBufferProperties(
1939*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1940*38e8c45fSAndroid Build Coastguard Worker     const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
1941*38e8c45fSAndroid Build Coastguard Worker     VkExternalBufferProperties* pExternalBufferProperties) {
1942*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1943*38e8c45fSAndroid Build Coastguard Worker 
1944*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1945*38e8c45fSAndroid Build Coastguard Worker 
1946*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceExternalBufferProperties) {
1947*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceExternalBufferProperties(
1948*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
1949*38e8c45fSAndroid Build Coastguard Worker         return;
1950*38e8c45fSAndroid Build Coastguard Worker     }
1951*38e8c45fSAndroid Build Coastguard Worker 
1952*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceExternalBufferPropertiesKHR) {
1953*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceExternalBufferPropertiesKHR(
1954*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
1955*38e8c45fSAndroid Build Coastguard Worker         return;
1956*38e8c45fSAndroid Build Coastguard Worker     }
1957*38e8c45fSAndroid Build Coastguard Worker 
1958*38e8c45fSAndroid Build Coastguard Worker     memset(&pExternalBufferProperties->externalMemoryProperties, 0,
1959*38e8c45fSAndroid Build Coastguard Worker            sizeof(VkExternalMemoryProperties));
1960*38e8c45fSAndroid Build Coastguard Worker }
1961*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)1962*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceExternalSemaphoreProperties(
1963*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1964*38e8c45fSAndroid Build Coastguard Worker     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
1965*38e8c45fSAndroid Build Coastguard Worker     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
1966*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1967*38e8c45fSAndroid Build Coastguard Worker 
1968*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1969*38e8c45fSAndroid Build Coastguard Worker 
1970*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceExternalSemaphoreProperties) {
1971*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceExternalSemaphoreProperties(
1972*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pExternalSemaphoreInfo,
1973*38e8c45fSAndroid Build Coastguard Worker             pExternalSemaphoreProperties);
1974*38e8c45fSAndroid Build Coastguard Worker         return;
1975*38e8c45fSAndroid Build Coastguard Worker     }
1976*38e8c45fSAndroid Build Coastguard Worker 
1977*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceExternalSemaphorePropertiesKHR) {
1978*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceExternalSemaphorePropertiesKHR(
1979*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pExternalSemaphoreInfo,
1980*38e8c45fSAndroid Build Coastguard Worker             pExternalSemaphoreProperties);
1981*38e8c45fSAndroid Build Coastguard Worker         return;
1982*38e8c45fSAndroid Build Coastguard Worker     }
1983*38e8c45fSAndroid Build Coastguard Worker 
1984*38e8c45fSAndroid Build Coastguard Worker     pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
1985*38e8c45fSAndroid Build Coastguard Worker     pExternalSemaphoreProperties->compatibleHandleTypes = 0;
1986*38e8c45fSAndroid Build Coastguard Worker     pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
1987*38e8c45fSAndroid Build Coastguard Worker }
1988*38e8c45fSAndroid Build Coastguard Worker 
GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,VkExternalFenceProperties * pExternalFenceProperties)1989*38e8c45fSAndroid Build Coastguard Worker void GetPhysicalDeviceExternalFenceProperties(
1990*38e8c45fSAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
1991*38e8c45fSAndroid Build Coastguard Worker     const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
1992*38e8c45fSAndroid Build Coastguard Worker     VkExternalFenceProperties* pExternalFenceProperties) {
1993*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
1994*38e8c45fSAndroid Build Coastguard Worker 
1995*38e8c45fSAndroid Build Coastguard Worker     const auto& driver = GetData(physicalDevice).driver;
1996*38e8c45fSAndroid Build Coastguard Worker 
1997*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceExternalFenceProperties) {
1998*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceExternalFenceProperties(
1999*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
2000*38e8c45fSAndroid Build Coastguard Worker         return;
2001*38e8c45fSAndroid Build Coastguard Worker     }
2002*38e8c45fSAndroid Build Coastguard Worker 
2003*38e8c45fSAndroid Build Coastguard Worker     if (driver.GetPhysicalDeviceExternalFencePropertiesKHR) {
2004*38e8c45fSAndroid Build Coastguard Worker         driver.GetPhysicalDeviceExternalFencePropertiesKHR(
2005*38e8c45fSAndroid Build Coastguard Worker             physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
2006*38e8c45fSAndroid Build Coastguard Worker         return;
2007*38e8c45fSAndroid Build Coastguard Worker     }
2008*38e8c45fSAndroid Build Coastguard Worker 
2009*38e8c45fSAndroid Build Coastguard Worker     pExternalFenceProperties->exportFromImportedHandleTypes = 0;
2010*38e8c45fSAndroid Build Coastguard Worker     pExternalFenceProperties->compatibleHandleTypes = 0;
2011*38e8c45fSAndroid Build Coastguard Worker     pExternalFenceProperties->externalFenceFeatures = 0;
2012*38e8c45fSAndroid Build Coastguard Worker }
2013*38e8c45fSAndroid Build Coastguard Worker 
2014*38e8c45fSAndroid Build Coastguard Worker }  // namespace driver
2015*38e8c45fSAndroid Build Coastguard Worker }  // namespace vulkan
2016