xref: /aosp_15_r20/external/angle/src/tests/test_utils/VulkanHelper.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // VulkanHelper.cpp : Helper for allocating & managing vulkan external objects.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/VulkanHelper.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include <vector>
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include "common/bitset_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "common/vulkan/vulkan_icd.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "vulkan/vulkan_core.h"
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker namespace angle
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker namespace
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker 
EnumeratePhysicalDevices(VkInstance instance)26*8975f5c5SAndroid Build Coastguard Worker std::vector<VkPhysicalDevice> EnumeratePhysicalDevices(VkInstance instance)
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker     uint32_t physicalDeviceCount;
29*8975f5c5SAndroid Build Coastguard Worker     VkResult result = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
30*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
31*8975f5c5SAndroid Build Coastguard Worker     std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
32*8975f5c5SAndroid Build Coastguard Worker     result = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
33*8975f5c5SAndroid Build Coastguard Worker     return physicalDevices;
34*8975f5c5SAndroid Build Coastguard Worker }
35*8975f5c5SAndroid Build Coastguard Worker 
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * layerName)36*8975f5c5SAndroid Build Coastguard Worker std::vector<VkExtensionProperties> EnumerateDeviceExtensionProperties(
37*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice,
38*8975f5c5SAndroid Build Coastguard Worker     const char *layerName)
39*8975f5c5SAndroid Build Coastguard Worker {
40*8975f5c5SAndroid Build Coastguard Worker     uint32_t deviceExtensionCount;
41*8975f5c5SAndroid Build Coastguard Worker     VkResult result = vkEnumerateDeviceExtensionProperties(physicalDevice, layerName,
42*8975f5c5SAndroid Build Coastguard Worker                                                            &deviceExtensionCount, nullptr);
43*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
44*8975f5c5SAndroid Build Coastguard Worker     std::vector<VkExtensionProperties> deviceExtensionProperties(deviceExtensionCount);
45*8975f5c5SAndroid Build Coastguard Worker     result = vkEnumerateDeviceExtensionProperties(physicalDevice, layerName, &deviceExtensionCount,
46*8975f5c5SAndroid Build Coastguard Worker                                                   deviceExtensionProperties.data());
47*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
48*8975f5c5SAndroid Build Coastguard Worker     return deviceExtensionProperties;
49*8975f5c5SAndroid Build Coastguard Worker }
50*8975f5c5SAndroid Build Coastguard Worker 
GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice)51*8975f5c5SAndroid Build Coastguard Worker std::vector<VkQueueFamilyProperties> GetPhysicalDeviceQueueFamilyProperties(
52*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDevice physicalDevice)
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker     uint32_t queueFamilyPropertyCount;
55*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertyCount, nullptr);
56*8975f5c5SAndroid Build Coastguard Worker     std::vector<VkQueueFamilyProperties> physicalDeviceQueueFamilyProperties(
57*8975f5c5SAndroid Build Coastguard Worker         queueFamilyPropertyCount);
58*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertyCount,
59*8975f5c5SAndroid Build Coastguard Worker                                              physicalDeviceQueueFamilyProperties.data());
60*8975f5c5SAndroid Build Coastguard Worker     return physicalDeviceQueueFamilyProperties;
61*8975f5c5SAndroid Build Coastguard Worker }
62*8975f5c5SAndroid Build Coastguard Worker 
HasExtension(const std::vector<VkExtensionProperties> instanceExtensions,const char * extensionName)63*8975f5c5SAndroid Build Coastguard Worker bool HasExtension(const std::vector<VkExtensionProperties> instanceExtensions,
64*8975f5c5SAndroid Build Coastguard Worker                   const char *extensionName)
65*8975f5c5SAndroid Build Coastguard Worker {
66*8975f5c5SAndroid Build Coastguard Worker     for (const auto &extensionProperties : instanceExtensions)
67*8975f5c5SAndroid Build Coastguard Worker     {
68*8975f5c5SAndroid Build Coastguard Worker         if (!strcmp(extensionProperties.extensionName, extensionName))
69*8975f5c5SAndroid Build Coastguard Worker             return true;
70*8975f5c5SAndroid Build Coastguard Worker     }
71*8975f5c5SAndroid Build Coastguard Worker 
72*8975f5c5SAndroid Build Coastguard Worker     return false;
73*8975f5c5SAndroid Build Coastguard Worker }
74*8975f5c5SAndroid Build Coastguard Worker 
HasExtension(const std::vector<const char * > enabledExtensions,const char * extensionName)75*8975f5c5SAndroid Build Coastguard Worker bool HasExtension(const std::vector<const char *> enabledExtensions, const char *extensionName)
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker     for (const char *enabledExtension : enabledExtensions)
78*8975f5c5SAndroid Build Coastguard Worker     {
79*8975f5c5SAndroid Build Coastguard Worker         if (!strcmp(enabledExtension, extensionName))
80*8975f5c5SAndroid Build Coastguard Worker             return true;
81*8975f5c5SAndroid Build Coastguard Worker     }
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker     return false;
84*8975f5c5SAndroid Build Coastguard Worker }
85*8975f5c5SAndroid Build Coastguard Worker 
HasExtension(const char * const * enabledExtensions,const char * extensionName)86*8975f5c5SAndroid Build Coastguard Worker bool HasExtension(const char *const *enabledExtensions, const char *extensionName)
87*8975f5c5SAndroid Build Coastguard Worker {
88*8975f5c5SAndroid Build Coastguard Worker     size_t i = 0;
89*8975f5c5SAndroid Build Coastguard Worker     while (enabledExtensions[i])
90*8975f5c5SAndroid Build Coastguard Worker     {
91*8975f5c5SAndroid Build Coastguard Worker         if (!strcmp(enabledExtensions[i], extensionName))
92*8975f5c5SAndroid Build Coastguard Worker             return true;
93*8975f5c5SAndroid Build Coastguard Worker         i++;
94*8975f5c5SAndroid Build Coastguard Worker     }
95*8975f5c5SAndroid Build Coastguard Worker     return false;
96*8975f5c5SAndroid Build Coastguard Worker }
97*8975f5c5SAndroid Build Coastguard Worker 
FindMemoryType(const VkPhysicalDeviceMemoryProperties & memoryProperties,uint32_t memoryTypeBits,VkMemoryPropertyFlags requiredMemoryPropertyFlags)98*8975f5c5SAndroid Build Coastguard Worker uint32_t FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProperties,
99*8975f5c5SAndroid Build Coastguard Worker                         uint32_t memoryTypeBits,
100*8975f5c5SAndroid Build Coastguard Worker                         VkMemoryPropertyFlags requiredMemoryPropertyFlags)
101*8975f5c5SAndroid Build Coastguard Worker {
102*8975f5c5SAndroid Build Coastguard Worker     for (size_t memoryIndex : angle::BitSet32<32>(memoryTypeBits))
103*8975f5c5SAndroid Build Coastguard Worker     {
104*8975f5c5SAndroid Build Coastguard Worker         ASSERT(memoryIndex < memoryProperties.memoryTypeCount);
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker         if ((memoryProperties.memoryTypes[memoryIndex].propertyFlags &
107*8975f5c5SAndroid Build Coastguard Worker              requiredMemoryPropertyFlags) == requiredMemoryPropertyFlags)
108*8975f5c5SAndroid Build Coastguard Worker         {
109*8975f5c5SAndroid Build Coastguard Worker             return static_cast<uint32_t>(memoryIndex);
110*8975f5c5SAndroid Build Coastguard Worker         }
111*8975f5c5SAndroid Build Coastguard Worker     }
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker     return UINT32_MAX;
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker 
ImageMemoryBarrier(VkCommandBuffer commandBuffer,VkImage image,uint32_t srcQueueFamilyIndex,uint32_t dstQueueFamilyIndex,VkImageLayout oldLayout,VkImageLayout newLayout)116*8975f5c5SAndroid Build Coastguard Worker void ImageMemoryBarrier(VkCommandBuffer commandBuffer,
117*8975f5c5SAndroid Build Coastguard Worker                         VkImage image,
118*8975f5c5SAndroid Build Coastguard Worker                         uint32_t srcQueueFamilyIndex,
119*8975f5c5SAndroid Build Coastguard Worker                         uint32_t dstQueueFamilyIndex,
120*8975f5c5SAndroid Build Coastguard Worker                         VkImageLayout oldLayout,
121*8975f5c5SAndroid Build Coastguard Worker                         VkImageLayout newLayout)
122*8975f5c5SAndroid Build Coastguard Worker {
123*8975f5c5SAndroid Build Coastguard Worker     const VkImageMemoryBarrier imageMemoryBarriers[] = {
124*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {/* .sType = */ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
125*8975f5c5SAndroid Build Coastguard Worker                      /* .pNext = */ nullptr,
126*8975f5c5SAndroid Build Coastguard Worker                      /* .srcAccessMask = */ VK_ACCESS_MEMORY_WRITE_BIT,
127*8975f5c5SAndroid Build Coastguard Worker                      /* .dstAccessMask = */ VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
128*8975f5c5SAndroid Build Coastguard Worker                      /* .oldLayout = */ oldLayout,
129*8975f5c5SAndroid Build Coastguard Worker                      /* .newLayout = */ newLayout,
130*8975f5c5SAndroid Build Coastguard Worker                      /* .srcQueueFamilyIndex = */ srcQueueFamilyIndex,
131*8975f5c5SAndroid Build Coastguard Worker                      /* .dstQueueFamilyIndex = */ dstQueueFamilyIndex,
132*8975f5c5SAndroid Build Coastguard Worker                      /* .image = */ image,
133*8975f5c5SAndroid Build Coastguard Worker                      /* .subresourceRange = */
134*8975f5c5SAndroid Build Coastguard Worker                      {
135*8975f5c5SAndroid Build Coastguard Worker                          /* .aspectMask = */ VK_IMAGE_ASPECT_COLOR_BIT,
136*8975f5c5SAndroid Build Coastguard Worker                          /* .basicMiplevel = */ 0,
137*8975f5c5SAndroid Build Coastguard Worker                          /* .levelCount = */ 1,
138*8975f5c5SAndroid Build Coastguard Worker                          /* .baseArrayLayer = */ 0,
139*8975f5c5SAndroid Build Coastguard Worker                          /* .layerCount = */ 1,
140*8975f5c5SAndroid Build Coastguard Worker                      }}};
141*8975f5c5SAndroid Build Coastguard Worker     const uint32_t imageMemoryBarrierCount = std::extent<decltype(imageMemoryBarriers)>();
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker     constexpr VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
144*8975f5c5SAndroid Build Coastguard Worker     constexpr VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
145*8975f5c5SAndroid Build Coastguard Worker     const VkDependencyFlags dependencyFlags     = 0;
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker     vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0, nullptr, 0,
148*8975f5c5SAndroid Build Coastguard Worker                          nullptr, imageMemoryBarrierCount, imageMemoryBarriers);
149*8975f5c5SAndroid Build Coastguard Worker }
150*8975f5c5SAndroid Build Coastguard Worker 
151*8975f5c5SAndroid Build Coastguard Worker }  // namespace
152*8975f5c5SAndroid Build Coastguard Worker 
VulkanHelper()153*8975f5c5SAndroid Build Coastguard Worker VulkanHelper::VulkanHelper() {}
154*8975f5c5SAndroid Build Coastguard Worker 
~VulkanHelper()155*8975f5c5SAndroid Build Coastguard Worker VulkanHelper::~VulkanHelper()
156*8975f5c5SAndroid Build Coastguard Worker {
157*8975f5c5SAndroid Build Coastguard Worker     if (mDevice != VK_NULL_HANDLE)
158*8975f5c5SAndroid Build Coastguard Worker     {
159*8975f5c5SAndroid Build Coastguard Worker         vkDeviceWaitIdle(mDevice);
160*8975f5c5SAndroid Build Coastguard Worker     }
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker     if (mCommandPool != VK_NULL_HANDLE)
163*8975f5c5SAndroid Build Coastguard Worker     {
164*8975f5c5SAndroid Build Coastguard Worker         vkDestroyCommandPool(mDevice, mCommandPool, nullptr);
165*8975f5c5SAndroid Build Coastguard Worker     }
166*8975f5c5SAndroid Build Coastguard Worker 
167*8975f5c5SAndroid Build Coastguard Worker     if (!mInitializedFromANGLE)
168*8975f5c5SAndroid Build Coastguard Worker     {
169*8975f5c5SAndroid Build Coastguard Worker         if (mDevice != VK_NULL_HANDLE)
170*8975f5c5SAndroid Build Coastguard Worker         {
171*8975f5c5SAndroid Build Coastguard Worker             vkDestroyDevice(mDevice, nullptr);
172*8975f5c5SAndroid Build Coastguard Worker 
173*8975f5c5SAndroid Build Coastguard Worker             mDevice        = VK_NULL_HANDLE;
174*8975f5c5SAndroid Build Coastguard Worker             mGraphicsQueue = VK_NULL_HANDLE;
175*8975f5c5SAndroid Build Coastguard Worker         }
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker         if (mInstance != VK_NULL_HANDLE)
178*8975f5c5SAndroid Build Coastguard Worker         {
179*8975f5c5SAndroid Build Coastguard Worker             vkDestroyInstance(mInstance, nullptr);
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker             mInstance = VK_NULL_HANDLE;
182*8975f5c5SAndroid Build Coastguard Worker         }
183*8975f5c5SAndroid Build Coastguard Worker     }
184*8975f5c5SAndroid Build Coastguard Worker }
185*8975f5c5SAndroid Build Coastguard Worker 
initialize(bool useSwiftshader,bool enableValidationLayers)186*8975f5c5SAndroid Build Coastguard Worker void VulkanHelper::initialize(bool useSwiftshader, bool enableValidationLayers)
187*8975f5c5SAndroid Build Coastguard Worker {
188*8975f5c5SAndroid Build Coastguard Worker     bool enableValidationLayersOverride = enableValidationLayers;
189*8975f5c5SAndroid Build Coastguard Worker #if !defined(ANGLE_ENABLE_VULKAN_VALIDATION_LAYERS)
190*8975f5c5SAndroid Build Coastguard Worker     enableValidationLayersOverride = false;
191*8975f5c5SAndroid Build Coastguard Worker #endif
192*8975f5c5SAndroid Build Coastguard Worker 
193*8975f5c5SAndroid Build Coastguard Worker     vk::ICD icd = useSwiftshader ? vk::ICD::SwiftShader : vk::ICD::Default;
194*8975f5c5SAndroid Build Coastguard Worker 
195*8975f5c5SAndroid Build Coastguard Worker     vk::ScopedVkLoaderEnvironment scopedEnvironment(enableValidationLayersOverride, icd);
196*8975f5c5SAndroid Build Coastguard Worker 
197*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mInstance == VK_NULL_HANDLE);
198*8975f5c5SAndroid Build Coastguard Worker     VkResult result = VK_SUCCESS;
199*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_SHARED_LIBVULKAN
200*8975f5c5SAndroid Build Coastguard Worker     result = volkInitialize();
201*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
202*8975f5c5SAndroid Build Coastguard Worker #endif  // ANGLE_SHARED_LIBVULKAN
203*8975f5c5SAndroid Build Coastguard Worker 
204*8975f5c5SAndroid Build Coastguard Worker     VkApplicationInfo applicationInfo = {
205*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_APPLICATION_INFO,
206*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
207*8975f5c5SAndroid Build Coastguard Worker         /* .pApplicationName = */ "ANGLE Tests",
208*8975f5c5SAndroid Build Coastguard Worker         /* .applicationVersion = */ 1,
209*8975f5c5SAndroid Build Coastguard Worker         /* .pEngineName = */ nullptr,
210*8975f5c5SAndroid Build Coastguard Worker         /* .engineVersion = */ 0,
211*8975f5c5SAndroid Build Coastguard Worker         /* .apiVersion = */ VK_API_VERSION_1_1,
212*8975f5c5SAndroid Build Coastguard Worker     };
213*8975f5c5SAndroid Build Coastguard Worker 
214*8975f5c5SAndroid Build Coastguard Worker     std::vector<const char *> enabledLayerNames;
215*8975f5c5SAndroid Build Coastguard Worker     if (enableValidationLayersOverride)
216*8975f5c5SAndroid Build Coastguard Worker     {
217*8975f5c5SAndroid Build Coastguard Worker         enabledLayerNames.push_back("VK_LAYER_KHRONOS_validation");
218*8975f5c5SAndroid Build Coastguard Worker     }
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker     VkInstanceCreateInfo instanceCreateInfo = {
221*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
222*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
223*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ 0,
224*8975f5c5SAndroid Build Coastguard Worker         /* .pApplicationInfo = */ &applicationInfo,
225*8975f5c5SAndroid Build Coastguard Worker         /* .enabledLayerCount = */ static_cast<uint32_t>(enabledLayerNames.size()),
226*8975f5c5SAndroid Build Coastguard Worker         /* .ppEnabledLayerNames = */ enabledLayerNames.data(),
227*8975f5c5SAndroid Build Coastguard Worker         /* .enabledExtensionCount = */ 0,
228*8975f5c5SAndroid Build Coastguard Worker         /* .ppEnabledExtensionName = */ nullptr,
229*8975f5c5SAndroid Build Coastguard Worker     };
230*8975f5c5SAndroid Build Coastguard Worker 
231*8975f5c5SAndroid Build Coastguard Worker     result = vkCreateInstance(&instanceCreateInfo, nullptr, &mInstance);
232*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
233*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mInstance != VK_NULL_HANDLE);
234*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_SHARED_LIBVULKAN
235*8975f5c5SAndroid Build Coastguard Worker     volkLoadInstance(mInstance);
236*8975f5c5SAndroid Build Coastguard Worker #endif  // ANGLE_SHARED_LIBVULKAN
237*8975f5c5SAndroid Build Coastguard Worker 
238*8975f5c5SAndroid Build Coastguard Worker     std::vector<VkPhysicalDevice> physicalDevices = EnumeratePhysicalDevices(mInstance);
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker     ASSERT(physicalDevices.size() > 0);
241*8975f5c5SAndroid Build Coastguard Worker 
242*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDeviceProperties physicalDeviceProperties;
243*8975f5c5SAndroid Build Coastguard Worker     ChoosePhysicalDevice(vkGetPhysicalDeviceProperties, physicalDevices, icd, 0, 0,
244*8975f5c5SAndroid Build Coastguard Worker                          &mPhysicalDevice, &physicalDeviceProperties);
245*8975f5c5SAndroid Build Coastguard Worker 
246*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceMemoryProperties(mPhysicalDevice, &mMemoryProperties);
247*8975f5c5SAndroid Build Coastguard Worker 
248*8975f5c5SAndroid Build Coastguard Worker     std::vector<VkExtensionProperties> deviceExtensionProperties =
249*8975f5c5SAndroid Build Coastguard Worker         EnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr);
250*8975f5c5SAndroid Build Coastguard Worker 
251*8975f5c5SAndroid Build Coastguard Worker     std::vector<const char *> requestedDeviceExtensions = {
252*8975f5c5SAndroid Build Coastguard Worker         VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
253*8975f5c5SAndroid Build Coastguard Worker         VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME,   VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
254*8975f5c5SAndroid Build Coastguard Worker         VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME,
255*8975f5c5SAndroid Build Coastguard Worker     };
256*8975f5c5SAndroid Build Coastguard Worker 
257*8975f5c5SAndroid Build Coastguard Worker     std::vector<const char *> enabledDeviceExtensions;
258*8975f5c5SAndroid Build Coastguard Worker 
259*8975f5c5SAndroid Build Coastguard Worker     for (const char *extensionName : requestedDeviceExtensions)
260*8975f5c5SAndroid Build Coastguard Worker     {
261*8975f5c5SAndroid Build Coastguard Worker         if (HasExtension(deviceExtensionProperties, extensionName))
262*8975f5c5SAndroid Build Coastguard Worker         {
263*8975f5c5SAndroid Build Coastguard Worker             enabledDeviceExtensions.push_back(extensionName);
264*8975f5c5SAndroid Build Coastguard Worker         }
265*8975f5c5SAndroid Build Coastguard Worker     }
266*8975f5c5SAndroid Build Coastguard Worker 
267*8975f5c5SAndroid Build Coastguard Worker     std::vector<VkQueueFamilyProperties> queueFamilyProperties =
268*8975f5c5SAndroid Build Coastguard Worker         GetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice);
269*8975f5c5SAndroid Build Coastguard Worker 
270*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < queueFamilyProperties.size(); ++i)
271*8975f5c5SAndroid Build Coastguard Worker     {
272*8975f5c5SAndroid Build Coastguard Worker         if (queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
273*8975f5c5SAndroid Build Coastguard Worker         {
274*8975f5c5SAndroid Build Coastguard Worker             mGraphicsQueueFamilyIndex = i;
275*8975f5c5SAndroid Build Coastguard Worker         }
276*8975f5c5SAndroid Build Coastguard Worker     }
277*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mGraphicsQueueFamilyIndex != UINT32_MAX);
278*8975f5c5SAndroid Build Coastguard Worker 
279*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t kQueueCreateInfoCount           = 1;
280*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t kGraphicsQueueCount             = 1;
281*8975f5c5SAndroid Build Coastguard Worker     float graphicsQueuePriorities[kGraphicsQueueCount] = {0.f};
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker     VkDeviceQueueCreateInfo queueCreateInfos[kQueueCreateInfoCount] = {
284*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
285*8975f5c5SAndroid Build Coastguard Worker             /* .sType = */ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
286*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
287*8975f5c5SAndroid Build Coastguard Worker             /* .flags = */ 0,
288*8975f5c5SAndroid Build Coastguard Worker             /* .queueFamilyIndex = */ mGraphicsQueueFamilyIndex,
289*8975f5c5SAndroid Build Coastguard Worker             /* .queueCount = */ 1,
290*8975f5c5SAndroid Build Coastguard Worker             /* .pQueuePriorities = */ graphicsQueuePriorities,
291*8975f5c5SAndroid Build Coastguard Worker         },
292*8975f5c5SAndroid Build Coastguard Worker     };
293*8975f5c5SAndroid Build Coastguard Worker 
294*8975f5c5SAndroid Build Coastguard Worker     uint32_t enabledDeviceExtensionCount = static_cast<uint32_t>(enabledDeviceExtensions.size());
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker     VkDeviceCreateInfo deviceCreateInfo = {
297*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
298*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
299*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ 0,
300*8975f5c5SAndroid Build Coastguard Worker         /* .queueCreateInfoCount = */ kQueueCreateInfoCount,
301*8975f5c5SAndroid Build Coastguard Worker         /* .pQueueCreateInfos = */ queueCreateInfos,
302*8975f5c5SAndroid Build Coastguard Worker         /* .enabledLayerCount = */ 0,
303*8975f5c5SAndroid Build Coastguard Worker         /* .ppEnabledLayerNames = */ nullptr,
304*8975f5c5SAndroid Build Coastguard Worker         /* .enabledExtensionCount = */ enabledDeviceExtensionCount,
305*8975f5c5SAndroid Build Coastguard Worker         /* .ppEnabledExtensionName = */ enabledDeviceExtensions.data(),
306*8975f5c5SAndroid Build Coastguard Worker         /* .pEnabledFeatures = */ nullptr,
307*8975f5c5SAndroid Build Coastguard Worker     };
308*8975f5c5SAndroid Build Coastguard Worker 
309*8975f5c5SAndroid Build Coastguard Worker     result = vkCreateDevice(mPhysicalDevice, &deviceCreateInfo, nullptr, &mDevice);
310*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
311*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mDevice != VK_NULL_HANDLE);
312*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_SHARED_LIBVULKAN
313*8975f5c5SAndroid Build Coastguard Worker     volkLoadDevice(mDevice);
314*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceExternalSemaphoreProperties =
315*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphoreProperties>(
316*8975f5c5SAndroid Build Coastguard Worker             vkGetInstanceProcAddr(mInstance, "vkGetPhysicalDeviceExternalSemaphoreProperties"));
317*8975f5c5SAndroid Build Coastguard Worker     ASSERT(vkGetPhysicalDeviceExternalSemaphoreProperties);
318*8975f5c5SAndroid Build Coastguard Worker #endif  // ANGLE_SHARED_LIBVULKAN
319*8975f5c5SAndroid Build Coastguard Worker 
320*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t kGraphicsQueueIndex = 0;
321*8975f5c5SAndroid Build Coastguard Worker     static_assert(kGraphicsQueueIndex < kGraphicsQueueCount, "must be in range");
322*8975f5c5SAndroid Build Coastguard Worker     vkGetDeviceQueue(mDevice, mGraphicsQueueFamilyIndex, kGraphicsQueueIndex, &mGraphicsQueue);
323*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mGraphicsQueue != VK_NULL_HANDLE);
324*8975f5c5SAndroid Build Coastguard Worker 
325*8975f5c5SAndroid Build Coastguard Worker     VkCommandPoolCreateInfo commandPoolCreateInfo = {
326*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
327*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
328*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ 0,
329*8975f5c5SAndroid Build Coastguard Worker         /* .queueFamilyIndex = */ mGraphicsQueueFamilyIndex,
330*8975f5c5SAndroid Build Coastguard Worker     };
331*8975f5c5SAndroid Build Coastguard Worker     result = vkCreateCommandPool(mDevice, &commandPoolCreateInfo, nullptr, &mCommandPool);
332*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
333*8975f5c5SAndroid Build Coastguard Worker 
334*8975f5c5SAndroid Build Coastguard Worker     mHasExternalMemoryFd =
335*8975f5c5SAndroid Build Coastguard Worker         HasExtension(enabledDeviceExtensions, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
336*8975f5c5SAndroid Build Coastguard Worker     mHasExternalSemaphoreFd =
337*8975f5c5SAndroid Build Coastguard Worker         HasExtension(enabledDeviceExtensions, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
338*8975f5c5SAndroid Build Coastguard Worker     mHasExternalMemoryFuchsia =
339*8975f5c5SAndroid Build Coastguard Worker         HasExtension(enabledDeviceExtensions, VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME);
340*8975f5c5SAndroid Build Coastguard Worker     mHasExternalSemaphoreFuchsia =
341*8975f5c5SAndroid Build Coastguard Worker         HasExtension(enabledDeviceExtensions, VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
342*8975f5c5SAndroid Build Coastguard Worker 
343*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceImageFormatProperties2 =
344*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2>(
345*8975f5c5SAndroid Build Coastguard Worker             vkGetInstanceProcAddr(mInstance, "vkGetPhysicalDeviceImageFormatProperties2"));
346*8975f5c5SAndroid Build Coastguard Worker     ASSERT(vkGetPhysicalDeviceImageFormatProperties2);
347*8975f5c5SAndroid Build Coastguard Worker     vkGetMemoryFdKHR = reinterpret_cast<PFN_vkGetMemoryFdKHR>(
348*8975f5c5SAndroid Build Coastguard Worker         vkGetInstanceProcAddr(mInstance, "vkGetMemoryFdKHR"));
349*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mHasExternalMemoryFd || vkGetMemoryFdKHR);
350*8975f5c5SAndroid Build Coastguard Worker     vkGetSemaphoreFdKHR = reinterpret_cast<PFN_vkGetSemaphoreFdKHR>(
351*8975f5c5SAndroid Build Coastguard Worker         vkGetInstanceProcAddr(mInstance, "vkGetSemaphoreFdKHR"));
352*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mHasExternalSemaphoreFd || vkGetSemaphoreFdKHR);
353*8975f5c5SAndroid Build Coastguard Worker     vkGetMemoryZirconHandleFUCHSIA = reinterpret_cast<PFN_vkGetMemoryZirconHandleFUCHSIA>(
354*8975f5c5SAndroid Build Coastguard Worker         vkGetInstanceProcAddr(mInstance, "vkGetMemoryZirconHandleFUCHSIA"));
355*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mHasExternalMemoryFuchsia || vkGetMemoryZirconHandleFUCHSIA);
356*8975f5c5SAndroid Build Coastguard Worker     vkGetSemaphoreZirconHandleFUCHSIA = reinterpret_cast<PFN_vkGetSemaphoreZirconHandleFUCHSIA>(
357*8975f5c5SAndroid Build Coastguard Worker         vkGetInstanceProcAddr(mInstance, "vkGetSemaphoreZirconHandleFUCHSIA"));
358*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mHasExternalSemaphoreFuchsia || vkGetSemaphoreZirconHandleFUCHSIA);
359*8975f5c5SAndroid Build Coastguard Worker }
360*8975f5c5SAndroid Build Coastguard Worker 
initializeFromANGLE()361*8975f5c5SAndroid Build Coastguard Worker void VulkanHelper::initializeFromANGLE()
362*8975f5c5SAndroid Build Coastguard Worker {
363*8975f5c5SAndroid Build Coastguard Worker     mInitializedFromANGLE = true;
364*8975f5c5SAndroid Build Coastguard Worker     VkResult vkResult     = VK_SUCCESS;
365*8975f5c5SAndroid Build Coastguard Worker 
366*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(IsEGLClientExtensionEnabled("EGL_EXT_device_query"));
367*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = eglGetCurrentDisplay();
368*8975f5c5SAndroid Build Coastguard Worker 
369*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib result = 0;
370*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, &result));
371*8975f5c5SAndroid Build Coastguard Worker 
372*8975f5c5SAndroid Build Coastguard Worker     EGLDeviceEXT device = reinterpret_cast<EGLDeviceEXT>(result);
373*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(EGL_NO_DEVICE_EXT, device);
374*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(IsEGLDeviceExtensionEnabled(device, "EGL_ANGLE_device_vulkan"));
375*8975f5c5SAndroid Build Coastguard Worker 
376*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_GET_INSTANCE_PROC_ADDR, &result));
377*8975f5c5SAndroid Build Coastguard Worker     PFN_vkGetInstanceProcAddr getInstanceProcAddr =
378*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<PFN_vkGetInstanceProcAddr>(result);
379*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(getInstanceProcAddr, nullptr);
380*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_SHARED_LIBVULKAN
381*8975f5c5SAndroid Build Coastguard Worker     volkInitializeCustom(getInstanceProcAddr);
382*8975f5c5SAndroid Build Coastguard Worker #endif  // ANGLE_SHARED_LIBVULKAN
383*8975f5c5SAndroid Build Coastguard Worker 
384*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_INSTANCE_ANGLE, &result));
385*8975f5c5SAndroid Build Coastguard Worker     mInstance = reinterpret_cast<VkInstance>(result);
386*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(mInstance, static_cast<VkInstance>(VK_NULL_HANDLE));
387*8975f5c5SAndroid Build Coastguard Worker 
388*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_SHARED_LIBVULKAN
389*8975f5c5SAndroid Build Coastguard Worker     volkLoadInstance(mInstance);
390*8975f5c5SAndroid Build Coastguard Worker #endif  // ANGLE_SHARED_LIBVULKAN
391*8975f5c5SAndroid Build Coastguard Worker 
392*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_PHYSICAL_DEVICE_ANGLE, &result));
393*8975f5c5SAndroid Build Coastguard Worker     mPhysicalDevice = reinterpret_cast<VkPhysicalDevice>(result);
394*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(mPhysicalDevice, static_cast<VkPhysicalDevice>(VK_NULL_HANDLE));
395*8975f5c5SAndroid Build Coastguard Worker 
396*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceMemoryProperties(mPhysicalDevice, &mMemoryProperties);
397*8975f5c5SAndroid Build Coastguard Worker 
398*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_DEVICE_ANGLE, &result));
399*8975f5c5SAndroid Build Coastguard Worker     mDevice = reinterpret_cast<VkDevice>(result);
400*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(mDevice, static_cast<VkDevice>(VK_NULL_HANDLE));
401*8975f5c5SAndroid Build Coastguard Worker 
402*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_QUEUE_ANGLE, &result));
403*8975f5c5SAndroid Build Coastguard Worker     mGraphicsQueue = reinterpret_cast<VkQueue>(result);
404*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(mGraphicsQueue, static_cast<VkQueue>(VK_NULL_HANDLE));
405*8975f5c5SAndroid Build Coastguard Worker 
406*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE, &result));
407*8975f5c5SAndroid Build Coastguard Worker     mGraphicsQueueFamilyIndex = static_cast<uint32_t>(result);
408*8975f5c5SAndroid Build Coastguard Worker 
409*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE, &result));
410*8975f5c5SAndroid Build Coastguard Worker     const char *const *enabledDeviceExtensions = reinterpret_cast<const char *const *>(result);
411*8975f5c5SAndroid Build Coastguard Worker 
412*8975f5c5SAndroid Build Coastguard Worker     mHasExternalMemoryFd =
413*8975f5c5SAndroid Build Coastguard Worker         HasExtension(enabledDeviceExtensions, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
414*8975f5c5SAndroid Build Coastguard Worker     mHasExternalSemaphoreFd =
415*8975f5c5SAndroid Build Coastguard Worker         HasExtension(enabledDeviceExtensions, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
416*8975f5c5SAndroid Build Coastguard Worker     mHasExternalMemoryFuchsia =
417*8975f5c5SAndroid Build Coastguard Worker         HasExtension(enabledDeviceExtensions, VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME);
418*8975f5c5SAndroid Build Coastguard Worker     mHasExternalSemaphoreFuchsia =
419*8975f5c5SAndroid Build Coastguard Worker         HasExtension(enabledDeviceExtensions, VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
420*8975f5c5SAndroid Build Coastguard Worker 
421*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_SHARED_LIBVULKAN
422*8975f5c5SAndroid Build Coastguard Worker     volkLoadDevice(mDevice);
423*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceExternalSemaphoreProperties =
424*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphoreProperties>(
425*8975f5c5SAndroid Build Coastguard Worker             vkGetInstanceProcAddr(mInstance, "vkGetPhysicalDeviceExternalSemaphoreProperties"));
426*8975f5c5SAndroid Build Coastguard Worker     ASSERT(vkGetPhysicalDeviceExternalSemaphoreProperties);
427*8975f5c5SAndroid Build Coastguard Worker #endif  // ANGLE_SHARED_LIBVULKAN
428*8975f5c5SAndroid Build Coastguard Worker 
429*8975f5c5SAndroid Build Coastguard Worker     VkCommandPoolCreateInfo commandPoolCreateInfo = {
430*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
431*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
432*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ 0,
433*8975f5c5SAndroid Build Coastguard Worker         /* .queueFamilyIndex = */ mGraphicsQueueFamilyIndex,
434*8975f5c5SAndroid Build Coastguard Worker     };
435*8975f5c5SAndroid Build Coastguard Worker     vkResult = vkCreateCommandPool(mDevice, &commandPoolCreateInfo, nullptr, &mCommandPool);
436*8975f5c5SAndroid Build Coastguard Worker     ASSERT(vkResult == VK_SUCCESS);
437*8975f5c5SAndroid Build Coastguard Worker 
438*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceImageFormatProperties2 =
439*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2>(
440*8975f5c5SAndroid Build Coastguard Worker             vkGetInstanceProcAddr(mInstance, "vkGetPhysicalDeviceImageFormatProperties2"));
441*8975f5c5SAndroid Build Coastguard Worker     ASSERT(vkGetPhysicalDeviceImageFormatProperties2);
442*8975f5c5SAndroid Build Coastguard Worker     vkGetMemoryFdKHR = reinterpret_cast<PFN_vkGetMemoryFdKHR>(
443*8975f5c5SAndroid Build Coastguard Worker         vkGetInstanceProcAddr(mInstance, "vkGetMemoryFdKHR"));
444*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mHasExternalMemoryFd || vkGetMemoryFdKHR);
445*8975f5c5SAndroid Build Coastguard Worker     vkGetSemaphoreFdKHR = reinterpret_cast<PFN_vkGetSemaphoreFdKHR>(
446*8975f5c5SAndroid Build Coastguard Worker         vkGetInstanceProcAddr(mInstance, "vkGetSemaphoreFdKHR"));
447*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mHasExternalSemaphoreFd || vkGetSemaphoreFdKHR);
448*8975f5c5SAndroid Build Coastguard Worker     vkGetMemoryZirconHandleFUCHSIA = reinterpret_cast<PFN_vkGetMemoryZirconHandleFUCHSIA>(
449*8975f5c5SAndroid Build Coastguard Worker         vkGetInstanceProcAddr(mInstance, "vkGetMemoryZirconHandleFUCHSIA"));
450*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mHasExternalMemoryFuchsia || vkGetMemoryZirconHandleFUCHSIA);
451*8975f5c5SAndroid Build Coastguard Worker     vkGetSemaphoreZirconHandleFUCHSIA = reinterpret_cast<PFN_vkGetSemaphoreZirconHandleFUCHSIA>(
452*8975f5c5SAndroid Build Coastguard Worker         vkGetInstanceProcAddr(mInstance, "vkGetSemaphoreZirconHandleFUCHSIA"));
453*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mHasExternalSemaphoreFuchsia || vkGetSemaphoreZirconHandleFUCHSIA);
454*8975f5c5SAndroid Build Coastguard Worker }
455*8975f5c5SAndroid Build Coastguard Worker 
createImage2D(VkFormat format,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,VkExtent3D extent,VkImage * imageOut,VkDeviceMemory * deviceMemoryOut,VkDeviceSize * deviceMemorySizeOut,VkImageCreateInfo * imageCreateInfoOut)456*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::createImage2D(VkFormat format,
457*8975f5c5SAndroid Build Coastguard Worker                                      VkImageCreateFlags createFlags,
458*8975f5c5SAndroid Build Coastguard Worker                                      VkImageUsageFlags usageFlags,
459*8975f5c5SAndroid Build Coastguard Worker                                      VkExtent3D extent,
460*8975f5c5SAndroid Build Coastguard Worker                                      VkImage *imageOut,
461*8975f5c5SAndroid Build Coastguard Worker                                      VkDeviceMemory *deviceMemoryOut,
462*8975f5c5SAndroid Build Coastguard Worker                                      VkDeviceSize *deviceMemorySizeOut,
463*8975f5c5SAndroid Build Coastguard Worker                                      VkImageCreateInfo *imageCreateInfoOut)
464*8975f5c5SAndroid Build Coastguard Worker {
465*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateInfo imageCreateInfo = {
466*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
467*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
468*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ createFlags,
469*8975f5c5SAndroid Build Coastguard Worker         /* .imageType = */ VK_IMAGE_TYPE_2D,
470*8975f5c5SAndroid Build Coastguard Worker         /* .format = */ format,
471*8975f5c5SAndroid Build Coastguard Worker         /* .extent = */ extent,
472*8975f5c5SAndroid Build Coastguard Worker         /* .mipLevels = */ 1,
473*8975f5c5SAndroid Build Coastguard Worker         /* .arrayLayers = */ 1,
474*8975f5c5SAndroid Build Coastguard Worker         /* .samples = */ VK_SAMPLE_COUNT_1_BIT,
475*8975f5c5SAndroid Build Coastguard Worker         /* .tiling = */ VK_IMAGE_TILING_OPTIMAL,
476*8975f5c5SAndroid Build Coastguard Worker         /* .usage = */ usageFlags,
477*8975f5c5SAndroid Build Coastguard Worker         /* .sharingMode = */ VK_SHARING_MODE_EXCLUSIVE,
478*8975f5c5SAndroid Build Coastguard Worker         /* .queueFamilyIndexCount = */ 0,
479*8975f5c5SAndroid Build Coastguard Worker         /* .pQueueFamilyIndices = */ nullptr,
480*8975f5c5SAndroid Build Coastguard Worker         /* initialLayout = */ VK_IMAGE_LAYOUT_UNDEFINED,
481*8975f5c5SAndroid Build Coastguard Worker     };
482*8975f5c5SAndroid Build Coastguard Worker 
483*8975f5c5SAndroid Build Coastguard Worker     VkImage image   = VK_NULL_HANDLE;
484*8975f5c5SAndroid Build Coastguard Worker     VkResult result = vkCreateImage(mDevice, &imageCreateInfo, nullptr, &image);
485*8975f5c5SAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
486*8975f5c5SAndroid Build Coastguard Worker     {
487*8975f5c5SAndroid Build Coastguard Worker         return result;
488*8975f5c5SAndroid Build Coastguard Worker     }
489*8975f5c5SAndroid Build Coastguard Worker 
490*8975f5c5SAndroid Build Coastguard Worker     VkMemoryPropertyFlags requestedMemoryPropertyFlags = 0;
491*8975f5c5SAndroid Build Coastguard Worker     VkMemoryRequirements memoryRequirements;
492*8975f5c5SAndroid Build Coastguard Worker     vkGetImageMemoryRequirements(mDevice, image, &memoryRequirements);
493*8975f5c5SAndroid Build Coastguard Worker     uint32_t memoryTypeIndex = FindMemoryType(mMemoryProperties, memoryRequirements.memoryTypeBits,
494*8975f5c5SAndroid Build Coastguard Worker                                               requestedMemoryPropertyFlags);
495*8975f5c5SAndroid Build Coastguard Worker     ASSERT(memoryTypeIndex != UINT32_MAX);
496*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize deviceMemorySize = memoryRequirements.size;
497*8975f5c5SAndroid Build Coastguard Worker 
498*8975f5c5SAndroid Build Coastguard Worker     VkMemoryAllocateInfo memoryAllocateInfo = {
499*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
500*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
501*8975f5c5SAndroid Build Coastguard Worker         /* .allocationSize = */ deviceMemorySize,
502*8975f5c5SAndroid Build Coastguard Worker         /* .memoryTypeIndex = */ memoryTypeIndex,
503*8975f5c5SAndroid Build Coastguard Worker     };
504*8975f5c5SAndroid Build Coastguard Worker 
505*8975f5c5SAndroid Build Coastguard Worker     VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
506*8975f5c5SAndroid Build Coastguard Worker     result = vkAllocateMemory(mDevice, &memoryAllocateInfo, nullptr, &deviceMemory);
507*8975f5c5SAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
508*8975f5c5SAndroid Build Coastguard Worker     {
509*8975f5c5SAndroid Build Coastguard Worker         vkDestroyImage(mDevice, image, nullptr);
510*8975f5c5SAndroid Build Coastguard Worker         return result;
511*8975f5c5SAndroid Build Coastguard Worker     }
512*8975f5c5SAndroid Build Coastguard Worker 
513*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize memoryOffset = 0;
514*8975f5c5SAndroid Build Coastguard Worker     result                    = vkBindImageMemory(mDevice, image, deviceMemory, memoryOffset);
515*8975f5c5SAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
516*8975f5c5SAndroid Build Coastguard Worker     {
517*8975f5c5SAndroid Build Coastguard Worker         vkFreeMemory(mDevice, deviceMemory, nullptr);
518*8975f5c5SAndroid Build Coastguard Worker         vkDestroyImage(mDevice, image, nullptr);
519*8975f5c5SAndroid Build Coastguard Worker         return result;
520*8975f5c5SAndroid Build Coastguard Worker     }
521*8975f5c5SAndroid Build Coastguard Worker 
522*8975f5c5SAndroid Build Coastguard Worker     *imageOut            = image;
523*8975f5c5SAndroid Build Coastguard Worker     *deviceMemoryOut     = deviceMemory;
524*8975f5c5SAndroid Build Coastguard Worker     *deviceMemorySizeOut = deviceMemorySize;
525*8975f5c5SAndroid Build Coastguard Worker     *imageCreateInfoOut  = imageCreateInfo;
526*8975f5c5SAndroid Build Coastguard Worker 
527*8975f5c5SAndroid Build Coastguard Worker     return VK_SUCCESS;
528*8975f5c5SAndroid Build Coastguard Worker }
529*8975f5c5SAndroid Build Coastguard Worker 
canCreateImageExternal(VkFormat format,VkImageType type,VkImageTiling tiling,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,VkExternalMemoryHandleTypeFlagBits handleType) const530*8975f5c5SAndroid Build Coastguard Worker bool VulkanHelper::canCreateImageExternal(VkFormat format,
531*8975f5c5SAndroid Build Coastguard Worker                                           VkImageType type,
532*8975f5c5SAndroid Build Coastguard Worker                                           VkImageTiling tiling,
533*8975f5c5SAndroid Build Coastguard Worker                                           VkImageCreateFlags createFlags,
534*8975f5c5SAndroid Build Coastguard Worker                                           VkImageUsageFlags usageFlags,
535*8975f5c5SAndroid Build Coastguard Worker                                           VkExternalMemoryHandleTypeFlagBits handleType) const
536*8975f5c5SAndroid Build Coastguard Worker {
537*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo = {
538*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
539*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
540*8975f5c5SAndroid Build Coastguard Worker         /* .handleType = */ handleType,
541*8975f5c5SAndroid Build Coastguard Worker     };
542*8975f5c5SAndroid Build Coastguard Worker 
543*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {
544*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
545*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &externalImageFormatInfo,
546*8975f5c5SAndroid Build Coastguard Worker         /* .format = */ format,
547*8975f5c5SAndroid Build Coastguard Worker         /* .type = */ type,
548*8975f5c5SAndroid Build Coastguard Worker         /* .tiling = */ tiling,
549*8975f5c5SAndroid Build Coastguard Worker         /* .usage = */ usageFlags,
550*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ createFlags,
551*8975f5c5SAndroid Build Coastguard Worker     };
552*8975f5c5SAndroid Build Coastguard Worker 
553*8975f5c5SAndroid Build Coastguard Worker     VkExternalImageFormatProperties externalImageFormatProperties = {
554*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
555*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
556*8975f5c5SAndroid Build Coastguard Worker     };
557*8975f5c5SAndroid Build Coastguard Worker 
558*8975f5c5SAndroid Build Coastguard Worker     VkImageFormatProperties2 imageFormatProperties = {
559*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
560*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &externalImageFormatProperties};
561*8975f5c5SAndroid Build Coastguard Worker 
562*8975f5c5SAndroid Build Coastguard Worker     VkResult result = vkGetPhysicalDeviceImageFormatProperties2(mPhysicalDevice, &imageFormatInfo,
563*8975f5c5SAndroid Build Coastguard Worker                                                                 &imageFormatProperties);
564*8975f5c5SAndroid Build Coastguard Worker     if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
565*8975f5c5SAndroid Build Coastguard Worker     {
566*8975f5c5SAndroid Build Coastguard Worker         return false;
567*8975f5c5SAndroid Build Coastguard Worker     }
568*8975f5c5SAndroid Build Coastguard Worker 
569*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
570*8975f5c5SAndroid Build Coastguard Worker 
571*8975f5c5SAndroid Build Coastguard Worker     constexpr VkExternalMemoryFeatureFlags kRequiredFeatures =
572*8975f5c5SAndroid Build Coastguard Worker         VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
573*8975f5c5SAndroid Build Coastguard Worker     if ((externalImageFormatProperties.externalMemoryProperties.externalMemoryFeatures &
574*8975f5c5SAndroid Build Coastguard Worker          kRequiredFeatures) != kRequiredFeatures)
575*8975f5c5SAndroid Build Coastguard Worker     {
576*8975f5c5SAndroid Build Coastguard Worker         return false;
577*8975f5c5SAndroid Build Coastguard Worker     }
578*8975f5c5SAndroid Build Coastguard Worker 
579*8975f5c5SAndroid Build Coastguard Worker     return true;
580*8975f5c5SAndroid Build Coastguard Worker }
581*8975f5c5SAndroid Build Coastguard Worker 
createImage2DExternal(VkFormat format,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,const void * imageCreateInfoPNext,VkExtent3D extent,VkExternalMemoryHandleTypeFlags handleTypes,VkImage * imageOut,VkDeviceMemory * deviceMemoryOut,VkDeviceSize * deviceMemorySizeOut)582*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::createImage2DExternal(VkFormat format,
583*8975f5c5SAndroid Build Coastguard Worker                                              VkImageCreateFlags createFlags,
584*8975f5c5SAndroid Build Coastguard Worker                                              VkImageUsageFlags usageFlags,
585*8975f5c5SAndroid Build Coastguard Worker                                              const void *imageCreateInfoPNext,
586*8975f5c5SAndroid Build Coastguard Worker                                              VkExtent3D extent,
587*8975f5c5SAndroid Build Coastguard Worker                                              VkExternalMemoryHandleTypeFlags handleTypes,
588*8975f5c5SAndroid Build Coastguard Worker                                              VkImage *imageOut,
589*8975f5c5SAndroid Build Coastguard Worker                                              VkDeviceMemory *deviceMemoryOut,
590*8975f5c5SAndroid Build Coastguard Worker                                              VkDeviceSize *deviceMemorySizeOut)
591*8975f5c5SAndroid Build Coastguard Worker {
592*8975f5c5SAndroid Build Coastguard Worker     VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = {
593*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
594*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ imageCreateInfoPNext,
595*8975f5c5SAndroid Build Coastguard Worker         /* .handleTypes = */ handleTypes,
596*8975f5c5SAndroid Build Coastguard Worker     };
597*8975f5c5SAndroid Build Coastguard Worker 
598*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateInfo imageCreateInfo = {
599*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
600*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &externalMemoryImageCreateInfo,
601*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ createFlags,
602*8975f5c5SAndroid Build Coastguard Worker         /* .imageType = */ VK_IMAGE_TYPE_2D,
603*8975f5c5SAndroid Build Coastguard Worker         /* .format = */ format,
604*8975f5c5SAndroid Build Coastguard Worker         /* .extent = */ extent,
605*8975f5c5SAndroid Build Coastguard Worker         /* .mipLevels = */ 1,
606*8975f5c5SAndroid Build Coastguard Worker         /* .arrayLayers = */ 1,
607*8975f5c5SAndroid Build Coastguard Worker         /* .samples = */ VK_SAMPLE_COUNT_1_BIT,
608*8975f5c5SAndroid Build Coastguard Worker         /* .tiling = */ VK_IMAGE_TILING_OPTIMAL,
609*8975f5c5SAndroid Build Coastguard Worker         /* .usage = */ usageFlags,
610*8975f5c5SAndroid Build Coastguard Worker         /* .sharingMode = */ VK_SHARING_MODE_EXCLUSIVE,
611*8975f5c5SAndroid Build Coastguard Worker         /* .queueFamilyIndexCount = */ 0,
612*8975f5c5SAndroid Build Coastguard Worker         /* .pQueueFamilyIndices = */ nullptr,
613*8975f5c5SAndroid Build Coastguard Worker         /* initialLayout = */ VK_IMAGE_LAYOUT_UNDEFINED,
614*8975f5c5SAndroid Build Coastguard Worker     };
615*8975f5c5SAndroid Build Coastguard Worker 
616*8975f5c5SAndroid Build Coastguard Worker     VkImage image   = VK_NULL_HANDLE;
617*8975f5c5SAndroid Build Coastguard Worker     VkResult result = vkCreateImage(mDevice, &imageCreateInfo, nullptr, &image);
618*8975f5c5SAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
619*8975f5c5SAndroid Build Coastguard Worker     {
620*8975f5c5SAndroid Build Coastguard Worker         return result;
621*8975f5c5SAndroid Build Coastguard Worker     }
622*8975f5c5SAndroid Build Coastguard Worker 
623*8975f5c5SAndroid Build Coastguard Worker     VkMemoryPropertyFlags requestedMemoryPropertyFlags = 0;
624*8975f5c5SAndroid Build Coastguard Worker     VkMemoryRequirements memoryRequirements;
625*8975f5c5SAndroid Build Coastguard Worker     vkGetImageMemoryRequirements(mDevice, image, &memoryRequirements);
626*8975f5c5SAndroid Build Coastguard Worker     uint32_t memoryTypeIndex = FindMemoryType(mMemoryProperties, memoryRequirements.memoryTypeBits,
627*8975f5c5SAndroid Build Coastguard Worker                                               requestedMemoryPropertyFlags);
628*8975f5c5SAndroid Build Coastguard Worker     ASSERT(memoryTypeIndex != UINT32_MAX);
629*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize deviceMemorySize = memoryRequirements.size;
630*8975f5c5SAndroid Build Coastguard Worker 
631*8975f5c5SAndroid Build Coastguard Worker     VkExportMemoryAllocateInfo exportMemoryAllocateInfo = {
632*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
633*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
634*8975f5c5SAndroid Build Coastguard Worker         /* .handleTypes = */ handleTypes,
635*8975f5c5SAndroid Build Coastguard Worker     };
636*8975f5c5SAndroid Build Coastguard Worker     VkMemoryDedicatedAllocateInfo memoryDedicatedAllocateInfo = {
637*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
638*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &exportMemoryAllocateInfo,
639*8975f5c5SAndroid Build Coastguard Worker         /* .image = */ image,
640*8975f5c5SAndroid Build Coastguard Worker     };
641*8975f5c5SAndroid Build Coastguard Worker     VkMemoryAllocateInfo memoryAllocateInfo = {
642*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
643*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &memoryDedicatedAllocateInfo,
644*8975f5c5SAndroid Build Coastguard Worker         /* .allocationSize = */ deviceMemorySize,
645*8975f5c5SAndroid Build Coastguard Worker         /* .memoryTypeIndex = */ memoryTypeIndex,
646*8975f5c5SAndroid Build Coastguard Worker     };
647*8975f5c5SAndroid Build Coastguard Worker 
648*8975f5c5SAndroid Build Coastguard Worker     VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
649*8975f5c5SAndroid Build Coastguard Worker     result = vkAllocateMemory(mDevice, &memoryAllocateInfo, nullptr, &deviceMemory);
650*8975f5c5SAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
651*8975f5c5SAndroid Build Coastguard Worker     {
652*8975f5c5SAndroid Build Coastguard Worker         vkDestroyImage(mDevice, image, nullptr);
653*8975f5c5SAndroid Build Coastguard Worker         return result;
654*8975f5c5SAndroid Build Coastguard Worker     }
655*8975f5c5SAndroid Build Coastguard Worker 
656*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize memoryOffset = 0;
657*8975f5c5SAndroid Build Coastguard Worker     result                    = vkBindImageMemory(mDevice, image, deviceMemory, memoryOffset);
658*8975f5c5SAndroid Build Coastguard Worker     if (result != VK_SUCCESS)
659*8975f5c5SAndroid Build Coastguard Worker     {
660*8975f5c5SAndroid Build Coastguard Worker         vkFreeMemory(mDevice, deviceMemory, nullptr);
661*8975f5c5SAndroid Build Coastguard Worker         vkDestroyImage(mDevice, image, nullptr);
662*8975f5c5SAndroid Build Coastguard Worker         return result;
663*8975f5c5SAndroid Build Coastguard Worker     }
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker     *imageOut            = image;
666*8975f5c5SAndroid Build Coastguard Worker     *deviceMemoryOut     = deviceMemory;
667*8975f5c5SAndroid Build Coastguard Worker     *deviceMemorySizeOut = deviceMemorySize;
668*8975f5c5SAndroid Build Coastguard Worker 
669*8975f5c5SAndroid Build Coastguard Worker     return VK_SUCCESS;
670*8975f5c5SAndroid Build Coastguard Worker }
671*8975f5c5SAndroid Build Coastguard Worker 
canCreateImageOpaqueFd(VkFormat format,VkImageType type,VkImageTiling tiling,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags) const672*8975f5c5SAndroid Build Coastguard Worker bool VulkanHelper::canCreateImageOpaqueFd(VkFormat format,
673*8975f5c5SAndroid Build Coastguard Worker                                           VkImageType type,
674*8975f5c5SAndroid Build Coastguard Worker                                           VkImageTiling tiling,
675*8975f5c5SAndroid Build Coastguard Worker                                           VkImageCreateFlags createFlags,
676*8975f5c5SAndroid Build Coastguard Worker                                           VkImageUsageFlags usageFlags) const
677*8975f5c5SAndroid Build Coastguard Worker {
678*8975f5c5SAndroid Build Coastguard Worker     if (!mHasExternalMemoryFd)
679*8975f5c5SAndroid Build Coastguard Worker     {
680*8975f5c5SAndroid Build Coastguard Worker         return false;
681*8975f5c5SAndroid Build Coastguard Worker     }
682*8975f5c5SAndroid Build Coastguard Worker 
683*8975f5c5SAndroid Build Coastguard Worker     return canCreateImageExternal(format, type, tiling, createFlags, usageFlags,
684*8975f5c5SAndroid Build Coastguard Worker                                   VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
685*8975f5c5SAndroid Build Coastguard Worker }
686*8975f5c5SAndroid Build Coastguard Worker 
createImage2DOpaqueFd(VkFormat format,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,const void * imageCreateInfoPNext,VkExtent3D extent,VkImage * imageOut,VkDeviceMemory * deviceMemoryOut,VkDeviceSize * deviceMemorySizeOut)687*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::createImage2DOpaqueFd(VkFormat format,
688*8975f5c5SAndroid Build Coastguard Worker                                              VkImageCreateFlags createFlags,
689*8975f5c5SAndroid Build Coastguard Worker                                              VkImageUsageFlags usageFlags,
690*8975f5c5SAndroid Build Coastguard Worker                                              const void *imageCreateInfoPNext,
691*8975f5c5SAndroid Build Coastguard Worker                                              VkExtent3D extent,
692*8975f5c5SAndroid Build Coastguard Worker                                              VkImage *imageOut,
693*8975f5c5SAndroid Build Coastguard Worker                                              VkDeviceMemory *deviceMemoryOut,
694*8975f5c5SAndroid Build Coastguard Worker                                              VkDeviceSize *deviceMemorySizeOut)
695*8975f5c5SAndroid Build Coastguard Worker {
696*8975f5c5SAndroid Build Coastguard Worker     return createImage2DExternal(format, createFlags, usageFlags, imageCreateInfoPNext, extent,
697*8975f5c5SAndroid Build Coastguard Worker                                  VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, imageOut,
698*8975f5c5SAndroid Build Coastguard Worker                                  deviceMemoryOut, deviceMemorySizeOut);
699*8975f5c5SAndroid Build Coastguard Worker }
700*8975f5c5SAndroid Build Coastguard Worker 
exportMemoryOpaqueFd(VkDeviceMemory deviceMemory,int * fd)701*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::exportMemoryOpaqueFd(VkDeviceMemory deviceMemory, int *fd)
702*8975f5c5SAndroid Build Coastguard Worker {
703*8975f5c5SAndroid Build Coastguard Worker     VkMemoryGetFdInfoKHR memoryGetFdInfo = {
704*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
705*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
706*8975f5c5SAndroid Build Coastguard Worker         /* .memory = */ deviceMemory,
707*8975f5c5SAndroid Build Coastguard Worker         /* .handleType = */ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
708*8975f5c5SAndroid Build Coastguard Worker     };
709*8975f5c5SAndroid Build Coastguard Worker 
710*8975f5c5SAndroid Build Coastguard Worker     return vkGetMemoryFdKHR(mDevice, &memoryGetFdInfo, fd);
711*8975f5c5SAndroid Build Coastguard Worker }
712*8975f5c5SAndroid Build Coastguard Worker 
canCreateImageZirconVmo(VkFormat format,VkImageType type,VkImageTiling tiling,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags) const713*8975f5c5SAndroid Build Coastguard Worker bool VulkanHelper::canCreateImageZirconVmo(VkFormat format,
714*8975f5c5SAndroid Build Coastguard Worker                                            VkImageType type,
715*8975f5c5SAndroid Build Coastguard Worker                                            VkImageTiling tiling,
716*8975f5c5SAndroid Build Coastguard Worker                                            VkImageCreateFlags createFlags,
717*8975f5c5SAndroid Build Coastguard Worker                                            VkImageUsageFlags usageFlags) const
718*8975f5c5SAndroid Build Coastguard Worker {
719*8975f5c5SAndroid Build Coastguard Worker     if (!mHasExternalMemoryFuchsia)
720*8975f5c5SAndroid Build Coastguard Worker     {
721*8975f5c5SAndroid Build Coastguard Worker         return false;
722*8975f5c5SAndroid Build Coastguard Worker     }
723*8975f5c5SAndroid Build Coastguard Worker 
724*8975f5c5SAndroid Build Coastguard Worker     return canCreateImageExternal(format, type, tiling, createFlags, usageFlags,
725*8975f5c5SAndroid Build Coastguard Worker                                   VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA);
726*8975f5c5SAndroid Build Coastguard Worker }
727*8975f5c5SAndroid Build Coastguard Worker 
createImage2DZirconVmo(VkFormat format,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,const void * imageCreateInfoPNext,VkExtent3D extent,VkImage * imageOut,VkDeviceMemory * deviceMemoryOut,VkDeviceSize * deviceMemorySizeOut)728*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::createImage2DZirconVmo(VkFormat format,
729*8975f5c5SAndroid Build Coastguard Worker                                               VkImageCreateFlags createFlags,
730*8975f5c5SAndroid Build Coastguard Worker                                               VkImageUsageFlags usageFlags,
731*8975f5c5SAndroid Build Coastguard Worker                                               const void *imageCreateInfoPNext,
732*8975f5c5SAndroid Build Coastguard Worker                                               VkExtent3D extent,
733*8975f5c5SAndroid Build Coastguard Worker                                               VkImage *imageOut,
734*8975f5c5SAndroid Build Coastguard Worker                                               VkDeviceMemory *deviceMemoryOut,
735*8975f5c5SAndroid Build Coastguard Worker                                               VkDeviceSize *deviceMemorySizeOut)
736*8975f5c5SAndroid Build Coastguard Worker {
737*8975f5c5SAndroid Build Coastguard Worker     return createImage2DExternal(format, createFlags, usageFlags, imageCreateInfoPNext, extent,
738*8975f5c5SAndroid Build Coastguard Worker                                  VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA, imageOut,
739*8975f5c5SAndroid Build Coastguard Worker                                  deviceMemoryOut, deviceMemorySizeOut);
740*8975f5c5SAndroid Build Coastguard Worker }
741*8975f5c5SAndroid Build Coastguard Worker 
exportMemoryZirconVmo(VkDeviceMemory deviceMemory,zx_handle_t * vmo)742*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::exportMemoryZirconVmo(VkDeviceMemory deviceMemory, zx_handle_t *vmo)
743*8975f5c5SAndroid Build Coastguard Worker {
744*8975f5c5SAndroid Build Coastguard Worker     VkMemoryGetZirconHandleInfoFUCHSIA memoryGetZirconHandleInfo = {
745*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
746*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
747*8975f5c5SAndroid Build Coastguard Worker         /* .memory = */ deviceMemory,
748*8975f5c5SAndroid Build Coastguard Worker         /* .handleType = */ VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA,
749*8975f5c5SAndroid Build Coastguard Worker     };
750*8975f5c5SAndroid Build Coastguard Worker 
751*8975f5c5SAndroid Build Coastguard Worker     return vkGetMemoryZirconHandleFUCHSIA(mDevice, &memoryGetZirconHandleInfo, vmo);
752*8975f5c5SAndroid Build Coastguard Worker }
753*8975f5c5SAndroid Build Coastguard Worker 
canCreateSemaphoreOpaqueFd() const754*8975f5c5SAndroid Build Coastguard Worker bool VulkanHelper::canCreateSemaphoreOpaqueFd() const
755*8975f5c5SAndroid Build Coastguard Worker {
756*8975f5c5SAndroid Build Coastguard Worker     if (!mHasExternalSemaphoreFd)
757*8975f5c5SAndroid Build Coastguard Worker     {
758*8975f5c5SAndroid Build Coastguard Worker         return false;
759*8975f5c5SAndroid Build Coastguard Worker     }
760*8975f5c5SAndroid Build Coastguard Worker 
761*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDeviceExternalSemaphoreInfo externalSemaphoreInfo = {
762*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
763*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
764*8975f5c5SAndroid Build Coastguard Worker         /* .handleType = */ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
765*8975f5c5SAndroid Build Coastguard Worker     };
766*8975f5c5SAndroid Build Coastguard Worker 
767*8975f5c5SAndroid Build Coastguard Worker     VkExternalSemaphoreProperties externalSemaphoreProperties = {
768*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
769*8975f5c5SAndroid Build Coastguard Worker     };
770*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceExternalSemaphoreProperties(mPhysicalDevice, &externalSemaphoreInfo,
771*8975f5c5SAndroid Build Coastguard Worker                                                    &externalSemaphoreProperties);
772*8975f5c5SAndroid Build Coastguard Worker 
773*8975f5c5SAndroid Build Coastguard Worker     constexpr VkExternalSemaphoreFeatureFlags kRequiredFeatures =
774*8975f5c5SAndroid Build Coastguard Worker         VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
775*8975f5c5SAndroid Build Coastguard Worker 
776*8975f5c5SAndroid Build Coastguard Worker     if ((externalSemaphoreProperties.externalSemaphoreFeatures & kRequiredFeatures) !=
777*8975f5c5SAndroid Build Coastguard Worker         kRequiredFeatures)
778*8975f5c5SAndroid Build Coastguard Worker     {
779*8975f5c5SAndroid Build Coastguard Worker         return false;
780*8975f5c5SAndroid Build Coastguard Worker     }
781*8975f5c5SAndroid Build Coastguard Worker 
782*8975f5c5SAndroid Build Coastguard Worker     return true;
783*8975f5c5SAndroid Build Coastguard Worker }
784*8975f5c5SAndroid Build Coastguard Worker 
createSemaphoreOpaqueFd(VkSemaphore * semaphore)785*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::createSemaphoreOpaqueFd(VkSemaphore *semaphore)
786*8975f5c5SAndroid Build Coastguard Worker {
787*8975f5c5SAndroid Build Coastguard Worker     VkExportSemaphoreCreateInfo exportSemaphoreCreateInfo = {
788*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
789*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
790*8975f5c5SAndroid Build Coastguard Worker         /* .handleTypes = */ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
791*8975f5c5SAndroid Build Coastguard Worker     };
792*8975f5c5SAndroid Build Coastguard Worker 
793*8975f5c5SAndroid Build Coastguard Worker     VkSemaphoreCreateInfo semaphoreCreateInfo = {
794*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
795*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &exportSemaphoreCreateInfo,
796*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ 0,
797*8975f5c5SAndroid Build Coastguard Worker     };
798*8975f5c5SAndroid Build Coastguard Worker 
799*8975f5c5SAndroid Build Coastguard Worker     return vkCreateSemaphore(mDevice, &semaphoreCreateInfo, nullptr, semaphore);
800*8975f5c5SAndroid Build Coastguard Worker }
801*8975f5c5SAndroid Build Coastguard Worker 
exportSemaphoreOpaqueFd(VkSemaphore semaphore,int * fd)802*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::exportSemaphoreOpaqueFd(VkSemaphore semaphore, int *fd)
803*8975f5c5SAndroid Build Coastguard Worker {
804*8975f5c5SAndroid Build Coastguard Worker     VkSemaphoreGetFdInfoKHR semaphoreGetFdInfo = {
805*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
806*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
807*8975f5c5SAndroid Build Coastguard Worker         /* .semaphore = */ semaphore,
808*8975f5c5SAndroid Build Coastguard Worker         /* .handleType = */ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
809*8975f5c5SAndroid Build Coastguard Worker     };
810*8975f5c5SAndroid Build Coastguard Worker 
811*8975f5c5SAndroid Build Coastguard Worker     return vkGetSemaphoreFdKHR(mDevice, &semaphoreGetFdInfo, fd);
812*8975f5c5SAndroid Build Coastguard Worker }
813*8975f5c5SAndroid Build Coastguard Worker 
canCreateSemaphoreZirconEvent() const814*8975f5c5SAndroid Build Coastguard Worker bool VulkanHelper::canCreateSemaphoreZirconEvent() const
815*8975f5c5SAndroid Build Coastguard Worker {
816*8975f5c5SAndroid Build Coastguard Worker     if (!mHasExternalSemaphoreFuchsia)
817*8975f5c5SAndroid Build Coastguard Worker     {
818*8975f5c5SAndroid Build Coastguard Worker         return false;
819*8975f5c5SAndroid Build Coastguard Worker     }
820*8975f5c5SAndroid Build Coastguard Worker 
821*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDeviceExternalSemaphoreInfo externalSemaphoreInfo = {
822*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
823*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
824*8975f5c5SAndroid Build Coastguard Worker         /* .handleType = */ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA,
825*8975f5c5SAndroid Build Coastguard Worker     };
826*8975f5c5SAndroid Build Coastguard Worker 
827*8975f5c5SAndroid Build Coastguard Worker     VkExternalSemaphoreProperties externalSemaphoreProperties = {
828*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
829*8975f5c5SAndroid Build Coastguard Worker     };
830*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceExternalSemaphoreProperties(mPhysicalDevice, &externalSemaphoreInfo,
831*8975f5c5SAndroid Build Coastguard Worker                                                    &externalSemaphoreProperties);
832*8975f5c5SAndroid Build Coastguard Worker 
833*8975f5c5SAndroid Build Coastguard Worker     constexpr VkExternalSemaphoreFeatureFlags kRequiredFeatures =
834*8975f5c5SAndroid Build Coastguard Worker         VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
835*8975f5c5SAndroid Build Coastguard Worker 
836*8975f5c5SAndroid Build Coastguard Worker     if ((externalSemaphoreProperties.externalSemaphoreFeatures & kRequiredFeatures) !=
837*8975f5c5SAndroid Build Coastguard Worker         kRequiredFeatures)
838*8975f5c5SAndroid Build Coastguard Worker     {
839*8975f5c5SAndroid Build Coastguard Worker         return false;
840*8975f5c5SAndroid Build Coastguard Worker     }
841*8975f5c5SAndroid Build Coastguard Worker 
842*8975f5c5SAndroid Build Coastguard Worker     return true;
843*8975f5c5SAndroid Build Coastguard Worker }
844*8975f5c5SAndroid Build Coastguard Worker 
createSemaphoreZirconEvent(VkSemaphore * semaphore)845*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::createSemaphoreZirconEvent(VkSemaphore *semaphore)
846*8975f5c5SAndroid Build Coastguard Worker {
847*8975f5c5SAndroid Build Coastguard Worker     VkExportSemaphoreCreateInfo exportSemaphoreCreateInfo = {
848*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
849*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
850*8975f5c5SAndroid Build Coastguard Worker         /* .handleTypes = */ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA,
851*8975f5c5SAndroid Build Coastguard Worker     };
852*8975f5c5SAndroid Build Coastguard Worker 
853*8975f5c5SAndroid Build Coastguard Worker     VkSemaphoreCreateInfo semaphoreCreateInfo = {
854*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
855*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &exportSemaphoreCreateInfo,
856*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ 0,
857*8975f5c5SAndroid Build Coastguard Worker     };
858*8975f5c5SAndroid Build Coastguard Worker 
859*8975f5c5SAndroid Build Coastguard Worker     return vkCreateSemaphore(mDevice, &semaphoreCreateInfo, nullptr, semaphore);
860*8975f5c5SAndroid Build Coastguard Worker }
861*8975f5c5SAndroid Build Coastguard Worker 
exportSemaphoreZirconEvent(VkSemaphore semaphore,zx_handle_t * event)862*8975f5c5SAndroid Build Coastguard Worker VkResult VulkanHelper::exportSemaphoreZirconEvent(VkSemaphore semaphore, zx_handle_t *event)
863*8975f5c5SAndroid Build Coastguard Worker {
864*8975f5c5SAndroid Build Coastguard Worker     VkSemaphoreGetZirconHandleInfoFUCHSIA semaphoreGetZirconHandleInfo = {
865*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
866*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
867*8975f5c5SAndroid Build Coastguard Worker         /* .semaphore = */ semaphore,
868*8975f5c5SAndroid Build Coastguard Worker         /* .handleType = */ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA,
869*8975f5c5SAndroid Build Coastguard Worker     };
870*8975f5c5SAndroid Build Coastguard Worker 
871*8975f5c5SAndroid Build Coastguard Worker     return vkGetSemaphoreZirconHandleFUCHSIA(mDevice, &semaphoreGetZirconHandleInfo, event);
872*8975f5c5SAndroid Build Coastguard Worker }
873*8975f5c5SAndroid Build Coastguard Worker 
releaseImageAndSignalSemaphore(VkImage image,VkImageLayout oldLayout,VkImageLayout newLayout,VkSemaphore semaphore)874*8975f5c5SAndroid Build Coastguard Worker void VulkanHelper::releaseImageAndSignalSemaphore(VkImage image,
875*8975f5c5SAndroid Build Coastguard Worker                                                   VkImageLayout oldLayout,
876*8975f5c5SAndroid Build Coastguard Worker                                                   VkImageLayout newLayout,
877*8975f5c5SAndroid Build Coastguard Worker                                                   VkSemaphore semaphore)
878*8975f5c5SAndroid Build Coastguard Worker {
879*8975f5c5SAndroid Build Coastguard Worker     VkResult result;
880*8975f5c5SAndroid Build Coastguard Worker 
881*8975f5c5SAndroid Build Coastguard Worker     VkCommandBuffer commandBuffers[]                      = {VK_NULL_HANDLE};
882*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t commandBufferCount                 = std::extent<decltype(commandBuffers)>();
883*8975f5c5SAndroid Build Coastguard Worker     VkCommandBufferAllocateInfo commandBufferAllocateInfo = {
884*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
885*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
886*8975f5c5SAndroid Build Coastguard Worker         /* .commandPool = */ mCommandPool,
887*8975f5c5SAndroid Build Coastguard Worker         /* .level = */ VK_COMMAND_BUFFER_LEVEL_PRIMARY,
888*8975f5c5SAndroid Build Coastguard Worker         /* .commandBufferCount = */ commandBufferCount,
889*8975f5c5SAndroid Build Coastguard Worker     };
890*8975f5c5SAndroid Build Coastguard Worker 
891*8975f5c5SAndroid Build Coastguard Worker     result = vkAllocateCommandBuffers(mDevice, &commandBufferAllocateInfo, commandBuffers);
892*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
893*8975f5c5SAndroid Build Coastguard Worker 
894*8975f5c5SAndroid Build Coastguard Worker     VkCommandBufferBeginInfo commandBufferBeginInfo = {
895*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
896*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
897*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
898*8975f5c5SAndroid Build Coastguard Worker         /* .pInheritanceInfo = */ nullptr,
899*8975f5c5SAndroid Build Coastguard Worker     };
900*8975f5c5SAndroid Build Coastguard Worker     result = vkBeginCommandBuffer(commandBuffers[0], &commandBufferBeginInfo);
901*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
902*8975f5c5SAndroid Build Coastguard Worker 
903*8975f5c5SAndroid Build Coastguard Worker     ImageMemoryBarrier(commandBuffers[0], image, mGraphicsQueueFamilyIndex,
904*8975f5c5SAndroid Build Coastguard Worker                        VK_QUEUE_FAMILY_EXTERNAL, oldLayout, newLayout);
905*8975f5c5SAndroid Build Coastguard Worker 
906*8975f5c5SAndroid Build Coastguard Worker     result = vkEndCommandBuffer(commandBuffers[0]);
907*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
908*8975f5c5SAndroid Build Coastguard Worker 
909*8975f5c5SAndroid Build Coastguard Worker     const VkSemaphore signalSemaphores[] = {
910*8975f5c5SAndroid Build Coastguard Worker         semaphore,
911*8975f5c5SAndroid Build Coastguard Worker     };
912*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t signalSemaphoreCount = std::extent<decltype(signalSemaphores)>();
913*8975f5c5SAndroid Build Coastguard Worker 
914*8975f5c5SAndroid Build Coastguard Worker     const VkSubmitInfo submits[] = {
915*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
916*8975f5c5SAndroid Build Coastguard Worker             /* .sType */ VK_STRUCTURE_TYPE_SUBMIT_INFO,
917*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
918*8975f5c5SAndroid Build Coastguard Worker             /* .waitSemaphoreCount = */ 0,
919*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitSemaphores = */ nullptr,
920*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitDstStageMask = */ nullptr,
921*8975f5c5SAndroid Build Coastguard Worker             /* .commandBufferCount = */ commandBufferCount,
922*8975f5c5SAndroid Build Coastguard Worker             /* .pCommandBuffers = */ commandBuffers,
923*8975f5c5SAndroid Build Coastguard Worker             /* .signalSemaphoreCount = */ signalSemaphoreCount,
924*8975f5c5SAndroid Build Coastguard Worker             /* .pSignalSemaphores = */ signalSemaphores,
925*8975f5c5SAndroid Build Coastguard Worker         },
926*8975f5c5SAndroid Build Coastguard Worker     };
927*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t submitCount = std::extent<decltype(submits)>();
928*8975f5c5SAndroid Build Coastguard Worker 
929*8975f5c5SAndroid Build Coastguard Worker     const VkFence fence = VK_NULL_HANDLE;
930*8975f5c5SAndroid Build Coastguard Worker     result              = vkQueueSubmit(mGraphicsQueue, submitCount, submits, fence);
931*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
932*8975f5c5SAndroid Build Coastguard Worker }
933*8975f5c5SAndroid Build Coastguard Worker 
signalSemaphore(VkSemaphore semaphore)934*8975f5c5SAndroid Build Coastguard Worker void VulkanHelper::signalSemaphore(VkSemaphore semaphore)
935*8975f5c5SAndroid Build Coastguard Worker {
936*8975f5c5SAndroid Build Coastguard Worker     VkResult result;
937*8975f5c5SAndroid Build Coastguard Worker 
938*8975f5c5SAndroid Build Coastguard Worker     const VkSemaphore signalSemaphores[] = {
939*8975f5c5SAndroid Build Coastguard Worker         semaphore,
940*8975f5c5SAndroid Build Coastguard Worker     };
941*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t signalSemaphoreCount = std::extent<decltype(signalSemaphores)>();
942*8975f5c5SAndroid Build Coastguard Worker 
943*8975f5c5SAndroid Build Coastguard Worker     const VkSubmitInfo submits[] = {
944*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
945*8975f5c5SAndroid Build Coastguard Worker             /* .sType */ VK_STRUCTURE_TYPE_SUBMIT_INFO,
946*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
947*8975f5c5SAndroid Build Coastguard Worker             /* .waitSemaphoreCount = */ 0,
948*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitSemaphores = */ nullptr,
949*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitDstStageMask = */ nullptr,
950*8975f5c5SAndroid Build Coastguard Worker             /* .commandBufferCount = */ 0,
951*8975f5c5SAndroid Build Coastguard Worker             /* .pCommandBuffers = */ nullptr,
952*8975f5c5SAndroid Build Coastguard Worker             /* .signalSemaphoreCount = */ signalSemaphoreCount,
953*8975f5c5SAndroid Build Coastguard Worker             /* .pSignalSemaphores = */ signalSemaphores,
954*8975f5c5SAndroid Build Coastguard Worker         },
955*8975f5c5SAndroid Build Coastguard Worker     };
956*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t submitCount = std::extent<decltype(submits)>();
957*8975f5c5SAndroid Build Coastguard Worker 
958*8975f5c5SAndroid Build Coastguard Worker     const VkFence fence = VK_NULL_HANDLE;
959*8975f5c5SAndroid Build Coastguard Worker     result              = vkQueueSubmit(mGraphicsQueue, submitCount, submits, fence);
960*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
961*8975f5c5SAndroid Build Coastguard Worker }
962*8975f5c5SAndroid Build Coastguard Worker 
waitSemaphoreAndAcquireImage(VkImage image,VkImageLayout oldLayout,VkImageLayout newLayout,VkSemaphore semaphore)963*8975f5c5SAndroid Build Coastguard Worker void VulkanHelper::waitSemaphoreAndAcquireImage(VkImage image,
964*8975f5c5SAndroid Build Coastguard Worker                                                 VkImageLayout oldLayout,
965*8975f5c5SAndroid Build Coastguard Worker                                                 VkImageLayout newLayout,
966*8975f5c5SAndroid Build Coastguard Worker                                                 VkSemaphore semaphore)
967*8975f5c5SAndroid Build Coastguard Worker {
968*8975f5c5SAndroid Build Coastguard Worker     VkResult result;
969*8975f5c5SAndroid Build Coastguard Worker 
970*8975f5c5SAndroid Build Coastguard Worker     VkCommandBuffer commandBuffers[]                      = {VK_NULL_HANDLE};
971*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t commandBufferCount                 = std::extent<decltype(commandBuffers)>();
972*8975f5c5SAndroid Build Coastguard Worker     VkCommandBufferAllocateInfo commandBufferAllocateInfo = {
973*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
974*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
975*8975f5c5SAndroid Build Coastguard Worker         /* .commandPool = */ mCommandPool,
976*8975f5c5SAndroid Build Coastguard Worker         /* .level = */ VK_COMMAND_BUFFER_LEVEL_PRIMARY,
977*8975f5c5SAndroid Build Coastguard Worker         /* .commandBufferCount = */ commandBufferCount,
978*8975f5c5SAndroid Build Coastguard Worker     };
979*8975f5c5SAndroid Build Coastguard Worker 
980*8975f5c5SAndroid Build Coastguard Worker     result = vkAllocateCommandBuffers(mDevice, &commandBufferAllocateInfo, commandBuffers);
981*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
982*8975f5c5SAndroid Build Coastguard Worker 
983*8975f5c5SAndroid Build Coastguard Worker     VkCommandBufferBeginInfo commandBufferBeginInfo = {
984*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
985*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
986*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
987*8975f5c5SAndroid Build Coastguard Worker         /* .pInheritanceInfo = */ nullptr,
988*8975f5c5SAndroid Build Coastguard Worker     };
989*8975f5c5SAndroid Build Coastguard Worker     result = vkBeginCommandBuffer(commandBuffers[0], &commandBufferBeginInfo);
990*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
991*8975f5c5SAndroid Build Coastguard Worker 
992*8975f5c5SAndroid Build Coastguard Worker     ImageMemoryBarrier(commandBuffers[0], image, VK_QUEUE_FAMILY_EXTERNAL,
993*8975f5c5SAndroid Build Coastguard Worker                        mGraphicsQueueFamilyIndex, oldLayout, newLayout);
994*8975f5c5SAndroid Build Coastguard Worker 
995*8975f5c5SAndroid Build Coastguard Worker     result = vkEndCommandBuffer(commandBuffers[0]);
996*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
997*8975f5c5SAndroid Build Coastguard Worker 
998*8975f5c5SAndroid Build Coastguard Worker     const VkSemaphore waitSemaphores[] = {
999*8975f5c5SAndroid Build Coastguard Worker         semaphore,
1000*8975f5c5SAndroid Build Coastguard Worker     };
1001*8975f5c5SAndroid Build Coastguard Worker     const VkPipelineStageFlags waitDstStageMasks[] = {
1002*8975f5c5SAndroid Build Coastguard Worker         VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1003*8975f5c5SAndroid Build Coastguard Worker     };
1004*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t waitSemaphoreCount    = std::extent<decltype(waitSemaphores)>();
1005*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t waitDstStageMaskCount = std::extent<decltype(waitDstStageMasks)>();
1006*8975f5c5SAndroid Build Coastguard Worker     static_assert(waitSemaphoreCount == waitDstStageMaskCount,
1007*8975f5c5SAndroid Build Coastguard Worker                   "waitSemaphores and waitDstStageMasks must be the same length");
1008*8975f5c5SAndroid Build Coastguard Worker 
1009*8975f5c5SAndroid Build Coastguard Worker     const VkSubmitInfo submits[] = {
1010*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
1011*8975f5c5SAndroid Build Coastguard Worker             /* .sType */ VK_STRUCTURE_TYPE_SUBMIT_INFO,
1012*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
1013*8975f5c5SAndroid Build Coastguard Worker             /* .waitSemaphoreCount = */ waitSemaphoreCount,
1014*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitSemaphores = */ waitSemaphores,
1015*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitDstStageMask = */ waitDstStageMasks,
1016*8975f5c5SAndroid Build Coastguard Worker             /* .commandBufferCount = */ commandBufferCount,
1017*8975f5c5SAndroid Build Coastguard Worker             /* .pCommandBuffers = */ commandBuffers,
1018*8975f5c5SAndroid Build Coastguard Worker             /* .signalSemaphoreCount = */ 0,
1019*8975f5c5SAndroid Build Coastguard Worker             /* .pSignalSemaphores = */ nullptr,
1020*8975f5c5SAndroid Build Coastguard Worker         },
1021*8975f5c5SAndroid Build Coastguard Worker     };
1022*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t submitCount = std::extent<decltype(submits)>();
1023*8975f5c5SAndroid Build Coastguard Worker 
1024*8975f5c5SAndroid Build Coastguard Worker     const VkFence fence = VK_NULL_HANDLE;
1025*8975f5c5SAndroid Build Coastguard Worker     result              = vkQueueSubmit(mGraphicsQueue, submitCount, submits, fence);
1026*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1027*8975f5c5SAndroid Build Coastguard Worker }
1028*8975f5c5SAndroid Build Coastguard Worker 
readPixels(VkImage srcImage,VkImageLayout srcImageLayout,VkFormat srcImageFormat,VkOffset3D imageOffset,VkExtent3D imageExtent,void * pixels,size_t pixelsSize)1029*8975f5c5SAndroid Build Coastguard Worker void VulkanHelper::readPixels(VkImage srcImage,
1030*8975f5c5SAndroid Build Coastguard Worker                               VkImageLayout srcImageLayout,
1031*8975f5c5SAndroid Build Coastguard Worker                               VkFormat srcImageFormat,
1032*8975f5c5SAndroid Build Coastguard Worker                               VkOffset3D imageOffset,
1033*8975f5c5SAndroid Build Coastguard Worker                               VkExtent3D imageExtent,
1034*8975f5c5SAndroid Build Coastguard Worker                               void *pixels,
1035*8975f5c5SAndroid Build Coastguard Worker                               size_t pixelsSize)
1036*8975f5c5SAndroid Build Coastguard Worker {
1037*8975f5c5SAndroid Build Coastguard Worker     ASSERT(srcImageFormat == VK_FORMAT_B8G8R8A8_UNORM ||
1038*8975f5c5SAndroid Build Coastguard Worker            srcImageFormat == VK_FORMAT_R8G8B8A8_UNORM);
1039*8975f5c5SAndroid Build Coastguard Worker     ASSERT(imageExtent.depth == 1);
1040*8975f5c5SAndroid Build Coastguard Worker     ASSERT(pixelsSize == 4 * imageExtent.width * imageExtent.height);
1041*8975f5c5SAndroid Build Coastguard Worker 
1042*8975f5c5SAndroid Build Coastguard Worker     VkBufferCreateInfo bufferCreateInfo = {
1043*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1044*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
1045*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ 0,
1046*8975f5c5SAndroid Build Coastguard Worker         /* .size = */ pixelsSize,
1047*8975f5c5SAndroid Build Coastguard Worker         /* .usage = */ VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1048*8975f5c5SAndroid Build Coastguard Worker         /* .sharingMode = */ VK_SHARING_MODE_EXCLUSIVE,
1049*8975f5c5SAndroid Build Coastguard Worker         /* .queueFamilyIndexCount = */ 0,
1050*8975f5c5SAndroid Build Coastguard Worker         /* .pQueueFamilyIndices = */ nullptr,
1051*8975f5c5SAndroid Build Coastguard Worker     };
1052*8975f5c5SAndroid Build Coastguard Worker     VkBuffer stagingBuffer = VK_NULL_HANDLE;
1053*8975f5c5SAndroid Build Coastguard Worker     VkResult result        = vkCreateBuffer(mDevice, &bufferCreateInfo, nullptr, &stagingBuffer);
1054*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1055*8975f5c5SAndroid Build Coastguard Worker 
1056*8975f5c5SAndroid Build Coastguard Worker     VkMemoryPropertyFlags requestedMemoryPropertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1057*8975f5c5SAndroid Build Coastguard Worker     VkMemoryRequirements memoryRequirements;
1058*8975f5c5SAndroid Build Coastguard Worker     vkGetBufferMemoryRequirements(mDevice, stagingBuffer, &memoryRequirements);
1059*8975f5c5SAndroid Build Coastguard Worker     uint32_t memoryTypeIndex = FindMemoryType(mMemoryProperties, memoryRequirements.memoryTypeBits,
1060*8975f5c5SAndroid Build Coastguard Worker                                               requestedMemoryPropertyFlags);
1061*8975f5c5SAndroid Build Coastguard Worker     ASSERT(memoryTypeIndex != UINT32_MAX);
1062*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize deviceMemorySize = memoryRequirements.size;
1063*8975f5c5SAndroid Build Coastguard Worker 
1064*8975f5c5SAndroid Build Coastguard Worker     VkMemoryDedicatedAllocateInfo memoryDedicatedAllocateInfo = {
1065*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1066*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
1067*8975f5c5SAndroid Build Coastguard Worker         /* .image = */ VK_NULL_HANDLE,
1068*8975f5c5SAndroid Build Coastguard Worker         /* .buffer = */ stagingBuffer,
1069*8975f5c5SAndroid Build Coastguard Worker     };
1070*8975f5c5SAndroid Build Coastguard Worker     VkMemoryAllocateInfo memoryAllocateInfo = {
1071*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1072*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &memoryDedicatedAllocateInfo,
1073*8975f5c5SAndroid Build Coastguard Worker         /* .allocationSize = */ deviceMemorySize,
1074*8975f5c5SAndroid Build Coastguard Worker         /* .memoryTypeIndex = */ memoryTypeIndex,
1075*8975f5c5SAndroid Build Coastguard Worker     };
1076*8975f5c5SAndroid Build Coastguard Worker 
1077*8975f5c5SAndroid Build Coastguard Worker     VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
1078*8975f5c5SAndroid Build Coastguard Worker     result = vkAllocateMemory(mDevice, &memoryAllocateInfo, nullptr, &deviceMemory);
1079*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1080*8975f5c5SAndroid Build Coastguard Worker 
1081*8975f5c5SAndroid Build Coastguard Worker     result = vkBindBufferMemory(mDevice, stagingBuffer, deviceMemory, 0 /* memoryOffset */);
1082*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1083*8975f5c5SAndroid Build Coastguard Worker 
1084*8975f5c5SAndroid Build Coastguard Worker     VkCommandBuffer commandBuffers[]                      = {VK_NULL_HANDLE};
1085*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t commandBufferCount                 = std::extent<decltype(commandBuffers)>();
1086*8975f5c5SAndroid Build Coastguard Worker     VkCommandBufferAllocateInfo commandBufferAllocateInfo = {
1087*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1088*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
1089*8975f5c5SAndroid Build Coastguard Worker         /* .commandPool = */ mCommandPool,
1090*8975f5c5SAndroid Build Coastguard Worker         /* .level = */ VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1091*8975f5c5SAndroid Build Coastguard Worker         /* .commandBufferCount = */ commandBufferCount,
1092*8975f5c5SAndroid Build Coastguard Worker     };
1093*8975f5c5SAndroid Build Coastguard Worker 
1094*8975f5c5SAndroid Build Coastguard Worker     result = vkAllocateCommandBuffers(mDevice, &commandBufferAllocateInfo, commandBuffers);
1095*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1096*8975f5c5SAndroid Build Coastguard Worker 
1097*8975f5c5SAndroid Build Coastguard Worker     VkCommandBufferBeginInfo commandBufferBeginInfo = {
1098*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1099*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
1100*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
1101*8975f5c5SAndroid Build Coastguard Worker         /* .pInheritanceInfo = */ nullptr,
1102*8975f5c5SAndroid Build Coastguard Worker     };
1103*8975f5c5SAndroid Build Coastguard Worker     result = vkBeginCommandBuffer(commandBuffers[0], &commandBufferBeginInfo);
1104*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1105*8975f5c5SAndroid Build Coastguard Worker 
1106*8975f5c5SAndroid Build Coastguard Worker     VkBufferImageCopy bufferImageCopies[] = {
1107*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
1108*8975f5c5SAndroid Build Coastguard Worker             /* .bufferOffset = */ 0,
1109*8975f5c5SAndroid Build Coastguard Worker             /* .bufferRowLength = */ 0,
1110*8975f5c5SAndroid Build Coastguard Worker             /* .bufferImageHeight = */ 0,
1111*8975f5c5SAndroid Build Coastguard Worker             /* .imageSubresources = */
1112*8975f5c5SAndroid Build Coastguard Worker             {
1113*8975f5c5SAndroid Build Coastguard Worker                 /* .aspectMask = */ VK_IMAGE_ASPECT_COLOR_BIT,
1114*8975f5c5SAndroid Build Coastguard Worker                 /* .mipLevel = */ 0,
1115*8975f5c5SAndroid Build Coastguard Worker                 /* .baseArrayLayer = */ 0,
1116*8975f5c5SAndroid Build Coastguard Worker                 /* .layerCount = */ 1,
1117*8975f5c5SAndroid Build Coastguard Worker             },
1118*8975f5c5SAndroid Build Coastguard Worker             /* .imageOffset = */ imageOffset,
1119*8975f5c5SAndroid Build Coastguard Worker             /* .imageExtent = */ imageExtent,
1120*8975f5c5SAndroid Build Coastguard Worker         },
1121*8975f5c5SAndroid Build Coastguard Worker     };
1122*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t bufferImageCopyCount = std::extent<decltype(bufferImageCopies)>();
1123*8975f5c5SAndroid Build Coastguard Worker 
1124*8975f5c5SAndroid Build Coastguard Worker     if (srcImageLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
1125*8975f5c5SAndroid Build Coastguard Worker     {
1126*8975f5c5SAndroid Build Coastguard Worker         VkImageMemoryBarrier imageMemoryBarriers = {
1127*8975f5c5SAndroid Build Coastguard Worker             /* .sType = */ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1128*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
1129*8975f5c5SAndroid Build Coastguard Worker             /* .srcAccessMask = */ VK_ACCESS_TRANSFER_WRITE_BIT,
1130*8975f5c5SAndroid Build Coastguard Worker             /* .dstAccessMask = */ VK_ACCESS_TRANSFER_READ_BIT,
1131*8975f5c5SAndroid Build Coastguard Worker             /* .oldLayout = */ srcImageLayout,
1132*8975f5c5SAndroid Build Coastguard Worker             /* .newLayout = */ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1133*8975f5c5SAndroid Build Coastguard Worker             /* .srcQueueFamilyIndex = */ mGraphicsQueueFamilyIndex,
1134*8975f5c5SAndroid Build Coastguard Worker             /* .dstQueueFamilyIndex = */ mGraphicsQueueFamilyIndex,
1135*8975f5c5SAndroid Build Coastguard Worker             /* .image = */ srcImage,
1136*8975f5c5SAndroid Build Coastguard Worker             /* .subresourceRange = */
1137*8975f5c5SAndroid Build Coastguard Worker             {
1138*8975f5c5SAndroid Build Coastguard Worker                 /* .aspectMask = */ VK_IMAGE_ASPECT_COLOR_BIT,
1139*8975f5c5SAndroid Build Coastguard Worker                 /* .baseMipLevel = */ 0,
1140*8975f5c5SAndroid Build Coastguard Worker                 /* .levelCount = */ 1,
1141*8975f5c5SAndroid Build Coastguard Worker                 /* .baseArrayLayer = */ 0,
1142*8975f5c5SAndroid Build Coastguard Worker                 /* .layerCount = */ 1,
1143*8975f5c5SAndroid Build Coastguard Worker             },
1144*8975f5c5SAndroid Build Coastguard Worker 
1145*8975f5c5SAndroid Build Coastguard Worker         };
1146*8975f5c5SAndroid Build Coastguard Worker         vkCmdPipelineBarrier(commandBuffers[0], VK_PIPELINE_STAGE_TRANSFER_BIT,
1147*8975f5c5SAndroid Build Coastguard Worker                              VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
1148*8975f5c5SAndroid Build Coastguard Worker                              &imageMemoryBarriers);
1149*8975f5c5SAndroid Build Coastguard Worker         srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1150*8975f5c5SAndroid Build Coastguard Worker     }
1151*8975f5c5SAndroid Build Coastguard Worker 
1152*8975f5c5SAndroid Build Coastguard Worker     vkCmdCopyImageToBuffer(commandBuffers[0], srcImage, srcImageLayout, stagingBuffer,
1153*8975f5c5SAndroid Build Coastguard Worker                            bufferImageCopyCount, bufferImageCopies);
1154*8975f5c5SAndroid Build Coastguard Worker 
1155*8975f5c5SAndroid Build Coastguard Worker     VkMemoryBarrier memoryBarriers[] = {
1156*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {/* .sType = */ VK_STRUCTURE_TYPE_MEMORY_BARRIER,
1157*8975f5c5SAndroid Build Coastguard Worker                      /* .pNext = */ nullptr,
1158*8975f5c5SAndroid Build Coastguard Worker                      /* .srcAccessMask = */ VK_ACCESS_MEMORY_WRITE_BIT,
1159*8975f5c5SAndroid Build Coastguard Worker                      /* .dstAccessMask = */ VK_ACCESS_HOST_READ_BIT},
1160*8975f5c5SAndroid Build Coastguard Worker     };
1161*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t memoryBarrierCount = std::extent<decltype(memoryBarriers)>();
1162*8975f5c5SAndroid Build Coastguard Worker     vkCmdPipelineBarrier(commandBuffers[0], VK_PIPELINE_STAGE_TRANSFER_BIT,
1163*8975f5c5SAndroid Build Coastguard Worker                          VK_PIPELINE_STAGE_HOST_BIT, 0 /* dependencyFlags */, memoryBarrierCount,
1164*8975f5c5SAndroid Build Coastguard Worker                          memoryBarriers, 0, nullptr, 0, nullptr);
1165*8975f5c5SAndroid Build Coastguard Worker 
1166*8975f5c5SAndroid Build Coastguard Worker     result = vkEndCommandBuffer(commandBuffers[0]);
1167*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1168*8975f5c5SAndroid Build Coastguard Worker 
1169*8975f5c5SAndroid Build Coastguard Worker     const VkSubmitInfo submits[] = {
1170*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
1171*8975f5c5SAndroid Build Coastguard Worker             /* .sType */ VK_STRUCTURE_TYPE_SUBMIT_INFO,
1172*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
1173*8975f5c5SAndroid Build Coastguard Worker             /* .waitSemaphoreCount = */ 0,
1174*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitSemaphores = */ nullptr,
1175*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitDstStageMask = */ nullptr,
1176*8975f5c5SAndroid Build Coastguard Worker             /* .commandBufferCount = */ commandBufferCount,
1177*8975f5c5SAndroid Build Coastguard Worker             /* .pCommandBuffers = */ commandBuffers,
1178*8975f5c5SAndroid Build Coastguard Worker             /* .signalSemaphoreCount = */ 0,
1179*8975f5c5SAndroid Build Coastguard Worker             /* .pSignalSemaphores = */ nullptr,
1180*8975f5c5SAndroid Build Coastguard Worker         },
1181*8975f5c5SAndroid Build Coastguard Worker     };
1182*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t submitCount = std::extent<decltype(submits)>();
1183*8975f5c5SAndroid Build Coastguard Worker 
1184*8975f5c5SAndroid Build Coastguard Worker     const VkFence fence = VK_NULL_HANDLE;
1185*8975f5c5SAndroid Build Coastguard Worker     result              = vkQueueSubmit(mGraphicsQueue, submitCount, submits, fence);
1186*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1187*8975f5c5SAndroid Build Coastguard Worker 
1188*8975f5c5SAndroid Build Coastguard Worker     result = vkQueueWaitIdle(mGraphicsQueue);
1189*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1190*8975f5c5SAndroid Build Coastguard Worker 
1191*8975f5c5SAndroid Build Coastguard Worker     vkFreeCommandBuffers(mDevice, mCommandPool, commandBufferCount, commandBuffers);
1192*8975f5c5SAndroid Build Coastguard Worker 
1193*8975f5c5SAndroid Build Coastguard Worker     void *stagingMemory = nullptr;
1194*8975f5c5SAndroid Build Coastguard Worker     result = vkMapMemory(mDevice, deviceMemory, 0 /* offset */, deviceMemorySize, 0 /* flags */,
1195*8975f5c5SAndroid Build Coastguard Worker                          &stagingMemory);
1196*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1197*8975f5c5SAndroid Build Coastguard Worker 
1198*8975f5c5SAndroid Build Coastguard Worker     VkMappedMemoryRange memoryRanges[] = {
1199*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
1200*8975f5c5SAndroid Build Coastguard Worker             /* .sType = */ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
1201*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
1202*8975f5c5SAndroid Build Coastguard Worker             /* .memory = */ deviceMemory,
1203*8975f5c5SAndroid Build Coastguard Worker             /* .offset = */ 0,
1204*8975f5c5SAndroid Build Coastguard Worker             /* .size = */ deviceMemorySize,
1205*8975f5c5SAndroid Build Coastguard Worker         },
1206*8975f5c5SAndroid Build Coastguard Worker     };
1207*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t memoryRangeCount = std::extent<decltype(memoryRanges)>();
1208*8975f5c5SAndroid Build Coastguard Worker 
1209*8975f5c5SAndroid Build Coastguard Worker     result = vkInvalidateMappedMemoryRanges(mDevice, memoryRangeCount, memoryRanges);
1210*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1211*8975f5c5SAndroid Build Coastguard Worker 
1212*8975f5c5SAndroid Build Coastguard Worker     memcpy(pixels, stagingMemory, pixelsSize);
1213*8975f5c5SAndroid Build Coastguard Worker 
1214*8975f5c5SAndroid Build Coastguard Worker     vkDestroyBuffer(mDevice, stagingBuffer, nullptr);
1215*8975f5c5SAndroid Build Coastguard Worker 
1216*8975f5c5SAndroid Build Coastguard Worker     vkUnmapMemory(mDevice, deviceMemory);
1217*8975f5c5SAndroid Build Coastguard Worker     vkFreeMemory(mDevice, deviceMemory, nullptr);
1218*8975f5c5SAndroid Build Coastguard Worker }
1219*8975f5c5SAndroid Build Coastguard Worker 
writePixels(VkImage dstImage,VkImageLayout imageLayout,VkFormat imageFormat,VkOffset3D imageOffset,VkExtent3D imageExtent,const void * pixels,size_t pixelsSize)1220*8975f5c5SAndroid Build Coastguard Worker void VulkanHelper::writePixels(VkImage dstImage,
1221*8975f5c5SAndroid Build Coastguard Worker                                VkImageLayout imageLayout,
1222*8975f5c5SAndroid Build Coastguard Worker                                VkFormat imageFormat,
1223*8975f5c5SAndroid Build Coastguard Worker                                VkOffset3D imageOffset,
1224*8975f5c5SAndroid Build Coastguard Worker                                VkExtent3D imageExtent,
1225*8975f5c5SAndroid Build Coastguard Worker                                const void *pixels,
1226*8975f5c5SAndroid Build Coastguard Worker                                size_t pixelsSize)
1227*8975f5c5SAndroid Build Coastguard Worker {
1228*8975f5c5SAndroid Build Coastguard Worker     ASSERT(imageFormat == VK_FORMAT_B8G8R8A8_UNORM || imageFormat == VK_FORMAT_R8G8B8A8_UNORM);
1229*8975f5c5SAndroid Build Coastguard Worker     ASSERT(imageExtent.depth == 1);
1230*8975f5c5SAndroid Build Coastguard Worker     ASSERT(pixelsSize == 4 * imageExtent.width * imageExtent.height);
1231*8975f5c5SAndroid Build Coastguard Worker 
1232*8975f5c5SAndroid Build Coastguard Worker     VkBufferCreateInfo bufferCreateInfo = {
1233*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1234*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
1235*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ 0,
1236*8975f5c5SAndroid Build Coastguard Worker         /* .size = */ pixelsSize,
1237*8975f5c5SAndroid Build Coastguard Worker         /* .usage = */ VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1238*8975f5c5SAndroid Build Coastguard Worker         /* .sharingMode = */ VK_SHARING_MODE_EXCLUSIVE,
1239*8975f5c5SAndroid Build Coastguard Worker         /* .queueFamilyIndexCount = */ 0,
1240*8975f5c5SAndroid Build Coastguard Worker         /* .pQueueFamilyIndices = */ nullptr,
1241*8975f5c5SAndroid Build Coastguard Worker     };
1242*8975f5c5SAndroid Build Coastguard Worker     VkBuffer stagingBuffer = VK_NULL_HANDLE;
1243*8975f5c5SAndroid Build Coastguard Worker     VkResult result        = vkCreateBuffer(mDevice, &bufferCreateInfo, nullptr, &stagingBuffer);
1244*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1245*8975f5c5SAndroid Build Coastguard Worker 
1246*8975f5c5SAndroid Build Coastguard Worker     VkMemoryPropertyFlags requestedMemoryPropertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1247*8975f5c5SAndroid Build Coastguard Worker     VkMemoryRequirements memoryRequirements;
1248*8975f5c5SAndroid Build Coastguard Worker     vkGetBufferMemoryRequirements(mDevice, stagingBuffer, &memoryRequirements);
1249*8975f5c5SAndroid Build Coastguard Worker     uint32_t memoryTypeIndex = FindMemoryType(mMemoryProperties, memoryRequirements.memoryTypeBits,
1250*8975f5c5SAndroid Build Coastguard Worker                                               requestedMemoryPropertyFlags);
1251*8975f5c5SAndroid Build Coastguard Worker     ASSERT(memoryTypeIndex != UINT32_MAX);
1252*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize deviceMemorySize = memoryRequirements.size;
1253*8975f5c5SAndroid Build Coastguard Worker 
1254*8975f5c5SAndroid Build Coastguard Worker     VkMemoryDedicatedAllocateInfo memoryDedicatedAllocateInfo = {
1255*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1256*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
1257*8975f5c5SAndroid Build Coastguard Worker         /* .image = */ VK_NULL_HANDLE,
1258*8975f5c5SAndroid Build Coastguard Worker         /* .buffer = */ stagingBuffer,
1259*8975f5c5SAndroid Build Coastguard Worker     };
1260*8975f5c5SAndroid Build Coastguard Worker     VkMemoryAllocateInfo memoryAllocateInfo = {
1261*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1262*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ &memoryDedicatedAllocateInfo,
1263*8975f5c5SAndroid Build Coastguard Worker         /* .allocationSize = */ deviceMemorySize,
1264*8975f5c5SAndroid Build Coastguard Worker         /* .memoryTypeIndex = */ memoryTypeIndex,
1265*8975f5c5SAndroid Build Coastguard Worker     };
1266*8975f5c5SAndroid Build Coastguard Worker 
1267*8975f5c5SAndroid Build Coastguard Worker     VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
1268*8975f5c5SAndroid Build Coastguard Worker     result = vkAllocateMemory(mDevice, &memoryAllocateInfo, nullptr, &deviceMemory);
1269*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1270*8975f5c5SAndroid Build Coastguard Worker 
1271*8975f5c5SAndroid Build Coastguard Worker     result = vkBindBufferMemory(mDevice, stagingBuffer, deviceMemory, 0 /* memoryOffset */);
1272*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1273*8975f5c5SAndroid Build Coastguard Worker 
1274*8975f5c5SAndroid Build Coastguard Worker     void *stagingMemory = nullptr;
1275*8975f5c5SAndroid Build Coastguard Worker     result = vkMapMemory(mDevice, deviceMemory, 0 /* offset */, deviceMemorySize, 0 /* flags */,
1276*8975f5c5SAndroid Build Coastguard Worker                          &stagingMemory);
1277*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1278*8975f5c5SAndroid Build Coastguard Worker 
1279*8975f5c5SAndroid Build Coastguard Worker     VkMappedMemoryRange memoryRanges[] = {
1280*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
1281*8975f5c5SAndroid Build Coastguard Worker             /* .sType = */ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
1282*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
1283*8975f5c5SAndroid Build Coastguard Worker             /* .memory = */ deviceMemory,
1284*8975f5c5SAndroid Build Coastguard Worker             /* .offset = */ 0,
1285*8975f5c5SAndroid Build Coastguard Worker             /* .size = */ deviceMemorySize,
1286*8975f5c5SAndroid Build Coastguard Worker         },
1287*8975f5c5SAndroid Build Coastguard Worker     };
1288*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t memoryRangeCount = std::extent<decltype(memoryRanges)>();
1289*8975f5c5SAndroid Build Coastguard Worker 
1290*8975f5c5SAndroid Build Coastguard Worker     result = vkInvalidateMappedMemoryRanges(mDevice, memoryRangeCount, memoryRanges);
1291*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1292*8975f5c5SAndroid Build Coastguard Worker 
1293*8975f5c5SAndroid Build Coastguard Worker     memcpy(stagingMemory, pixels, pixelsSize);
1294*8975f5c5SAndroid Build Coastguard Worker 
1295*8975f5c5SAndroid Build Coastguard Worker     vkUnmapMemory(mDevice, deviceMemory);
1296*8975f5c5SAndroid Build Coastguard Worker 
1297*8975f5c5SAndroid Build Coastguard Worker     VkCommandBuffer commandBuffers[]                      = {VK_NULL_HANDLE};
1298*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t commandBufferCount                 = std::extent<decltype(commandBuffers)>();
1299*8975f5c5SAndroid Build Coastguard Worker     VkCommandBufferAllocateInfo commandBufferAllocateInfo = {
1300*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1301*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
1302*8975f5c5SAndroid Build Coastguard Worker         /* .commandPool = */ mCommandPool,
1303*8975f5c5SAndroid Build Coastguard Worker         /* .level = */ VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1304*8975f5c5SAndroid Build Coastguard Worker         /* .commandBufferCount = */ commandBufferCount,
1305*8975f5c5SAndroid Build Coastguard Worker     };
1306*8975f5c5SAndroid Build Coastguard Worker 
1307*8975f5c5SAndroid Build Coastguard Worker     result = vkAllocateCommandBuffers(mDevice, &commandBufferAllocateInfo, commandBuffers);
1308*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1309*8975f5c5SAndroid Build Coastguard Worker 
1310*8975f5c5SAndroid Build Coastguard Worker     VkCommandBufferBeginInfo commandBufferBeginInfo = {
1311*8975f5c5SAndroid Build Coastguard Worker         /* .sType = */ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1312*8975f5c5SAndroid Build Coastguard Worker         /* .pNext = */ nullptr,
1313*8975f5c5SAndroid Build Coastguard Worker         /* .flags = */ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
1314*8975f5c5SAndroid Build Coastguard Worker         /* .pInheritanceInfo = */ nullptr,
1315*8975f5c5SAndroid Build Coastguard Worker     };
1316*8975f5c5SAndroid Build Coastguard Worker     result = vkBeginCommandBuffer(commandBuffers[0], &commandBufferBeginInfo);
1317*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1318*8975f5c5SAndroid Build Coastguard Worker 
1319*8975f5c5SAndroid Build Coastguard Worker     // Memory barrier for pipeline from Host-Write to Transfer-Read.
1320*8975f5c5SAndroid Build Coastguard Worker     VkMemoryBarrier memoryBarriers[] = {
1321*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {/* .sType = */ VK_STRUCTURE_TYPE_MEMORY_BARRIER,
1322*8975f5c5SAndroid Build Coastguard Worker                      /* .pNext = */ nullptr,
1323*8975f5c5SAndroid Build Coastguard Worker                      /* .srcAccessMask = */ VK_ACCESS_HOST_WRITE_BIT,
1324*8975f5c5SAndroid Build Coastguard Worker                      /* .dstAccessMask = */ VK_ACCESS_TRANSFER_READ_BIT},
1325*8975f5c5SAndroid Build Coastguard Worker     };
1326*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t memoryBarrierCount = std::extent<decltype(memoryBarriers)>();
1327*8975f5c5SAndroid Build Coastguard Worker     vkCmdPipelineBarrier(commandBuffers[0], VK_PIPELINE_STAGE_HOST_BIT,
1328*8975f5c5SAndroid Build Coastguard Worker                          VK_PIPELINE_STAGE_TRANSFER_BIT, 0 /* dependencyFlags */,
1329*8975f5c5SAndroid Build Coastguard Worker                          memoryBarrierCount, memoryBarriers, 0, nullptr, 0, nullptr);
1330*8975f5c5SAndroid Build Coastguard Worker 
1331*8975f5c5SAndroid Build Coastguard Worker     // Memory-barrier for image to Transfer-Write.
1332*8975f5c5SAndroid Build Coastguard Worker     if (imageLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
1333*8975f5c5SAndroid Build Coastguard Worker     {
1334*8975f5c5SAndroid Build Coastguard Worker         VkImageMemoryBarrier imageMemoryBarriers = {
1335*8975f5c5SAndroid Build Coastguard Worker             /* .sType = */ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1336*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
1337*8975f5c5SAndroid Build Coastguard Worker             /* .srcAccessMask = */ VK_ACCESS_NONE,
1338*8975f5c5SAndroid Build Coastguard Worker             /* .dstAccessMask = */ VK_ACCESS_TRANSFER_WRITE_BIT,
1339*8975f5c5SAndroid Build Coastguard Worker             /* .oldLayout = */ imageLayout,
1340*8975f5c5SAndroid Build Coastguard Worker             /* .newLayout = */ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1341*8975f5c5SAndroid Build Coastguard Worker             /* .srcQueueFamilyIndex = */ mGraphicsQueueFamilyIndex,
1342*8975f5c5SAndroid Build Coastguard Worker             /* .dstQueueFamilyIndex = */ mGraphicsQueueFamilyIndex,
1343*8975f5c5SAndroid Build Coastguard Worker             /* .image = */ dstImage,
1344*8975f5c5SAndroid Build Coastguard Worker             /* .subresourceRange = */
1345*8975f5c5SAndroid Build Coastguard Worker             {
1346*8975f5c5SAndroid Build Coastguard Worker                 /* .aspectMask = */ VK_IMAGE_ASPECT_COLOR_BIT,
1347*8975f5c5SAndroid Build Coastguard Worker                 /* .baseMipLevel = */ 0,
1348*8975f5c5SAndroid Build Coastguard Worker                 /* .levelCount = */ 1,
1349*8975f5c5SAndroid Build Coastguard Worker                 /* .baseArrayLayer = */ 0,
1350*8975f5c5SAndroid Build Coastguard Worker                 /* .layerCount = */ 1,
1351*8975f5c5SAndroid Build Coastguard Worker             },
1352*8975f5c5SAndroid Build Coastguard Worker 
1353*8975f5c5SAndroid Build Coastguard Worker         };
1354*8975f5c5SAndroid Build Coastguard Worker         vkCmdPipelineBarrier(commandBuffers[0], VK_PIPELINE_STAGE_TRANSFER_BIT,
1355*8975f5c5SAndroid Build Coastguard Worker                              VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
1356*8975f5c5SAndroid Build Coastguard Worker                              &imageMemoryBarriers);
1357*8975f5c5SAndroid Build Coastguard Worker         imageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1358*8975f5c5SAndroid Build Coastguard Worker     }
1359*8975f5c5SAndroid Build Coastguard Worker 
1360*8975f5c5SAndroid Build Coastguard Worker     // Issue the buffer to image copy.
1361*8975f5c5SAndroid Build Coastguard Worker     VkBufferImageCopy bufferImageCopies[] = {
1362*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
1363*8975f5c5SAndroid Build Coastguard Worker             /* .bufferOffset = */ 0,
1364*8975f5c5SAndroid Build Coastguard Worker             /* .bufferRowLength = */ 0,
1365*8975f5c5SAndroid Build Coastguard Worker             /* .bufferImageHeight = */ 0,
1366*8975f5c5SAndroid Build Coastguard Worker             /* .imageSubresources = */
1367*8975f5c5SAndroid Build Coastguard Worker             {
1368*8975f5c5SAndroid Build Coastguard Worker                 /* .aspectMask = */ VK_IMAGE_ASPECT_COLOR_BIT,
1369*8975f5c5SAndroid Build Coastguard Worker                 /* .mipLevel = */ 0,
1370*8975f5c5SAndroid Build Coastguard Worker                 /* .baseArrayLayer = */ 0,
1371*8975f5c5SAndroid Build Coastguard Worker                 /* .layerCount = */ 1,
1372*8975f5c5SAndroid Build Coastguard Worker             },
1373*8975f5c5SAndroid Build Coastguard Worker             /* .imageOffset = */ imageOffset,
1374*8975f5c5SAndroid Build Coastguard Worker             /* .imageExtent = */ imageExtent,
1375*8975f5c5SAndroid Build Coastguard Worker         },
1376*8975f5c5SAndroid Build Coastguard Worker     };
1377*8975f5c5SAndroid Build Coastguard Worker 
1378*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t bufferImageCopyCount = std::extent<decltype(bufferImageCopies)>();
1379*8975f5c5SAndroid Build Coastguard Worker 
1380*8975f5c5SAndroid Build Coastguard Worker     vkCmdCopyBufferToImage(commandBuffers[0], stagingBuffer, dstImage, imageLayout,
1381*8975f5c5SAndroid Build Coastguard Worker                            bufferImageCopyCount, bufferImageCopies);
1382*8975f5c5SAndroid Build Coastguard Worker 
1383*8975f5c5SAndroid Build Coastguard Worker     result = vkEndCommandBuffer(commandBuffers[0]);
1384*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1385*8975f5c5SAndroid Build Coastguard Worker 
1386*8975f5c5SAndroid Build Coastguard Worker     const VkSubmitInfo submits[] = {
1387*8975f5c5SAndroid Build Coastguard Worker         /* [0] = */ {
1388*8975f5c5SAndroid Build Coastguard Worker             /* .sType */ VK_STRUCTURE_TYPE_SUBMIT_INFO,
1389*8975f5c5SAndroid Build Coastguard Worker             /* .pNext = */ nullptr,
1390*8975f5c5SAndroid Build Coastguard Worker             /* .waitSemaphoreCount = */ 0,
1391*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitSemaphores = */ nullptr,
1392*8975f5c5SAndroid Build Coastguard Worker             /* .pWaitDstStageMask = */ nullptr,
1393*8975f5c5SAndroid Build Coastguard Worker             /* .commandBufferCount = */ commandBufferCount,
1394*8975f5c5SAndroid Build Coastguard Worker             /* .pCommandBuffers = */ commandBuffers,
1395*8975f5c5SAndroid Build Coastguard Worker             /* .signalSemaphoreCount = */ 0,
1396*8975f5c5SAndroid Build Coastguard Worker             /* .pSignalSemaphores = */ nullptr,
1397*8975f5c5SAndroid Build Coastguard Worker         },
1398*8975f5c5SAndroid Build Coastguard Worker     };
1399*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t submitCount = std::extent<decltype(submits)>();
1400*8975f5c5SAndroid Build Coastguard Worker 
1401*8975f5c5SAndroid Build Coastguard Worker     const VkFence fence = VK_NULL_HANDLE;
1402*8975f5c5SAndroid Build Coastguard Worker     result              = vkQueueSubmit(mGraphicsQueue, submitCount, submits, fence);
1403*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1404*8975f5c5SAndroid Build Coastguard Worker 
1405*8975f5c5SAndroid Build Coastguard Worker     result = vkQueueWaitIdle(mGraphicsQueue);
1406*8975f5c5SAndroid Build Coastguard Worker     ASSERT(result == VK_SUCCESS);
1407*8975f5c5SAndroid Build Coastguard Worker 
1408*8975f5c5SAndroid Build Coastguard Worker     vkFreeCommandBuffers(mDevice, mCommandPool, commandBufferCount, commandBuffers);
1409*8975f5c5SAndroid Build Coastguard Worker     vkDestroyBuffer(mDevice, stagingBuffer, nullptr);
1410*8975f5c5SAndroid Build Coastguard Worker     vkFreeMemory(mDevice, deviceMemory, nullptr);
1411*8975f5c5SAndroid Build Coastguard Worker }
1412*8975f5c5SAndroid Build Coastguard Worker 
1413*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
1414