| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2016 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 |  | 
 | 17 | #include "VulkanManager.h" | 
 | 18 |  | 
| Alec Mouri | 6db59a6 | 2019-08-02 17:05:26 -0700 | [diff] [blame] | 19 | #include <EGL/egl.h> | 
 | 20 | #include <EGL/eglext.h> | 
| Stan Iliev | aaa9e83 | 2019-09-17 14:07:23 -0400 | [diff] [blame] | 21 | #include <GrBackendSemaphore.h> | 
 | 22 | #include <GrBackendSurface.h> | 
| Adlai Holler | f8c434e | 2020-07-27 11:42:45 -0400 | [diff] [blame] | 23 | #include <GrDirectContext.h> | 
| Stan Iliev | aaa9e83 | 2019-09-17 14:07:23 -0400 | [diff] [blame] | 24 | #include <GrTypes.h> | 
 | 25 | #include <android/sync.h> | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 26 | #include <gui/TraceUtils.h> | 
 | 27 | #include <include/gpu/ganesh/SkSurfaceGanesh.h> | 
| Jagadeesh Pakaravoor | b624af3 | 2020-05-01 00:01:40 +0000 | [diff] [blame] | 28 | #include <ui/FatVector.h> | 
| Stan Iliev | aaa9e83 | 2019-09-17 14:07:23 -0400 | [diff] [blame] | 29 | #include <vk/GrVkExtensions.h> | 
 | 30 | #include <vk/GrVkTypes.h> | 
| Stan Iliev | 305e13a | 2018-11-13 11:14:48 -0500 | [diff] [blame] | 31 |  | 
| Greg Daniel | cd55852 | 2016-11-17 13:31:40 -0500 | [diff] [blame] | 32 | #include "Properties.h" | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 33 | #include "RenderThread.h" | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 34 | #include "pipeline/skia/ShaderCache.h" | 
| Greg Daniel | 45ec62b | 2017-01-04 14:27:00 -0500 | [diff] [blame] | 35 | #include "renderstate/RenderState.h" | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 36 |  | 
| Leon Scroggins III | 7ccb8a4 | 2021-11-30 14:17:28 -0500 | [diff] [blame] | 37 | #undef LOG_TAG | 
 | 38 | #define LOG_TAG "VulkanManager" | 
 | 39 |  | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 40 | namespace android { | 
 | 41 | namespace uirenderer { | 
 | 42 | namespace renderthread { | 
 | 43 |  | 
| John Reck | 90b244d | 2023-04-28 15:41:55 -0400 | [diff] [blame] | 44 | static std::array<std::string_view, 19> sEnableExtensions{ | 
| John Reck | f6067df | 2023-04-11 16:27:51 -0400 | [diff] [blame] | 45 |         VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, | 
 | 46 |         VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, | 
 | 47 |         VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, | 
 | 48 |         VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, | 
 | 49 |         VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, | 
 | 50 |         VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, | 
 | 51 |         VK_KHR_MAINTENANCE1_EXTENSION_NAME, | 
 | 52 |         VK_KHR_MAINTENANCE2_EXTENSION_NAME, | 
 | 53 |         VK_KHR_MAINTENANCE3_EXTENSION_NAME, | 
 | 54 |         VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, | 
 | 55 |         VK_KHR_SURFACE_EXTENSION_NAME, | 
 | 56 |         VK_KHR_SWAPCHAIN_EXTENSION_NAME, | 
 | 57 |         VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, | 
| John Reck | 90b244d | 2023-04-28 15:41:55 -0400 | [diff] [blame] | 58 |         VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, | 
| John Reck | f6067df | 2023-04-11 16:27:51 -0400 | [diff] [blame] | 59 |         VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, | 
 | 60 |         VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, | 
 | 61 |         VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, | 
 | 62 |         VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, | 
 | 63 |         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, | 
 | 64 | }; | 
 | 65 |  | 
 | 66 | static bool shouldEnableExtension(const std::string_view& extension) { | 
 | 67 |     for (const auto& it : sEnableExtensions) { | 
 | 68 |         if (it == extension) { | 
 | 69 |             return true; | 
 | 70 |         } | 
 | 71 |     } | 
 | 72 |     return false; | 
 | 73 | } | 
 | 74 |  | 
| Bo Liu | 7b8c1eb | 2019-01-08 20:17:55 -0800 | [diff] [blame] | 75 | static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& features) { | 
 | 76 |     // All Vulkan structs that could be part of the features chain will start with the | 
 | 77 |     // structure type followed by the pNext pointer. We cast to the CommonVulkanHeader | 
 | 78 |     // so we can get access to the pNext for the next struct. | 
 | 79 |     struct CommonVulkanHeader { | 
 | 80 |         VkStructureType sType; | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 81 |         void* pNext; | 
| Bo Liu | 7b8c1eb | 2019-01-08 20:17:55 -0800 | [diff] [blame] | 82 |     }; | 
 | 83 |  | 
 | 84 |     void* pNext = features.pNext; | 
 | 85 |     while (pNext) { | 
 | 86 |         void* current = pNext; | 
 | 87 |         pNext = static_cast<CommonVulkanHeader*>(current)->pNext; | 
 | 88 |         free(current); | 
 | 89 |     } | 
 | 90 | } | 
 | 91 |  | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 92 | #define GET_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vk" #F) | 
 | 93 | #define GET_INST_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(mInstance, "vk" #F) | 
 | 94 | #define GET_DEV_PROC(F) m##F = (PFN_vk##F)vkGetDeviceProcAddr(mDevice, "vk" #F) | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 95 |  | 
| John Reck | 9fc3d27 | 2023-05-01 16:33:22 -0400 | [diff] [blame] | 96 | // cache a weakptr to the context to enable a second thread to share the same vulkan state | 
 | 97 | static wp<VulkanManager> sWeakInstance = nullptr; | 
 | 98 | static std::mutex sLock; | 
| Derek Sollenberger | 802fefa | 2020-08-13 16:53:30 -0400 | [diff] [blame] | 99 |  | 
| John Reck | 9fc3d27 | 2023-05-01 16:33:22 -0400 | [diff] [blame] | 100 | sp<VulkanManager> VulkanManager::getInstance() { | 
| Derek Sollenberger | 802fefa | 2020-08-13 16:53:30 -0400 | [diff] [blame] | 101 |     std::lock_guard _lock{sLock}; | 
 | 102 |     sp<VulkanManager> vulkanManager = sWeakInstance.promote(); | 
 | 103 |     if (!vulkanManager.get()) { | 
 | 104 |         vulkanManager = new VulkanManager(); | 
 | 105 |         sWeakInstance = vulkanManager; | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 106 |     } | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 107 |  | 
| Derek Sollenberger | 802fefa | 2020-08-13 16:53:30 -0400 | [diff] [blame] | 108 |     return vulkanManager; | 
 | 109 | } | 
 | 110 |  | 
| John Reck | 9fc3d27 | 2023-05-01 16:33:22 -0400 | [diff] [blame] | 111 | sp<VulkanManager> VulkanManager::peekInstance() { | 
 | 112 |     std::lock_guard _lock{sLock}; | 
 | 113 |     return sWeakInstance.promote(); | 
 | 114 | } | 
 | 115 |  | 
| Derek Sollenberger | 802fefa | 2020-08-13 16:53:30 -0400 | [diff] [blame] | 116 | VulkanManager::~VulkanManager() { | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 117 |     if (mDevice != VK_NULL_HANDLE) { | 
 | 118 |         mDeviceWaitIdle(mDevice); | 
 | 119 |         mDestroyDevice(mDevice, nullptr); | 
| John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 120 |     } | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 121 |  | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 122 |     if (mInstance != VK_NULL_HANDLE) { | 
 | 123 |         mDestroyInstance(mInstance, nullptr); | 
 | 124 |     } | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 125 |  | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 126 |     mGraphicsQueue = VK_NULL_HANDLE; | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 127 |     mAHBUploadQueue = VK_NULL_HANDLE; | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 128 |     mDevice = VK_NULL_HANDLE; | 
 | 129 |     mPhysicalDevice = VK_NULL_HANDLE; | 
 | 130 |     mInstance = VK_NULL_HANDLE; | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 131 |     mInstanceExtensionsOwner.clear(); | 
| Bo Liu | 7b8c1eb | 2019-01-08 20:17:55 -0800 | [diff] [blame] | 132 |     mInstanceExtensions.clear(); | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 133 |     mDeviceExtensionsOwner.clear(); | 
| Bo Liu | 7b8c1eb | 2019-01-08 20:17:55 -0800 | [diff] [blame] | 134 |     mDeviceExtensions.clear(); | 
 | 135 |     free_features_extensions_structs(mPhysicalDeviceFeatures2); | 
 | 136 |     mPhysicalDeviceFeatures2 = {}; | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 137 | } | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 138 |  | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 139 | void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFeatures2& features) { | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 140 |     VkResult err; | 
 | 141 |  | 
 | 142 |     constexpr VkApplicationInfo app_info = { | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 143 |             VK_STRUCTURE_TYPE_APPLICATION_INFO,  // sType | 
 | 144 |             nullptr,                             // pNext | 
 | 145 |             "android framework",                 // pApplicationName | 
 | 146 |             0,                                   // applicationVersion | 
 | 147 |             "android framework",                 // pEngineName | 
 | 148 |             0,                                   // engineVerison | 
 | 149 |             mAPIVersion,                         // apiVersion | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 150 |     }; | 
 | 151 |  | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 152 |     { | 
 | 153 |         GET_PROC(EnumerateInstanceExtensionProperties); | 
 | 154 |  | 
 | 155 |         uint32_t extensionCount = 0; | 
 | 156 |         err = mEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 157 |         LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err); | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 158 |         mInstanceExtensionsOwner.resize(extensionCount); | 
 | 159 |         err = mEnumerateInstanceExtensionProperties(nullptr, &extensionCount, | 
 | 160 |                                                     mInstanceExtensionsOwner.data()); | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 161 |         LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 162 |         bool hasKHRSurfaceExtension = false; | 
 | 163 |         bool hasKHRAndroidSurfaceExtension = false; | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 164 |         for (const VkExtensionProperties& extension : mInstanceExtensionsOwner) { | 
| John Reck | f6067df | 2023-04-11 16:27:51 -0400 | [diff] [blame] | 165 |             if (!shouldEnableExtension(extension.extensionName)) { | 
 | 166 |                 ALOGV("Not enabling instance extension %s", extension.extensionName); | 
 | 167 |                 continue; | 
 | 168 |             } | 
 | 169 |             ALOGV("Enabling instance extension %s", extension.extensionName); | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 170 |             mInstanceExtensions.push_back(extension.extensionName); | 
 | 171 |             if (!strcmp(extension.extensionName, VK_KHR_SURFACE_EXTENSION_NAME)) { | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 172 |                 hasKHRSurfaceExtension = true; | 
 | 173 |             } | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 174 |             if (!strcmp(extension.extensionName, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME)) { | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 175 |                 hasKHRAndroidSurfaceExtension = true; | 
 | 176 |             } | 
 | 177 |         } | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 178 |         LOG_ALWAYS_FATAL_IF(!hasKHRSurfaceExtension || !hasKHRAndroidSurfaceExtension); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 179 |     } | 
 | 180 |  | 
 | 181 |     const VkInstanceCreateInfo instance_create = { | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 182 |             VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,  // sType | 
 | 183 |             nullptr,                                 // pNext | 
 | 184 |             0,                                       // flags | 
 | 185 |             &app_info,                               // pApplicationInfo | 
 | 186 |             0,                                       // enabledLayerNameCount | 
 | 187 |             nullptr,                                 // ppEnabledLayerNames | 
 | 188 |             (uint32_t)mInstanceExtensions.size(),    // enabledExtensionNameCount | 
 | 189 |             mInstanceExtensions.data(),              // ppEnabledExtensionNames | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 190 |     }; | 
 | 191 |  | 
 | 192 |     GET_PROC(CreateInstance); | 
 | 193 |     err = mCreateInstance(&instance_create, nullptr, &mInstance); | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 194 |     LOG_ALWAYS_FATAL_IF(err < 0); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 195 |  | 
| Yiwei Zhang | 0b9f0b8 | 2019-08-15 11:33:59 -0700 | [diff] [blame] | 196 |     GET_INST_PROC(CreateDevice); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 197 |     GET_INST_PROC(DestroyInstance); | 
| Yiwei Zhang | 0b9f0b8 | 2019-08-15 11:33:59 -0700 | [diff] [blame] | 198 |     GET_INST_PROC(EnumerateDeviceExtensionProperties); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 199 |     GET_INST_PROC(EnumeratePhysicalDevices); | 
| Greg Daniel | a227dbb | 2018-08-20 09:19:48 -0400 | [diff] [blame] | 200 |     GET_INST_PROC(GetPhysicalDeviceFeatures2); | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 201 |     GET_INST_PROC(GetPhysicalDeviceImageFormatProperties2); | 
| Yiwei Zhang | 0b9f0b8 | 2019-08-15 11:33:59 -0700 | [diff] [blame] | 202 |     GET_INST_PROC(GetPhysicalDeviceProperties); | 
 | 203 |     GET_INST_PROC(GetPhysicalDeviceQueueFamilyProperties); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 204 |  | 
 | 205 |     uint32_t gpuCount; | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 206 |     LOG_ALWAYS_FATAL_IF(mEnumeratePhysicalDevices(mInstance, &gpuCount, nullptr)); | 
 | 207 |     LOG_ALWAYS_FATAL_IF(!gpuCount); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 208 |     // Just returning the first physical device instead of getting the whole array. Since there | 
 | 209 |     // should only be one device on android. | 
 | 210 |     gpuCount = 1; | 
 | 211 |     err = mEnumeratePhysicalDevices(mInstance, &gpuCount, &mPhysicalDevice); | 
 | 212 |     // VK_INCOMPLETE is returned when the count we provide is less than the total device count. | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 213 |     LOG_ALWAYS_FATAL_IF(err && VK_INCOMPLETE != err); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 214 |  | 
| Greg Daniel | 9625962 | 2018-10-01 14:42:56 -0400 | [diff] [blame] | 215 |     VkPhysicalDeviceProperties physDeviceProperties; | 
 | 216 |     mGetPhysicalDeviceProperties(mPhysicalDevice, &physDeviceProperties); | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 217 |     LOG_ALWAYS_FATAL_IF(physDeviceProperties.apiVersion < VK_MAKE_VERSION(1, 1, 0)); | 
| Stan Iliev | bf99c44 | 2019-03-29 11:09:11 -0400 | [diff] [blame] | 218 |     mDriverVersion = physDeviceProperties.driverVersion; | 
| Greg Daniel | 9625962 | 2018-10-01 14:42:56 -0400 | [diff] [blame] | 219 |  | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 220 |     // query to get the initial queue props size | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 221 |     uint32_t queueCount = 0; | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 222 |     mGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, nullptr); | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 223 |     LOG_ALWAYS_FATAL_IF(!queueCount); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 224 |  | 
 | 225 |     // now get the actual queue props | 
 | 226 |     std::unique_ptr<VkQueueFamilyProperties[]> queueProps(new VkQueueFamilyProperties[queueCount]); | 
 | 227 |     mGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, queueProps.get()); | 
 | 228 |  | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 229 |     constexpr auto kRequestedQueueCount = 2; | 
 | 230 |  | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 231 |     // iterate to find the graphics queue | 
 | 232 |     mGraphicsQueueIndex = queueCount; | 
 | 233 |     for (uint32_t i = 0; i < queueCount; i++) { | 
 | 234 |         if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { | 
 | 235 |             mGraphicsQueueIndex = i; | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 236 |             LOG_ALWAYS_FATAL_IF(queueProps[i].queueCount < kRequestedQueueCount); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 237 |             break; | 
 | 238 |         } | 
 | 239 |     } | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 240 |     LOG_ALWAYS_FATAL_IF(mGraphicsQueueIndex == queueCount); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 241 |  | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 242 |     { | 
 | 243 |         uint32_t extensionCount = 0; | 
 | 244 |         err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount, | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 245 |                                                   nullptr); | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 246 |         LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err); | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 247 |         mDeviceExtensionsOwner.resize(extensionCount); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 248 |         err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount, | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 249 |                                                   mDeviceExtensionsOwner.data()); | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 250 |         LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 251 |         bool hasKHRSwapchainExtension = false; | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 252 |         for (const VkExtensionProperties& extension : mDeviceExtensionsOwner) { | 
| John Reck | f6067df | 2023-04-11 16:27:51 -0400 | [diff] [blame] | 253 |             if (!shouldEnableExtension(extension.extensionName)) { | 
 | 254 |                 ALOGV("Not enabling device extension %s", extension.extensionName); | 
 | 255 |                 continue; | 
 | 256 |             } | 
 | 257 |             ALOGV("Enabling device extension %s", extension.extensionName); | 
| Roman Kiryanov | 74ace839e | 2019-03-07 18:22:19 -0800 | [diff] [blame] | 258 |             mDeviceExtensions.push_back(extension.extensionName); | 
 | 259 |             if (!strcmp(extension.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME)) { | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 260 |                 hasKHRSwapchainExtension = true; | 
 | 261 |             } | 
 | 262 |         } | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 263 |         LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 264 |     } | 
 | 265 |  | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 266 |     auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) { | 
 | 267 |         if (device != VK_NULL_HANDLE) { | 
 | 268 |             return vkGetDeviceProcAddr(device, proc_name); | 
 | 269 |         } | 
 | 270 |         return vkGetInstanceProcAddr(instance, proc_name); | 
 | 271 |     }; | 
 | 272 |  | 
 | 273 |     grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(), | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 274 |                       mInstanceExtensions.data(), mDeviceExtensions.size(), | 
 | 275 |                       mDeviceExtensions.data()); | 
| Greg Daniel | a227dbb | 2018-08-20 09:19:48 -0400 | [diff] [blame] | 276 |  | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 277 |     LOG_ALWAYS_FATAL_IF(!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)); | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 278 |  | 
| Greg Daniel | a227dbb | 2018-08-20 09:19:48 -0400 | [diff] [blame] | 279 |     memset(&features, 0, sizeof(VkPhysicalDeviceFeatures2)); | 
 | 280 |     features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; | 
 | 281 |     features.pNext = nullptr; | 
 | 282 |  | 
 | 283 |     // Setup all extension feature structs we may want to use. | 
 | 284 |     void** tailPNext = &features.pNext; | 
 | 285 |  | 
 | 286 |     if (grExtensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2)) { | 
 | 287 |         VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT* blend; | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 288 |         blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*)malloc( | 
| Greg Daniel | a227dbb | 2018-08-20 09:19:48 -0400 | [diff] [blame] | 289 |                 sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT)); | 
 | 290 |         LOG_ALWAYS_FATAL_IF(!blend); | 
 | 291 |         blend->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT; | 
 | 292 |         blend->pNext = nullptr; | 
 | 293 |         *tailPNext = blend; | 
 | 294 |         tailPNext = &blend->pNext; | 
 | 295 |     } | 
 | 296 |  | 
| Greg Daniel | 0503617 | 2018-11-28 17:08:04 -0500 | [diff] [blame] | 297 |     VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeature; | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 298 |     ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)malloc( | 
| Greg Daniel | 0503617 | 2018-11-28 17:08:04 -0500 | [diff] [blame] | 299 |             sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures)); | 
 | 300 |     LOG_ALWAYS_FATAL_IF(!ycbcrFeature); | 
 | 301 |     ycbcrFeature->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES; | 
 | 302 |     ycbcrFeature->pNext = nullptr; | 
 | 303 |     *tailPNext = ycbcrFeature; | 
 | 304 |     tailPNext = &ycbcrFeature->pNext; | 
 | 305 |  | 
| Greg Daniel | a227dbb | 2018-08-20 09:19:48 -0400 | [diff] [blame] | 306 |     // query to get the physical device features | 
 | 307 |     mGetPhysicalDeviceFeatures2(mPhysicalDevice, &features); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 308 |     // this looks like it would slow things down, | 
 | 309 |     // and we can't depend on it on all platforms | 
| Greg Daniel | a227dbb | 2018-08-20 09:19:48 -0400 | [diff] [blame] | 310 |     features.features.robustBufferAccess = VK_FALSE; | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 311 |  | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 312 |     float queuePriorities[kRequestedQueueCount] = {0.0}; | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 313 |  | 
| Stan Iliev | 7e73336 | 2019-02-28 13:16:36 -0500 | [diff] [blame] | 314 |     void* queueNextPtr = nullptr; | 
 | 315 |  | 
 | 316 |     VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo; | 
 | 317 |  | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 318 |     if (Properties::contextPriority != 0 && | 
 | 319 |         grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) { | 
| Stan Iliev | 7e73336 | 2019-02-28 13:16:36 -0500 | [diff] [blame] | 320 |         memset(&queuePriorityCreateInfo, 0, sizeof(VkDeviceQueueGlobalPriorityCreateInfoEXT)); | 
 | 321 |         queuePriorityCreateInfo.sType = | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 322 |                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT; | 
| Stan Iliev | 7e73336 | 2019-02-28 13:16:36 -0500 | [diff] [blame] | 323 |         queuePriorityCreateInfo.pNext = nullptr; | 
 | 324 |         switch (Properties::contextPriority) { | 
 | 325 |             case EGL_CONTEXT_PRIORITY_LOW_IMG: | 
 | 326 |                 queuePriorityCreateInfo.globalPriority = VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT; | 
 | 327 |                 break; | 
 | 328 |             case EGL_CONTEXT_PRIORITY_MEDIUM_IMG: | 
 | 329 |                 queuePriorityCreateInfo.globalPriority = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT; | 
 | 330 |                 break; | 
 | 331 |             case EGL_CONTEXT_PRIORITY_HIGH_IMG: | 
 | 332 |                 queuePriorityCreateInfo.globalPriority = VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT; | 
 | 333 |                 break; | 
 | 334 |             default: | 
 | 335 |                 LOG_ALWAYS_FATAL("Unsupported context priority"); | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 336 |         } | 
 | 337 |         queueNextPtr = &queuePriorityCreateInfo; | 
| Stan Iliev | 7e73336 | 2019-02-28 13:16:36 -0500 | [diff] [blame] | 338 |     } | 
 | 339 |  | 
| Yiwei Zhang | 276d5fc | 2020-09-03 12:00:00 -0700 | [diff] [blame] | 340 |     const VkDeviceQueueCreateInfo queueInfo = { | 
 | 341 |             VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,  // sType | 
 | 342 |             queueNextPtr,                                // pNext | 
 | 343 |             0,                                           // VkDeviceQueueCreateFlags | 
 | 344 |             mGraphicsQueueIndex,                         // queueFamilyIndex | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 345 |             kRequestedQueueCount,                        // queueCount | 
| Yiwei Zhang | 276d5fc | 2020-09-03 12:00:00 -0700 | [diff] [blame] | 346 |             queuePriorities,                             // pQueuePriorities | 
 | 347 |     }; | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 348 |  | 
 | 349 |     const VkDeviceCreateInfo deviceInfo = { | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 350 |             VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,  // sType | 
 | 351 |             &features,                             // pNext | 
 | 352 |             0,                                     // VkDeviceCreateFlags | 
| Yiwei Zhang | 276d5fc | 2020-09-03 12:00:00 -0700 | [diff] [blame] | 353 |             1,                                     // queueCreateInfoCount | 
 | 354 |             &queueInfo,                            // pQueueCreateInfos | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 355 |             0,                                     // layerCount | 
 | 356 |             nullptr,                               // ppEnabledLayerNames | 
 | 357 |             (uint32_t)mDeviceExtensions.size(),    // extensionCount | 
 | 358 |             mDeviceExtensions.data(),              // ppEnabledExtensionNames | 
 | 359 |             nullptr,                               // ppEnabledFeatures | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 360 |     }; | 
 | 361 |  | 
| Stan Iliev | 90276c8 | 2019-02-03 18:01:02 -0500 | [diff] [blame] | 362 |     LOG_ALWAYS_FATAL_IF(mCreateDevice(mPhysicalDevice, &deviceInfo, nullptr, &mDevice)); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 363 |  | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 364 |     GET_DEV_PROC(AllocateCommandBuffers); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 365 |     GET_DEV_PROC(BeginCommandBuffer); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 366 |     GET_DEV_PROC(CmdPipelineBarrier); | 
| Yiwei Zhang | 0b9f0b8 | 2019-08-15 11:33:59 -0700 | [diff] [blame] | 367 |     GET_DEV_PROC(CreateCommandPool); | 
 | 368 |     GET_DEV_PROC(CreateFence); | 
 | 369 |     GET_DEV_PROC(CreateSemaphore); | 
 | 370 |     GET_DEV_PROC(DestroyCommandPool); | 
 | 371 |     GET_DEV_PROC(DestroyDevice); | 
 | 372 |     GET_DEV_PROC(DestroyFence); | 
 | 373 |     GET_DEV_PROC(DestroySemaphore); | 
 | 374 |     GET_DEV_PROC(DeviceWaitIdle); | 
 | 375 |     GET_DEV_PROC(EndCommandBuffer); | 
 | 376 |     GET_DEV_PROC(FreeCommandBuffers); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 377 |     GET_DEV_PROC(GetDeviceQueue); | 
| Yiwei Zhang | 0b9f0b8 | 2019-08-15 11:33:59 -0700 | [diff] [blame] | 378 |     GET_DEV_PROC(GetSemaphoreFdKHR); | 
 | 379 |     GET_DEV_PROC(ImportSemaphoreFdKHR); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 380 |     GET_DEV_PROC(QueueSubmit); | 
 | 381 |     GET_DEV_PROC(QueueWaitIdle); | 
| Yiwei Zhang | 0b9f0b8 | 2019-08-15 11:33:59 -0700 | [diff] [blame] | 382 |     GET_DEV_PROC(ResetCommandBuffer); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 383 |     GET_DEV_PROC(ResetFences); | 
| Yiwei Zhang | 0b9f0b8 | 2019-08-15 11:33:59 -0700 | [diff] [blame] | 384 |     GET_DEV_PROC(WaitForFences); | 
| Hugues Evrard | b9510a0 | 2021-03-01 14:35:22 +0000 | [diff] [blame] | 385 |     GET_DEV_PROC(FrameBoundaryANDROID); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 386 | } | 
 | 387 |  | 
 | 388 | void VulkanManager::initialize() { | 
| Greg Daniel | 1d9de71 | 2021-05-14 09:28:34 -0400 | [diff] [blame] | 389 |     std::lock_guard _lock{mInitializeLock}; | 
 | 390 |  | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 391 |     if (mDevice != VK_NULL_HANDLE) { | 
 | 392 |         return; | 
 | 393 |     } | 
 | 394 |  | 
| Greg Daniel | a227dbb | 2018-08-20 09:19:48 -0400 | [diff] [blame] | 395 |     GET_PROC(EnumerateInstanceVersion); | 
| Greg Daniel | eaf310e | 2019-01-28 16:10:32 -0500 | [diff] [blame] | 396 |     uint32_t instanceVersion; | 
 | 397 |     LOG_ALWAYS_FATAL_IF(mEnumerateInstanceVersion(&instanceVersion)); | 
 | 398 |     LOG_ALWAYS_FATAL_IF(instanceVersion < VK_MAKE_VERSION(1, 1, 0)); | 
| Greg Daniel | a227dbb | 2018-08-20 09:19:48 -0400 | [diff] [blame] | 399 |  | 
| Stan Iliev | 981afe7 | 2019-02-13 14:24:33 -0500 | [diff] [blame] | 400 |     this->setupDevice(mExtensions, mPhysicalDeviceFeatures2); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 401 |  | 
 | 402 |     mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue); | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 403 |     mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue); | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 404 |  | 
| Greg Daniel | cd55852 | 2016-11-17 13:31:40 -0500 | [diff] [blame] | 405 |     if (Properties::enablePartialUpdates && Properties::useBufferAge) { | 
 | 406 |         mSwapBehavior = SwapBehavior::BufferAge; | 
 | 407 |     } | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 408 | } | 
 | 409 |  | 
| John Reck | 9fc3d27 | 2023-05-01 16:33:22 -0400 | [diff] [blame] | 410 | static void onGrContextReleased(void* context) { | 
 | 411 |     VulkanManager* manager = (VulkanManager*)context; | 
 | 412 |     manager->decStrong((void*)onGrContextReleased); | 
 | 413 | } | 
| Stan Iliev | 981afe7 | 2019-02-13 14:24:33 -0500 | [diff] [blame] | 414 |  | 
| John Reck | 9fc3d27 | 2023-05-01 16:33:22 -0400 | [diff] [blame] | 415 | sk_sp<GrDirectContext> VulkanManager::createContext(GrContextOptions& options, | 
 | 416 |                                                     ContextType contextType) { | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 417 |     auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) { | 
 | 418 |         if (device != VK_NULL_HANDLE) { | 
 | 419 |             return vkGetDeviceProcAddr(device, proc_name); | 
 | 420 |         } | 
 | 421 |         return vkGetInstanceProcAddr(instance, proc_name); | 
 | 422 |     }; | 
 | 423 |  | 
| Stan Iliev | 981afe7 | 2019-02-13 14:24:33 -0500 | [diff] [blame] | 424 |     GrVkBackendContext backendContext; | 
 | 425 |     backendContext.fInstance = mInstance; | 
 | 426 |     backendContext.fPhysicalDevice = mPhysicalDevice; | 
 | 427 |     backendContext.fDevice = mDevice; | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 428 |     backendContext.fQueue = | 
 | 429 |             (contextType == ContextType::kRenderThread) ? mGraphicsQueue : mAHBUploadQueue; | 
| Stan Iliev | 981afe7 | 2019-02-13 14:24:33 -0500 | [diff] [blame] | 430 |     backendContext.fGraphicsQueueIndex = mGraphicsQueueIndex; | 
 | 431 |     backendContext.fMaxAPIVersion = mAPIVersion; | 
 | 432 |     backendContext.fVkExtensions = &mExtensions; | 
 | 433 |     backendContext.fDeviceFeatures2 = &mPhysicalDeviceFeatures2; | 
| Alec Mouri | 219997a | 2023-05-23 17:25:19 +0000 | [diff] [blame] | 434 |     backendContext.fGetProc = std::move(getProc); | 
| Stan Iliev | 981afe7 | 2019-02-13 14:24:33 -0500 | [diff] [blame] | 435 |  | 
| John Reck | 9fc3d27 | 2023-05-01 16:33:22 -0400 | [diff] [blame] | 436 |     LOG_ALWAYS_FATAL_IF(options.fContextDeleteProc != nullptr, "Conflicting fContextDeleteProcs!"); | 
 | 437 |     this->incStrong((void*)onGrContextReleased); | 
 | 438 |     options.fContextDeleteContext = this; | 
 | 439 |     options.fContextDeleteProc = onGrContextReleased; | 
 | 440 |  | 
| Adlai Holler | f8c434e | 2020-07-27 11:42:45 -0400 | [diff] [blame] | 441 |     return GrDirectContext::MakeVulkan(backendContext, options); | 
| Stan Iliev | 981afe7 | 2019-02-13 14:24:33 -0500 | [diff] [blame] | 442 | } | 
 | 443 |  | 
| Bo Liu | 7b8c1eb | 2019-01-08 20:17:55 -0800 | [diff] [blame] | 444 | VkFunctorInitParams VulkanManager::getVkFunctorInitParams() const { | 
 | 445 |     return VkFunctorInitParams{ | 
 | 446 |             .instance = mInstance, | 
 | 447 |             .physical_device = mPhysicalDevice, | 
 | 448 |             .device = mDevice, | 
 | 449 |             .queue = mGraphicsQueue, | 
 | 450 |             .graphics_queue_index = mGraphicsQueueIndex, | 
| Greg Daniel | eaf310e | 2019-01-28 16:10:32 -0500 | [diff] [blame] | 451 |             .api_version = mAPIVersion, | 
| Bo Liu | 7b8c1eb | 2019-01-08 20:17:55 -0800 | [diff] [blame] | 452 |             .enabled_instance_extension_names = mInstanceExtensions.data(), | 
 | 453 |             .enabled_instance_extension_names_length = | 
 | 454 |                     static_cast<uint32_t>(mInstanceExtensions.size()), | 
 | 455 |             .enabled_device_extension_names = mDeviceExtensions.data(), | 
 | 456 |             .enabled_device_extension_names_length = | 
 | 457 |                     static_cast<uint32_t>(mDeviceExtensions.size()), | 
 | 458 |             .device_features_2 = &mPhysicalDeviceFeatures2, | 
 | 459 |     }; | 
 | 460 | } | 
 | 461 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 462 | Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) { | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 463 |     VulkanSurface::NativeBufferInfo* bufferInfo = surface->dequeueNativeBuffer(); | 
 | 464 |  | 
 | 465 |     if (bufferInfo == nullptr) { | 
 | 466 |         ALOGE("VulkanSurface::dequeueNativeBuffer called with an invalid surface!"); | 
 | 467 |         return Frame(-1, -1, 0); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 468 |     } | 
 | 469 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 470 |     LOG_ALWAYS_FATAL_IF(!bufferInfo->dequeued); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 471 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 472 |     if (bufferInfo->dequeue_fence != -1) { | 
| Stan Iliev | 197843d | 2019-03-21 11:34:15 -0400 | [diff] [blame] | 473 |         struct sync_file_info* finfo = sync_file_info(bufferInfo->dequeue_fence); | 
 | 474 |         bool isSignalPending = false; | 
 | 475 |         if (finfo != NULL) { | 
 | 476 |             isSignalPending = finfo->status != 1; | 
 | 477 |             sync_file_info_free(finfo); | 
 | 478 |         } | 
 | 479 |         if (isSignalPending) { | 
 | 480 |             int fence_clone = dup(bufferInfo->dequeue_fence); | 
 | 481 |             if (fence_clone == -1) { | 
 | 482 |                 ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", strerror(errno), | 
 | 483 |                       errno); | 
 | 484 |                 sync_wait(bufferInfo->dequeue_fence, -1 /* forever */); | 
 | 485 |             } else { | 
 | 486 |                 VkSemaphoreCreateInfo semaphoreInfo; | 
 | 487 |                 semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | 
 | 488 |                 semaphoreInfo.pNext = nullptr; | 
 | 489 |                 semaphoreInfo.flags = 0; | 
 | 490 |                 VkSemaphore semaphore; | 
 | 491 |                 VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore); | 
| Greg Daniel | d667077 | 2021-06-09 12:01:12 -0400 | [diff] [blame] | 492 |                 if (err != VK_SUCCESS) { | 
 | 493 |                     ALOGE("Failed to create import semaphore, err: %d", err); | 
 | 494 |                     close(fence_clone); | 
 | 495 |                     sync_wait(bufferInfo->dequeue_fence, -1 /* forever */); | 
 | 496 |                 } else { | 
 | 497 |                     VkImportSemaphoreFdInfoKHR importInfo; | 
 | 498 |                     importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; | 
 | 499 |                     importInfo.pNext = nullptr; | 
 | 500 |                     importInfo.semaphore = semaphore; | 
 | 501 |                     importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT; | 
 | 502 |                     importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; | 
 | 503 |                     importInfo.fd = fence_clone; | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 504 |  | 
| Greg Daniel | d667077 | 2021-06-09 12:01:12 -0400 | [diff] [blame] | 505 |                     err = mImportSemaphoreFdKHR(mDevice, &importInfo); | 
 | 506 |                     if (err != VK_SUCCESS) { | 
 | 507 |                         ALOGE("Failed to import semaphore, err: %d", err); | 
 | 508 |                         mDestroySemaphore(mDevice, semaphore, nullptr); | 
 | 509 |                         close(fence_clone); | 
 | 510 |                         sync_wait(bufferInfo->dequeue_fence, -1 /* forever */); | 
 | 511 |                     } else { | 
 | 512 |                         GrBackendSemaphore backendSemaphore; | 
 | 513 |                         backendSemaphore.initVulkan(semaphore); | 
 | 514 |                         // Skia will take ownership of the VkSemaphore and delete it once the wait | 
 | 515 |                         // has finished. The VkSemaphore also owns the imported fd, so it will | 
 | 516 |                         // close the fd when it is deleted. | 
 | 517 |                         bufferInfo->skSurface->wait(1, &backendSemaphore); | 
 | 518 |                         // The following flush blocks the GPU immediately instead of waiting for | 
 | 519 |                         // other drawing ops. It seems dequeue_fence is not respected otherwise. | 
 | 520 |                         // TODO: remove the flush after finding why backendSemaphore is not working. | 
| Kevin Lubick | aa592d0 | 2023-05-30 15:07:06 +0000 | [diff] [blame] | 521 |                         skgpu::ganesh::FlushAndSubmit(bufferInfo->skSurface); | 
| Greg Daniel | d667077 | 2021-06-09 12:01:12 -0400 | [diff] [blame] | 522 |                     } | 
 | 523 |                 } | 
| Stan Iliev | 197843d | 2019-03-21 11:34:15 -0400 | [diff] [blame] | 524 |             } | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 525 |         } | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 526 |     } | 
 | 527 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 528 |     int bufferAge = (mSwapBehavior == SwapBehavior::Discard) ? 0 : surface->getCurrentBuffersAge(); | 
 | 529 |     return Frame(surface->logicalWidth(), surface->logicalHeight(), bufferAge); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 530 | } | 
 | 531 |  | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 532 | struct DestroySemaphoreInfo { | 
 | 533 |     PFN_vkDestroySemaphore mDestroyFunction; | 
 | 534 |     VkDevice mDevice; | 
 | 535 |     VkSemaphore mSemaphore; | 
| Greg Daniel | fd42939 | 2019-05-09 15:44:56 -0400 | [diff] [blame] | 536 |     // We need to make sure we don't delete the VkSemaphore until it is done being used by both Skia | 
 | 537 |     // (including by the GPU) and inside the VulkanManager. So we always start with two refs, one | 
 | 538 |     // owned by Skia and one owned by the VulkanManager. The refs are decremented each time | 
 | 539 |     // destroy_semaphore is called with this object. Skia will call destroy_semaphore once it is | 
 | 540 |     // done with the semaphore and the GPU has finished work on the semaphore. The VulkanManager | 
 | 541 |     // calls destroy_semaphore after sending the semaphore to Skia and exporting it if need be. | 
 | 542 |     int mRefs = 2; | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 543 |  | 
 | 544 |     DestroySemaphoreInfo(PFN_vkDestroySemaphore destroyFunction, VkDevice device, | 
| Stan Iliev | aaa9e83 | 2019-09-17 14:07:23 -0400 | [diff] [blame] | 545 |                          VkSemaphore semaphore) | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 546 |             : mDestroyFunction(destroyFunction), mDevice(device), mSemaphore(semaphore) {} | 
 | 547 | }; | 
 | 548 |  | 
 | 549 | static void destroy_semaphore(void* context) { | 
 | 550 |     DestroySemaphoreInfo* info = reinterpret_cast<DestroySemaphoreInfo*>(context); | 
| Greg Daniel | fd42939 | 2019-05-09 15:44:56 -0400 | [diff] [blame] | 551 |     --info->mRefs; | 
 | 552 |     if (!info->mRefs) { | 
 | 553 |         info->mDestroyFunction(info->mDevice, info->mSemaphore, nullptr); | 
 | 554 |         delete info; | 
 | 555 |     } | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 556 | } | 
 | 557 |  | 
| Alec Mouri | 3afb397 | 2022-05-27 22:03:11 +0000 | [diff] [blame] | 558 | nsecs_t VulkanManager::finishFrame(SkSurface* surface) { | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 559 |     ATRACE_NAME("Vulkan finish frame"); | 
 | 560 |     ALOGE_IF(mSwapSemaphore != VK_NULL_HANDLE || mDestroySemaphoreContext != nullptr, | 
 | 561 |              "finishFrame already has an outstanding semaphore"); | 
| Stan Iliev | bc5f06b | 2019-03-26 15:14:34 -0400 | [diff] [blame] | 562 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 563 |     VkExportSemaphoreCreateInfo exportInfo; | 
 | 564 |     exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO; | 
 | 565 |     exportInfo.pNext = nullptr; | 
 | 566 |     exportInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 567 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 568 |     VkSemaphoreCreateInfo semaphoreInfo; | 
 | 569 |     semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | 
 | 570 |     semaphoreInfo.pNext = &exportInfo; | 
 | 571 |     semaphoreInfo.flags = 0; | 
 | 572 |     VkSemaphore semaphore; | 
 | 573 |     VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore); | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 574 |     ALOGE_IF(VK_SUCCESS != err, "VulkanManager::makeSwapSemaphore(): Failed to create semaphore"); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 575 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 576 |     GrBackendSemaphore backendSemaphore; | 
 | 577 |     backendSemaphore.initVulkan(semaphore); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 578 |  | 
| Greg Daniel | c7ad408 | 2020-05-14 15:38:26 -0400 | [diff] [blame] | 579 |     GrFlushInfo flushInfo; | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 580 |     if (err == VK_SUCCESS) { | 
 | 581 |         mDestroySemaphoreContext = new DestroySemaphoreInfo(mDestroySemaphore, mDevice, semaphore); | 
 | 582 |         flushInfo.fNumSemaphores = 1; | 
 | 583 |         flushInfo.fSignalSemaphores = &backendSemaphore; | 
 | 584 |         flushInfo.fFinishedProc = destroy_semaphore; | 
 | 585 |         flushInfo.fFinishedContext = mDestroySemaphoreContext; | 
 | 586 |     } else { | 
 | 587 |         semaphore = VK_NULL_HANDLE; | 
 | 588 |     } | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 589 |     GrDirectContext* context = GrAsDirectContext(surface->recordingContext()); | 
| Adlai Holler | 0375fee | 2020-09-15 12:31:22 -0400 | [diff] [blame] | 590 |     ALOGE_IF(!context, "Surface is not backed by gpu"); | 
| Kevin Lubick | aa592d0 | 2023-05-30 15:07:06 +0000 | [diff] [blame] | 591 |     GrSemaphoresSubmitted submitted = context->flush( | 
 | 592 |             surface, SkSurfaces::BackendSurfaceAccess::kPresent, flushInfo); | 
| Adlai Holler | 0375fee | 2020-09-15 12:31:22 -0400 | [diff] [blame] | 593 |     context->submit(); | 
| Alec Mouri | 3afb397 | 2022-05-27 22:03:11 +0000 | [diff] [blame] | 594 |     const nsecs_t submissionTime = systemTime(); | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 595 |     if (semaphore != VK_NULL_HANDLE) { | 
 | 596 |         if (submitted == GrSemaphoresSubmitted::kYes) { | 
 | 597 |             mSwapSemaphore = semaphore; | 
| Hugues Evrard | b9510a0 | 2021-03-01 14:35:22 +0000 | [diff] [blame] | 598 |             if (mFrameBoundaryANDROID) { | 
 | 599 |                 // retrieve VkImage used as render target | 
 | 600 |                 VkImage image = VK_NULL_HANDLE; | 
 | 601 |                 GrBackendRenderTarget backendRenderTarget = | 
| Kevin Lubick | 098ed4c | 2023-05-08 12:03:59 +0000 | [diff] [blame] | 602 |                         SkSurfaces::GetBackendRenderTarget( | 
 | 603 |                             surface, SkSurfaces::BackendHandleAccess::kFlushRead); | 
| Hugues Evrard | b9510a0 | 2021-03-01 14:35:22 +0000 | [diff] [blame] | 604 |                 if (backendRenderTarget.isValid()) { | 
 | 605 |                     GrVkImageInfo info; | 
 | 606 |                     if (backendRenderTarget.getVkImageInfo(&info)) { | 
 | 607 |                         image = info.fImage; | 
 | 608 |                     } else { | 
 | 609 |                         ALOGE("Frame boundary: backend is not vulkan"); | 
 | 610 |                     } | 
 | 611 |                 } else { | 
 | 612 |                     ALOGE("Frame boundary: invalid backend render target"); | 
 | 613 |                 } | 
 | 614 |                 // frameBoundaryANDROID needs to know about mSwapSemaphore, but | 
 | 615 |                 // it won't wait on it. | 
 | 616 |                 mFrameBoundaryANDROID(mDevice, mSwapSemaphore, image); | 
 | 617 |             } | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 618 |         } else { | 
 | 619 |             destroy_semaphore(mDestroySemaphoreContext); | 
 | 620 |             mDestroySemaphoreContext = nullptr; | 
 | 621 |         } | 
 | 622 |     } | 
 | 623 |     skiapipeline::ShaderCache::get().onVkFrameFlushed(context); | 
| Alec Mouri | 3afb397 | 2022-05-27 22:03:11 +0000 | [diff] [blame] | 624 |  | 
 | 625 |     return submissionTime; | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 626 | } | 
 | 627 |  | 
 | 628 | void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect) { | 
 | 629 |     if (CC_UNLIKELY(Properties::waitForGpuCompletion)) { | 
 | 630 |         ATRACE_NAME("Finishing GPU work"); | 
 | 631 |         mDeviceWaitIdle(mDevice); | 
 | 632 |     } | 
 | 633 |  | 
 | 634 |     int fenceFd = -1; | 
 | 635 |     if (mSwapSemaphore != VK_NULL_HANDLE) { | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 636 |         VkSemaphoreGetFdInfoKHR getFdInfo; | 
 | 637 |         getFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR; | 
 | 638 |         getFdInfo.pNext = nullptr; | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 639 |         getFdInfo.semaphore = mSwapSemaphore; | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 640 |         getFdInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 641 |  | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 642 |         VkResult err = mGetSemaphoreFdKHR(mDevice, &getFdInfo, &fenceFd); | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 643 |         ALOGE_IF(VK_SUCCESS != err, "VulkanManager::swapBuffers(): Failed to get semaphore Fd"); | 
 | 644 |     } else { | 
 | 645 |         ALOGE("VulkanManager::swapBuffers(): Semaphore submission failed"); | 
 | 646 |         mQueueWaitIdle(mGraphicsQueue); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 647 |     } | 
| Greg Daniel | e8dc397 | 2021-07-15 13:38:44 -0400 | [diff] [blame] | 648 |     if (mDestroySemaphoreContext) { | 
 | 649 |         destroy_semaphore(mDestroySemaphoreContext); | 
 | 650 |     } | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 651 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 652 |     surface->presentCurrentBuffer(dirtyRect, fenceFd); | 
| Greg Daniel | be2803a | 2021-02-19 18:32:16 -0500 | [diff] [blame] | 653 |     mSwapSemaphore = VK_NULL_HANDLE; | 
 | 654 |     mDestroySemaphoreContext = nullptr; | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 655 | } | 
 | 656 |  | 
 | 657 | void VulkanManager::destroySurface(VulkanSurface* surface) { | 
 | 658 |     // Make sure all submit commands have finished before starting to destroy objects. | 
| Yiwei Zhang | 276d5fc | 2020-09-03 12:00:00 -0700 | [diff] [blame] | 659 |     if (VK_NULL_HANDLE != mGraphicsQueue) { | 
 | 660 |         mQueueWaitIdle(mGraphicsQueue); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 661 |     } | 
| Greg Daniel | 2ff20271 | 2018-06-14 11:50:10 -0400 | [diff] [blame] | 662 |     mDeviceWaitIdle(mDevice); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 663 |  | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 664 |     delete surface; | 
 | 665 | } | 
 | 666 |  | 
| Adlai Holler | f8c434e | 2020-07-27 11:42:45 -0400 | [diff] [blame] | 667 | VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, | 
 | 668 |                                             ColorMode colorMode, | 
| Peiyong Lin | 3bff135 | 2018-12-11 07:56:07 -0800 | [diff] [blame] | 669 |                                             sk_sp<SkColorSpace> surfaceColorSpace, | 
| Adlai Holler | f8c434e | 2020-07-27 11:42:45 -0400 | [diff] [blame] | 670 |                                             SkColorType surfaceColorType, | 
 | 671 |                                             GrDirectContext* grContext, | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 672 |                                             uint32_t extraBuffers) { | 
| Stan Iliev | 981afe7 | 2019-02-13 14:24:33 -0500 | [diff] [blame] | 673 |     LOG_ALWAYS_FATAL_IF(!hasVkContext(), "Not initialized"); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 674 |     if (!window) { | 
 | 675 |         return nullptr; | 
 | 676 |     } | 
 | 677 |  | 
| Derek Sollenberger | a19b71a | 2019-02-15 16:36:30 -0500 | [diff] [blame] | 678 |     return VulkanSurface::Create(window, colorMode, surfaceColorType, surfaceColorSpace, grContext, | 
| John Reck | 0fa0cbc | 2019-04-05 16:57:46 -0700 | [diff] [blame] | 679 |                                  *this, extraBuffers); | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 680 | } | 
 | 681 |  | 
| Adlai Holler | f8c434e | 2020-07-27 11:42:45 -0400 | [diff] [blame] | 682 | status_t VulkanManager::fenceWait(int fence, GrDirectContext* grContext) { | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 683 |     if (!hasVkContext()) { | 
 | 684 |         ALOGE("VulkanManager::fenceWait: VkDevice not initialized"); | 
 | 685 |         return INVALID_OPERATION; | 
 | 686 |     } | 
 | 687 |  | 
| Stan Iliev | 7a08127 | 2018-10-26 17:54:18 -0400 | [diff] [blame] | 688 |     // Block GPU on the fence. | 
| Stan Iliev | aaa9e83 | 2019-09-17 14:07:23 -0400 | [diff] [blame] | 689 |     int fenceFd = ::dup(fence); | 
| Stan Iliev | 7a08127 | 2018-10-26 17:54:18 -0400 | [diff] [blame] | 690 |     if (fenceFd == -1) { | 
 | 691 |         ALOGE("VulkanManager::fenceWait: error dup'ing fence fd: %d", errno); | 
 | 692 |         return -errno; | 
| Stan Iliev | 564ca3e | 2018-09-04 22:00:00 +0000 | [diff] [blame] | 693 |     } | 
| Stan Iliev | 7a08127 | 2018-10-26 17:54:18 -0400 | [diff] [blame] | 694 |  | 
 | 695 |     VkSemaphoreCreateInfo semaphoreInfo; | 
 | 696 |     semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | 
 | 697 |     semaphoreInfo.pNext = nullptr; | 
 | 698 |     semaphoreInfo.flags = 0; | 
 | 699 |     VkSemaphore semaphore; | 
 | 700 |     VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore); | 
 | 701 |     if (VK_SUCCESS != err) { | 
| Greg Daniel | d667077 | 2021-06-09 12:01:12 -0400 | [diff] [blame] | 702 |         close(fenceFd); | 
| Stan Iliev | 7a08127 | 2018-10-26 17:54:18 -0400 | [diff] [blame] | 703 |         ALOGE("Failed to create import semaphore, err: %d", err); | 
 | 704 |         return UNKNOWN_ERROR; | 
 | 705 |     } | 
 | 706 |     VkImportSemaphoreFdInfoKHR importInfo; | 
 | 707 |     importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; | 
 | 708 |     importInfo.pNext = nullptr; | 
 | 709 |     importInfo.semaphore = semaphore; | 
 | 710 |     importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT; | 
 | 711 |     importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; | 
 | 712 |     importInfo.fd = fenceFd; | 
 | 713 |  | 
 | 714 |     err = mImportSemaphoreFdKHR(mDevice, &importInfo); | 
 | 715 |     if (VK_SUCCESS != err) { | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 716 |         mDestroySemaphore(mDevice, semaphore, nullptr); | 
| Greg Daniel | d667077 | 2021-06-09 12:01:12 -0400 | [diff] [blame] | 717 |         close(fenceFd); | 
| Stan Iliev | 7a08127 | 2018-10-26 17:54:18 -0400 | [diff] [blame] | 718 |         ALOGE("Failed to import semaphore, err: %d", err); | 
 | 719 |         return UNKNOWN_ERROR; | 
 | 720 |     } | 
 | 721 |  | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 722 |     GrBackendSemaphore beSemaphore; | 
 | 723 |     beSemaphore.initVulkan(semaphore); | 
| Stan Iliev | 7a08127 | 2018-10-26 17:54:18 -0400 | [diff] [blame] | 724 |  | 
| Greg Daniel | d667077 | 2021-06-09 12:01:12 -0400 | [diff] [blame] | 725 |     // Skia will take ownership of the VkSemaphore and delete it once the wait has finished. The | 
 | 726 |     // VkSemaphore also owns the imported fd, so it will close the fd when it is deleted. | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 727 |     grContext->wait(1, &beSemaphore); | 
| Greg Daniel | c7ad408 | 2020-05-14 15:38:26 -0400 | [diff] [blame] | 728 |     grContext->flushAndSubmit(); | 
| Stan Iliev | 7a08127 | 2018-10-26 17:54:18 -0400 | [diff] [blame] | 729 |  | 
| Stan Iliev | 564ca3e | 2018-09-04 22:00:00 +0000 | [diff] [blame] | 730 |     return OK; | 
 | 731 | } | 
 | 732 |  | 
| Adlai Holler | f8c434e | 2020-07-27 11:42:45 -0400 | [diff] [blame] | 733 | status_t VulkanManager::createReleaseFence(int* nativeFence, GrDirectContext* grContext) { | 
| Stan Iliev | aaa9e83 | 2019-09-17 14:07:23 -0400 | [diff] [blame] | 734 |     *nativeFence = -1; | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 735 |     if (!hasVkContext()) { | 
 | 736 |         ALOGE("VulkanManager::createReleaseFence: VkDevice not initialized"); | 
 | 737 |         return INVALID_OPERATION; | 
 | 738 |     } | 
 | 739 |  | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 740 |     VkExportSemaphoreCreateInfo exportInfo; | 
 | 741 |     exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO; | 
 | 742 |     exportInfo.pNext = nullptr; | 
 | 743 |     exportInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; | 
 | 744 |  | 
 | 745 |     VkSemaphoreCreateInfo semaphoreInfo; | 
 | 746 |     semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | 
 | 747 |     semaphoreInfo.pNext = &exportInfo; | 
 | 748 |     semaphoreInfo.flags = 0; | 
 | 749 |     VkSemaphore semaphore; | 
 | 750 |     VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore); | 
 | 751 |     if (VK_SUCCESS != err) { | 
 | 752 |         ALOGE("VulkanManager::createReleaseFence: Failed to create semaphore"); | 
 | 753 |         return INVALID_OPERATION; | 
 | 754 |     } | 
 | 755 |  | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 756 |     GrBackendSemaphore backendSemaphore; | 
 | 757 |     backendSemaphore.initVulkan(semaphore); | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 758 |  | 
| Stan Iliev | aaa9e83 | 2019-09-17 14:07:23 -0400 | [diff] [blame] | 759 |     DestroySemaphoreInfo* destroyInfo = | 
 | 760 |             new DestroySemaphoreInfo(mDestroySemaphore, mDevice, semaphore); | 
| Greg Daniel | fd42939 | 2019-05-09 15:44:56 -0400 | [diff] [blame] | 761 |     // Even if Skia fails to submit the semaphore, it will still call the destroy_semaphore callback | 
 | 762 |     // which will remove its ref to the semaphore. The VulkanManager must still release its ref, | 
 | 763 |     // when it is done with the semaphore. | 
| Greg Daniel | c7ad408 | 2020-05-14 15:38:26 -0400 | [diff] [blame] | 764 |     GrFlushInfo flushInfo; | 
 | 765 |     flushInfo.fNumSemaphores = 1; | 
 | 766 |     flushInfo.fSignalSemaphores = &backendSemaphore; | 
 | 767 |     flushInfo.fFinishedProc = destroy_semaphore; | 
 | 768 |     flushInfo.fFinishedContext = destroyInfo; | 
 | 769 |     GrSemaphoresSubmitted submitted = grContext->flush(flushInfo); | 
 | 770 |     grContext->submit(); | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 771 |  | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 772 |     if (submitted == GrSemaphoresSubmitted::kNo) { | 
 | 773 |         ALOGE("VulkanManager::createReleaseFence: Failed to submit semaphore"); | 
| Greg Daniel | fd42939 | 2019-05-09 15:44:56 -0400 | [diff] [blame] | 774 |         destroy_semaphore(destroyInfo); | 
| Greg Daniel | d92a9b1 | 2019-04-23 10:11:04 -0400 | [diff] [blame] | 775 |         return INVALID_OPERATION; | 
 | 776 |     } | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 777 |  | 
 | 778 |     VkSemaphoreGetFdInfoKHR getFdInfo; | 
 | 779 |     getFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR; | 
 | 780 |     getFdInfo.pNext = nullptr; | 
 | 781 |     getFdInfo.semaphore = semaphore; | 
 | 782 |     getFdInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; | 
 | 783 |  | 
 | 784 |     int fenceFd = 0; | 
 | 785 |  | 
 | 786 |     err = mGetSemaphoreFdKHR(mDevice, &getFdInfo, &fenceFd); | 
| Greg Daniel | fd42939 | 2019-05-09 15:44:56 -0400 | [diff] [blame] | 787 |     destroy_semaphore(destroyInfo); | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 788 |     if (VK_SUCCESS != err) { | 
 | 789 |         ALOGE("VulkanManager::createReleaseFence: Failed to get semaphore Fd"); | 
 | 790 |         return INVALID_OPERATION; | 
 | 791 |     } | 
| Stan Iliev | aaa9e83 | 2019-09-17 14:07:23 -0400 | [diff] [blame] | 792 |     *nativeFence = fenceFd; | 
| Greg Daniel | 26e0dca | 2018-09-18 10:33:19 -0400 | [diff] [blame] | 793 |  | 
| Stan Iliev | 564ca3e | 2018-09-04 22:00:00 +0000 | [diff] [blame] | 794 |     return OK; | 
 | 795 | } | 
 | 796 |  | 
| Derek Sollenberger | 0e3cba3 | 2016-11-09 11:58:36 -0500 | [diff] [blame] | 797 | } /* namespace renderthread */ | 
 | 798 | } /* namespace uirenderer */ | 
 | 799 | } /* namespace android */ |