[go: nahoru, domu]

19d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu/*
29d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * Copyright 2016 The Android Open Source Project
39d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu *
49d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * Licensed under the Apache License, Version 2.0 (the "License");
59d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * you may not use this file except in compliance with the License.
69d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * You may obtain a copy of the License at
79d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu *
89d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu *      http://www.apache.org/licenses/LICENSE-2.0
99d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu *
109d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * Unless required by applicable law or agreed to in writing, software
119d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * distributed under the License is distributed on an "AS IS" BASIS,
129d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * See the License for the specific language governing permissions and
149d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * limitations under the License.
159d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu */
169d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu
17dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <stdlib.h>
18dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <string.h>
19dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <algorithm>
20ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu#include <array>
214901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu#include <new>
22dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <malloc.h>
239d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu#include <sys/prctl.h>
249d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu
259d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu#include "driver.h"
26b7c4e3b7c97c952ba26f061d74d2038e6c94e689Jesse Hall#include "stubhal.h"
279d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu
28dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu// #define ENABLE_ALLOC_CALLSTACKS 1
29dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#if ENABLE_ALLOC_CALLSTACKS
30dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <utils/CallStack.h>
31dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#define ALOGD_CALLSTACK(...)                             \
32dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    do {                                                 \
33dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        ALOGD(__VA_ARGS__);                              \
34dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        android::CallStack callstack;                    \
35dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        callstack.update();                              \
36dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, "  "); \
37dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    } while (false)
38dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#else
39dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#define ALOGD_CALLSTACK(...) \
40dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    do {                     \
41dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    } while (false)
42dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#endif
43dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu
449d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wunamespace vulkan {
459d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wunamespace driver {
469d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu
47136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wunamespace {
48136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu
4931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wuclass Hal {
5031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu   public:
5131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    static bool Open();
5231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
5331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    static const Hal& Get() { return hal_; }
5431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    static const hwvulkan_device_t& Device() { return *Get().dev_; }
5531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
56319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    int GetDebugReportIndex() const { return debug_report_index_; }
57319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
5831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu   private:
59319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    Hal() : dev_(nullptr), debug_report_index_(-1) {}
6031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    Hal(const Hal&) = delete;
6131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    Hal& operator=(const Hal&) = delete;
6231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
63319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    bool InitDebugReportIndex();
64319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
6531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    static Hal hal_;
6631b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
6731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    const hwvulkan_device_t* dev_;
68319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    int debug_report_index_;
6931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu};
7031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
714901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuclass CreateInfoWrapper {
724901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu   public:
7331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
74ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu                      const VkAllocationCallbacks& allocator);
754901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    CreateInfoWrapper(VkPhysicalDevice physical_dev,
764901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                      const VkDeviceCreateInfo& create_info,
774901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                      const VkAllocationCallbacks& allocator);
784901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    ~CreateInfoWrapper();
794901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
803e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult Validate();
814901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
823e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
833e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
844901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
85ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    explicit operator const VkInstanceCreateInfo*() const;
864901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    explicit operator const VkDeviceCreateInfo*() const;
874901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
884901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu   private:
894901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    struct ExtensionFilter {
904901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        VkExtensionProperties* exts;
914901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        uint32_t ext_count;
924901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
934901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        const char** names;
944901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        uint32_t name_count;
954901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    };
964901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
973e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult SanitizePNext();
984901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
993e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult SanitizeLayers();
1003e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult SanitizeExtensions();
1014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
1023e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult QueryExtensionCount(uint32_t& count) const;
1033e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult EnumerateExtensions(uint32_t& count,
1043e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu                                 VkExtensionProperties* props) const;
1053e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult InitExtensionFilter();
1063e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    void FilterExtension(const char* name);
1074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
1084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    const bool is_instance_;
1094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    const VkAllocationCallbacks& allocator_;
1104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
11131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    VkPhysicalDevice physical_dev_;
1124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
1134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    union {
1144901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        VkInstanceCreateInfo instance_info_;
1154901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        VkDeviceCreateInfo dev_info_;
1164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    };
1174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
1184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    ExtensionFilter extension_filter_;
1194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
1204901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
1214901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
1224901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu};
1234901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
12431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I WuHal Hal::hal_;
12531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
12631b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wubool Hal::Open() {
127dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall    ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
12831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
12931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    // Use a stub device unless we successfully open a real HAL device.
13031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    hal_.dev_ = &stubhal::kDevice;
13131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
13231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    const hwvulkan_module_t* module;
13331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    int result =
13431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module));
13531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    if (result != 0) {
13631b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        ALOGI("no Vulkan HAL present, using stub HAL");
13731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        return true;
13831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    }
13931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
14031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    hwvulkan_device_t* device;
14131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    result =
14231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
14331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu                                     reinterpret_cast<hw_device_t**>(&device));
14431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    if (result != 0) {
14531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        // Any device with a Vulkan HAL should be able to open the device.
14631b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
14731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu              result);
14831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        return false;
14931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    }
15031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
15131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    hal_.dev_ = device;
15231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
153319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    hal_.InitDebugReportIndex();
154319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
155319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    return true;
156319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu}
157319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
158319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wubool Hal::InitDebugReportIndex() {
159319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    uint32_t count;
160319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
161319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        VK_SUCCESS) {
162319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        ALOGE("failed to get HAL instance extension count");
163319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        return false;
164319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    }
165319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
166319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
167319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        malloc(sizeof(VkExtensionProperties) * count));
168319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    if (!exts) {
169319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        ALOGE("failed to allocate HAL instance extension array");
170319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        return false;
171319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    }
172319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
173319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
174319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        VK_SUCCESS) {
175319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        ALOGE("failed to enumerate HAL instance extensions");
176319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        free(exts);
177319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        return false;
178319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    }
179319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
180319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    for (uint32_t i = 0; i < count; i++) {
181319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
182319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            0) {
183319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            debug_report_index_ = static_cast<int>(i);
184319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            break;
185319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        }
186319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    }
187319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
188319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    free(exts);
189319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
19031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    return true;
19131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu}
19231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu
19331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I WuCreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
194ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu                                     const VkAllocationCallbacks& allocator)
195ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    : is_instance_(true),
196ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu      allocator_(allocator),
19731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu      physical_dev_(VK_NULL_HANDLE),
198ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu      instance_info_(create_info),
199ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu      extension_filter_() {
200ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    hook_extensions_.set(ProcHook::EXTENSION_CORE);
201ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    hal_extensions_.set(ProcHook::EXTENSION_CORE);
202ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu}
203ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
2044901db70b12801cf1966937a58eb7566bfdeb4ceChia-I WuCreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
2054901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                     const VkDeviceCreateInfo& create_info,
2064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                     const VkAllocationCallbacks& allocator)
2074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    : is_instance_(false),
2084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu      allocator_(allocator),
2094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu      physical_dev_(physical_dev),
2104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu      dev_info_(create_info),
2114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu      extension_filter_() {
2124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    hook_extensions_.set(ProcHook::EXTENSION_CORE);
2134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    hal_extensions_.set(ProcHook::EXTENSION_CORE);
2144901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
2154901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I WuCreateInfoWrapper::~CreateInfoWrapper() {
2174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
2184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
2194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
2204901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2213e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::Validate() {
2223e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult result = SanitizePNext();
2234901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (result == VK_SUCCESS)
2243e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu        result = SanitizeLayers();
2254901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (result == VK_SUCCESS)
2263e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu        result = SanitizeExtensions();
2274901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2284901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return result;
2294901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
2304901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2314901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuconst std::bitset<ProcHook::EXTENSION_COUNT>&
2323e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuCreateInfoWrapper::GetHookExtensions() const {
2334901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return hook_extensions_;
2344901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
2354901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2364901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuconst std::bitset<ProcHook::EXTENSION_COUNT>&
2373e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuCreateInfoWrapper::GetHalExtensions() const {
2384901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return hal_extensions_;
2394901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
2404901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
241ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuCreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
242ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    return &instance_info_;
243ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu}
244ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
2454901db70b12801cf1966937a58eb7566bfdeb4ceChia-I WuCreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
2464901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return &dev_info_;
2474901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
2484901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2493e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::SanitizePNext() {
2504901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    const struct StructHeader {
2514901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        VkStructureType type;
2524901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        const void* next;
2534901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    } * header;
2544901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2554901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (is_instance_) {
2564901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
2574901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2584901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
2594901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        while (header &&
2604901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu               header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
2614901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            header = reinterpret_cast<const StructHeader*>(header->next);
2624901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2634901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        instance_info_.pNext = header;
2644901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    } else {
2654901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
2664901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2674901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
2684901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        while (header &&
2694901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu               header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
2704901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            header = reinterpret_cast<const StructHeader*>(header->next);
2714901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2724901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        dev_info_.pNext = header;
2734901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    }
2744901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2754901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return VK_SUCCESS;
2764901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
2774901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2783e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::SanitizeLayers() {
2794901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
2804901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                       : dev_info_.ppEnabledLayerNames;
2814901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
2824901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                       : dev_info_.enabledLayerCount;
2834901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2844901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    // remove all layers
2854901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    layer_names = nullptr;
2864901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    layer_count = 0;
2874901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2884901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return VK_SUCCESS;
2894901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
2904901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2913e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::SanitizeExtensions() {
2924901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
2934901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                     : dev_info_.ppEnabledExtensionNames;
2944901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
2954901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                     : dev_info_.enabledExtensionCount;
2964901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (!ext_count)
2974901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return VK_SUCCESS;
2984901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
2993e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult result = InitExtensionFilter();
3004901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (result != VK_SUCCESS)
3014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return result;
3024901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3034901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    for (uint32_t i = 0; i < ext_count; i++)
3043e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu        FilterExtension(ext_names[i]);
3054901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    ext_names = extension_filter_.names;
3074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    ext_count = extension_filter_.name_count;
3084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return VK_SUCCESS;
3104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
3114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3123e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
3134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (is_instance_) {
31431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        return Hal::Device().EnumerateInstanceExtensionProperties(
31531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu            nullptr, &count, nullptr);
3164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    } else {
3174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        const auto& driver = GetData(physical_dev_).driver;
3184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
3194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                                         &count, nullptr);
3204901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    }
3214901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
3224901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3233e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::EnumerateExtensions(
3244901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    uint32_t& count,
3254901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    VkExtensionProperties* props) const {
3264901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (is_instance_) {
32731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        return Hal::Device().EnumerateInstanceExtensionProperties(
32831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu            nullptr, &count, props);
3294901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    } else {
3304901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        const auto& driver = GetData(physical_dev_).driver;
3314901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
3324901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                                         &count, props);
3334901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    }
3344901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
3354901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3363e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::InitExtensionFilter() {
3374901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    // query extension count
3384901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    uint32_t count;
3393e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult result = QueryExtensionCount(count);
3404901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (result != VK_SUCCESS || count == 0)
3414901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return result;
3424901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3434901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    auto& filter = extension_filter_;
3444901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    filter.exts =
3454901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
3464901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            allocator_.pUserData, sizeof(VkExtensionProperties) * count,
3474901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            alignof(VkExtensionProperties),
3484901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
3494901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (!filter.exts)
3504901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return VK_ERROR_OUT_OF_HOST_MEMORY;
3514901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3524901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    // enumerate extensions
3533e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    result = EnumerateExtensions(count, filter.exts);
3544901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (result != VK_SUCCESS && result != VK_INCOMPLETE)
3554901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return result;
3564901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3574901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (!count)
3584901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return VK_SUCCESS;
3594901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3604901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    filter.ext_count = count;
3614901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3624901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    // allocate name array
3634901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    uint32_t enabled_ext_count = (is_instance_)
3644901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                     ? instance_info_.enabledExtensionCount
3654901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                                     : dev_info_.enabledExtensionCount;
3664901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    count = std::min(filter.ext_count, enabled_ext_count);
3674901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
3684901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
3694901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
3704901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (!filter.names)
3714901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return VK_ERROR_OUT_OF_HOST_MEMORY;
3724901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3734901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return VK_SUCCESS;
3744901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
3754901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3763e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wuvoid CreateInfoWrapper::FilterExtension(const char* name) {
3774901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    auto& filter = extension_filter_;
3784901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
3794901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    ProcHook::Extension ext_bit = GetProcHookExtension(name);
3804901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (is_instance_) {
3814901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        switch (ext_bit) {
3824901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            case ProcHook::KHR_android_surface:
3834901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            case ProcHook::KHR_surface:
3844901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                hook_extensions_.set(ext_bit);
3854901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                // return now as these extensions do not require HAL support
3864901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                return;
3874901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            case ProcHook::EXT_debug_report:
3884901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                // both we and HAL can take part in
3894901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                hook_extensions_.set(ext_bit);
3904901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                break;
3914901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            case ProcHook::EXTENSION_UNKNOWN:
3924901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                // HAL's extensions
3934901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                break;
3944901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            default:
3954901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                ALOGW("Ignored invalid instance extension %s", name);
3964901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                return;
3974901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        }
3984901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    } else {
3994901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        switch (ext_bit) {
4004901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            case ProcHook::KHR_swapchain:
4014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                // map VK_KHR_swapchain to VK_ANDROID_native_buffer
4024901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
4034901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                ext_bit = ProcHook::ANDROID_native_buffer;
4044901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                break;
4054901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            case ProcHook::EXTENSION_UNKNOWN:
4064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                // HAL's extensions
4074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                break;
4084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            default:
4094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                ALOGW("Ignored invalid device extension %s", name);
4104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                return;
4114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        }
4124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    }
4134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
4144901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    for (uint32_t i = 0; i < filter.ext_count; i++) {
4154901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        const VkExtensionProperties& props = filter.exts[i];
4164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        // ignore unknown extensions
4174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        if (strcmp(name, props.extensionName) != 0)
4184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            continue;
4194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
4204901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        filter.names[filter.name_count++] = name;
4211600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu        if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
4221600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu            if (ext_bit == ProcHook::ANDROID_native_buffer)
4231600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu                hook_extensions_.set(ProcHook::KHR_swapchain);
4241600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu
4251600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu            hal_extensions_.set(ext_bit);
4261600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu        }
4274901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
4284901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        break;
4294901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    }
4304901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
4314901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
432dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I WuVKAPI_ATTR void* DefaultAllocate(void*,
433dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu                                 size_t size,
434dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu                                 size_t alignment,
435dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu                                 VkSystemAllocationScope) {
436dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    void* ptr = nullptr;
437dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    // Vulkan requires 'alignment' to be a power of two, but posix_memalign
438dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    // additionally requires that it be at least sizeof(void*).
439dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
440dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
441dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu                    ret, ptr);
442dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    return ret == 0 ? ptr : nullptr;
443dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu}
444dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu
445dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I WuVKAPI_ATTR void* DefaultReallocate(void*,
446dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu                                   void* ptr,
447dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu                                   size_t size,
448dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu                                   size_t alignment,
449dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu                                   VkSystemAllocationScope) {
450dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    if (size == 0) {
451dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        free(ptr);
452dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        return nullptr;
453dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    }
454dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu
455dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    // TODO(jessehall): Right now we never shrink allocations; if the new
456dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    // request is smaller than the existing chunk, we just continue using it.
457dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    // Right now the loader never reallocs, so this doesn't matter. If that
458dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    // changes, or if this code is copied into some other project, this should
459dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    // probably have a heuristic to allocate-copy-free when doing so will save
460dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    // "enough" space.
461dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
462dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    if (size <= old_size)
463dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        return ptr;
464dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu
465dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    void* new_ptr = nullptr;
466dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
467dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        return nullptr;
468dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    if (ptr) {
469dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        memcpy(new_ptr, ptr, std::min(old_size, size));
470dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        free(ptr);
471dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    }
472dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    return new_ptr;
473dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu}
474dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu
475dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I WuVKAPI_ATTR void DefaultFree(void*, void* ptr) {
476dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    ALOGD_CALLSTACK("Free: %p", ptr);
477dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    free(ptr);
478dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu}
479dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu
480ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuInstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
481ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    void* data_mem = allocator.pfnAllocation(
482ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
483ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
484ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if (!data_mem)
485ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        return nullptr;
486ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
487ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    return new (data_mem) InstanceData(allocator);
488ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu}
489ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
490ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wuvoid FreeInstanceData(InstanceData* data,
491ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu                      const VkAllocationCallbacks& allocator) {
492ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    data->~InstanceData();
493ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    allocator.pfnFree(allocator.pUserData, data);
494ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu}
495ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
496950d6e1102077d6a3905eb77268800002e792fb0Chia-I WuDeviceData* AllocateDeviceData(
497950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu    const VkAllocationCallbacks& allocator,
498950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu    const DebugReportCallbackList& debug_report_callbacks) {
4994901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    void* data_mem = allocator.pfnAllocation(
5004901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
5014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
5024901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (!data_mem)
5034901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return nullptr;
5044901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
505950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu    return new (data_mem) DeviceData(allocator, debug_report_callbacks);
5064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
5074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
5084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuvoid FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
5094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    data->~DeviceData();
5104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    allocator.pfnFree(allocator.pUserData, data);
5114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
5124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
513136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu}  // anonymous namespace
514136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu
5159d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wubool Debuggable() {
5169d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu    return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
5179d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu}
5189d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu
519136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wubool OpenHAL() {
52031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    return Hal::Open();
521136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu}
522136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu
523dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wuconst VkAllocationCallbacks& GetDefaultAllocator() {
524dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    static const VkAllocationCallbacks kDefaultAllocCallbacks = {
525dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        .pUserData = nullptr,
526dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        .pfnAllocation = DefaultAllocate,
527dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        .pfnReallocation = DefaultReallocate,
528dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu        .pfnFree = DefaultFree,
529dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    };
530dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu
531dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu    return kDefaultAllocCallbacks;
532dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu}
533dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu
534eb7db124e46da9a9210cf868353f5ea79502ffecChia-I WuPFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
535eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    const ProcHook* hook = GetProcHook(pName);
536eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    if (!hook)
53731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        return Hal::Device().GetInstanceProcAddr(instance, pName);
538eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
539eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    if (!instance) {
540eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu        if (hook->type == ProcHook::GLOBAL)
541eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            return hook->proc;
542eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
543109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu        // v0 layers expect
544109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu        //
545109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu        //   vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
546109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu        //
547109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu        // to work.
548109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu        if (strcmp(pName, "vkCreateDevice") == 0)
549109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu            return hook->proc;
550109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu
551eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu        ALOGE(
552e201c3f782f0d3e2ec508fb8093e506145614c06Chia-I Wu            "internal vkGetInstanceProcAddr called for %s without an instance",
553eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            pName);
554eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
555109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu        return nullptr;
556eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    }
557eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
558eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    PFN_vkVoidFunction proc;
559eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
560eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    switch (hook->type) {
561eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu        case ProcHook::INSTANCE:
562eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            proc = (GetData(instance).hook_extensions[hook->extension])
563eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu                       ? hook->proc
56436cc00a1739f7d926cc20671ae9900a5460dd6aeChia-I Wu                       : nullptr;
565eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            break;
566eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu        case ProcHook::DEVICE:
567eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            proc = (hook->extension == ProcHook::EXTENSION_CORE)
568eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu                       ? hook->proc
569eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu                       : hook->checked_proc;
570eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            break;
571eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu        default:
572eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            ALOGE(
573e201c3f782f0d3e2ec508fb8093e506145614c06Chia-I Wu                "internal vkGetInstanceProcAddr called for %s with an instance",
574eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu                pName);
575eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            proc = nullptr;
576eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu            break;
577eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    }
578eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
579eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    return proc;
580eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu}
581eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
582eb7db124e46da9a9210cf868353f5ea79502ffecChia-I WuPFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
583eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    const ProcHook* hook = GetProcHook(pName);
584eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    if (!hook)
585cc5e2765a9d56b03b69d0c3f25b94721f82d034eChia-I Wu        return GetData(device).driver.GetDeviceProcAddr(device, pName);
586eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
587eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    if (hook->type != ProcHook::DEVICE) {
588e201c3f782f0d3e2ec508fb8093e506145614c06Chia-I Wu        ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
589eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu        return nullptr;
590eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu    }
591eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
59236cc00a1739f7d926cc20671ae9900a5460dd6aeChia-I Wu    return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
59336cc00a1739f7d926cc20671ae9900a5460dd6aeChia-I Wu                                                              : nullptr;
594eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu}
595eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu
596ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuVkResult EnumerateInstanceExtensionProperties(
597ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    const char* pLayerName,
598ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    uint32_t* pPropertyCount,
599ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    VkExtensionProperties* pProperties) {
600ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    static const std::array<VkExtensionProperties, 2> loader_extensions = {{
601ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        // WSI extensions
602ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION},
603ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        {VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
604ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu         VK_KHR_ANDROID_SURFACE_SPEC_VERSION},
605ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    }};
606319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    static const VkExtensionProperties loader_debug_report_extension = {
607319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
608319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    };
609ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
610ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    // enumerate our extensions first
611ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if (!pLayerName && pProperties) {
612ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        uint32_t count = std::min(
613ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu            *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
614ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
615ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        std::copy_n(loader_extensions.begin(), count, pProperties);
616ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
617ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        if (count < loader_extensions.size()) {
618ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu            *pPropertyCount = count;
619ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu            return VK_INCOMPLETE;
620ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        }
621ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
622ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        pProperties += count;
623ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        *pPropertyCount -= count;
624319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
625319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        if (Hal::Get().GetDebugReportIndex() < 0) {
626319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            if (!*pPropertyCount) {
627319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu                *pPropertyCount = count;
628319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu                return VK_INCOMPLETE;
629319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            }
630319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
631319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            pProperties[0] = loader_debug_report_extension;
632319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            pProperties += 1;
633319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            *pPropertyCount -= 1;
634319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        }
635ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    }
636ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
63731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
638ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        pLayerName, pPropertyCount, pProperties);
639ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
640319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
641319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        int idx = Hal::Get().GetDebugReportIndex();
642319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        if (idx < 0) {
643319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            *pPropertyCount += 1;
644319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        } else if (pProperties &&
645319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu                   static_cast<uint32_t>(idx) < *pPropertyCount) {
646319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu            pProperties[idx].specVersion =
647319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu                std::min(pProperties[idx].specVersion,
648319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu                         loader_debug_report_extension.specVersion);
649319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu        }
650319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu
651ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        *pPropertyCount += loader_extensions.size();
652319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu    }
653ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
654ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    return result;
655ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu}
656ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
65701cf305325f3789c573d7eff435e409f04677c66Chia-I WuVkResult EnumerateDeviceExtensionProperties(
65801cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    VkPhysicalDevice physicalDevice,
65901cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    const char* pLayerName,
66001cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    uint32_t* pPropertyCount,
66101cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    VkExtensionProperties* pProperties) {
66201cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    const InstanceData& data = GetData(physicalDevice);
66301cf305325f3789c573d7eff435e409f04677c66Chia-I Wu
66401cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    VkResult result = data.driver.EnumerateDeviceExtensionProperties(
66501cf305325f3789c573d7eff435e409f04677c66Chia-I Wu        physicalDevice, pLayerName, pPropertyCount, pProperties);
66601cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    if (result != VK_SUCCESS && result != VK_INCOMPLETE)
66701cf305325f3789c573d7eff435e409f04677c66Chia-I Wu        return result;
66801cf305325f3789c573d7eff435e409f04677c66Chia-I Wu
66901cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    if (!pProperties)
67001cf305325f3789c573d7eff435e409f04677c66Chia-I Wu        return result;
67101cf305325f3789c573d7eff435e409f04677c66Chia-I Wu
67201cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    // map VK_ANDROID_native_buffer to VK_KHR_swapchain
67301cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    for (uint32_t i = 0; i < *pPropertyCount; i++) {
67401cf305325f3789c573d7eff435e409f04677c66Chia-I Wu        auto& prop = pProperties[i];
67501cf305325f3789c573d7eff435e409f04677c66Chia-I Wu
67601cf305325f3789c573d7eff435e409f04677c66Chia-I Wu        if (strcmp(prop.extensionName,
67701cf305325f3789c573d7eff435e409f04677c66Chia-I Wu                   VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
67801cf305325f3789c573d7eff435e409f04677c66Chia-I Wu            continue;
67901cf305325f3789c573d7eff435e409f04677c66Chia-I Wu
68001cf305325f3789c573d7eff435e409f04677c66Chia-I Wu        memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
68101cf305325f3789c573d7eff435e409f04677c66Chia-I Wu               sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
68201cf305325f3789c573d7eff435e409f04677c66Chia-I Wu        prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
68301cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    }
68401cf305325f3789c573d7eff435e409f04677c66Chia-I Wu
68501cf305325f3789c573d7eff435e409f04677c66Chia-I Wu    return result;
68601cf305325f3789c573d7eff435e409f04677c66Chia-I Wu}
68701cf305325f3789c573d7eff435e409f04677c66Chia-I Wu
688ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuVkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
689ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu                        const VkAllocationCallbacks* pAllocator,
690ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu                        VkInstance* pInstance) {
691ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    const VkAllocationCallbacks& data_allocator =
692ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        (pAllocator) ? *pAllocator : GetDefaultAllocator();
693ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
69431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
6953e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult result = wrapper.Validate();
696ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if (result != VK_SUCCESS)
697ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        return result;
698ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
699ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    InstanceData* data = AllocateInstanceData(data_allocator);
700ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if (!data)
701ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        return VK_ERROR_OUT_OF_HOST_MEMORY;
702ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
7033e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    data->hook_extensions |= wrapper.GetHookExtensions();
704ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
705ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    // call into the driver
706ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    VkInstance instance;
70731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu    result = Hal::Device().CreateInstance(
708ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
709ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        &instance);
710ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if (result != VK_SUCCESS) {
711ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        FreeInstanceData(data, data_allocator);
712ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        return result;
713ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    }
714ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
715ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    // initialize InstanceDriverTable
716ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if (!SetData(instance, *data) ||
71731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
718cbe07ef239121dc99a31a19b9593d76d76abb08bChia-I Wu                         wrapper.GetHalExtensions())) {
719ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
72031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu            Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
721ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        if (data->driver.DestroyInstance)
722ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu            data->driver.DestroyInstance(instance, pAllocator);
723ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
724ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        FreeInstanceData(data, data_allocator);
725ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
726ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        return VK_ERROR_INCOMPATIBLE_DRIVER;
727ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    }
728ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
729ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
73031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu        Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
731ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if (!data->get_device_proc_addr) {
732ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        data->driver.DestroyInstance(instance, pAllocator);
733ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        FreeInstanceData(data, data_allocator);
734ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
735ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        return VK_ERROR_INCOMPATIBLE_DRIVER;
736ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    }
737ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
738ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    *pInstance = instance;
739ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
740ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    return VK_SUCCESS;
741ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu}
742ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
743ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wuvoid DestroyInstance(VkInstance instance,
744ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu                     const VkAllocationCallbacks* pAllocator) {
745ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    InstanceData& data = GetData(instance);
746ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    data.driver.DestroyInstance(instance, pAllocator);
747ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
748ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    VkAllocationCallbacks local_allocator;
749ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if (!pAllocator) {
750ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        local_allocator = data.allocator;
751ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        pAllocator = &local_allocator;
752ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    }
753ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
754ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    FreeInstanceData(&data, *pAllocator);
755ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu}
756ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
7574901db70b12801cf1966937a58eb7566bfdeb4ceChia-I WuVkResult CreateDevice(VkPhysicalDevice physicalDevice,
7584901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                      const VkDeviceCreateInfo* pCreateInfo,
7594901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                      const VkAllocationCallbacks* pAllocator,
7604901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu                      VkDevice* pDevice) {
7614901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    const InstanceData& instance_data = GetData(physicalDevice);
7624901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    const VkAllocationCallbacks& data_allocator =
7634901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        (pAllocator) ? *pAllocator : instance_data.allocator;
7644901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
7654901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
7663e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    VkResult result = wrapper.Validate();
7674901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (result != VK_SUCCESS)
7684901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return result;
7694901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
770950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu    DeviceData* data = AllocateDeviceData(data_allocator,
771950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu                                          instance_data.debug_report_callbacks);
7724901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (!data)
7734901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return VK_ERROR_OUT_OF_HOST_MEMORY;
7744901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
7753e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu    data->hook_extensions |= wrapper.GetHookExtensions();
7764901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
7774901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    // call into the driver
7784901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    VkDevice dev;
7794901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    result = instance_data.driver.CreateDevice(
7804901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
7814901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        pAllocator, &dev);
7824901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (result != VK_SUCCESS) {
7834901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        FreeDeviceData(data, data_allocator);
7844901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return result;
7854901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    }
7864901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
7874901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    // initialize DeviceDriverTable
7884901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (!SetData(dev, *data) ||
789cbe07ef239121dc99a31a19b9593d76d76abb08bChia-I Wu        !InitDriverTable(dev, instance_data.get_device_proc_addr,
790cbe07ef239121dc99a31a19b9593d76d76abb08bChia-I Wu                         wrapper.GetHalExtensions())) {
7914901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
7924901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
7934901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        if (data->driver.DestroyDevice)
7944901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu            data->driver.DestroyDevice(dev, pAllocator);
7954901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
7964901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        FreeDeviceData(data, data_allocator);
7974901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
7984901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        return VK_ERROR_INCOMPATIBLE_DRIVER;
7994901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    }
800dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall    data->driver_device = dev;
8014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
8024901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    *pDevice = dev;
8034901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
8044901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    return VK_SUCCESS;
8054901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
8064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
8074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuvoid DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
8084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    DeviceData& data = GetData(device);
8094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    data.driver.DestroyDevice(device, pAllocator);
8104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
8114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    VkAllocationCallbacks local_allocator;
8124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    if (!pAllocator) {
8134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        local_allocator = data.allocator;
8144901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu        pAllocator = &local_allocator;
8154901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    }
8164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
8174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu    FreeDeviceData(&data, *pAllocator);
8184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}
8194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu
820ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuVkResult EnumeratePhysicalDevices(VkInstance instance,
821ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu                                  uint32_t* pPhysicalDeviceCount,
822ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu                                  VkPhysicalDevice* pPhysicalDevices) {
823ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    const auto& data = GetData(instance);
824ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
825ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    VkResult result = data.driver.EnumeratePhysicalDevices(
826ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        instance, pPhysicalDeviceCount, pPhysicalDevices);
827ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
828ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu        for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
829ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu            SetData(pPhysicalDevices[i], data);
830ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    }
831ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
832ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu    return result;
833ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu}
834ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu
835ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wuvoid GetDeviceQueue(VkDevice device,
836ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu                    uint32_t queueFamilyIndex,
837ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu                    uint32_t queueIndex,
838ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu                    VkQueue* pQueue) {
839ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu    const auto& data = GetData(device);
840ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu
841ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu    data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
842ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu    SetData(*pQueue, data);
843ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu}
844ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu
8456a58a8a7813450038cb15575e3333b83f268c972Chia-I WuVKAPI_ATTR VkResult
8466a58a8a7813450038cb15575e3333b83f268c972Chia-I WuAllocateCommandBuffers(VkDevice device,
8476a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu                       const VkCommandBufferAllocateInfo* pAllocateInfo,
8486a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu                       VkCommandBuffer* pCommandBuffers) {
8496a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu    const auto& data = GetData(device);
8506a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu
8516a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu    VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
8526a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu                                                         pCommandBuffers);
8536a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu    if (result == VK_SUCCESS) {
8546a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu        for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
8556a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu            SetData(pCommandBuffers[i], data);
8566a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu    }
8576a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu
8586a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu    return result;
8596a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu}
8606a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu
8619d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu}  // namespace driver
8629d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu}  // namespace vulkan
863