1 // 2 // Copyright 2019 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // VulkanHelper.h : Helper for vulkan. 7 8 #ifndef ANGLE_TESTS_TESTUTILS_VULKANHELPER_H_ 9 #define ANGLE_TESTS_TESTUTILS_VULKANHELPER_H_ 10 11 #include <mutex> 12 13 #include "common/angleutils.h" 14 #include "common/vulkan/vk_headers.h" 15 #include "test_utils/ANGLETest.h" 16 #include "vulkan/vulkan_fuchsia_ext.h" 17 18 namespace angle 19 { 20 class VulkanQueueMutex 21 { 22 public: 23 void init(EGLDisplay dpy); 24 25 void lock(); 26 void unlock(); 27 28 private: 29 EGLDisplay display; 30 }; 31 32 class VulkanHelper 33 { 34 public: 35 VulkanHelper(); 36 ~VulkanHelper(); 37 38 void initialize(bool useSwiftshader, bool enableValidationLayers); 39 void initializeFromANGLE(); 40 getInstance()41 VkInstance getInstance() const { return mInstance; } getPhysicalDevice()42 VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; } getDevice()43 VkDevice getDevice() const { return mDevice; } getGraphicsQueue()44 VkQueue getGraphicsQueue() const { return mGraphicsQueue; } getGraphicsQueueLock()45 std::unique_lock<VulkanQueueMutex> getGraphicsQueueLock() 46 { 47 if (mInitializedFromANGLE) 48 { 49 return std::unique_lock<VulkanQueueMutex>(mGraphicsQueueMutex); 50 } 51 return std::unique_lock<VulkanQueueMutex>(); 52 } 53 54 VkResult createImage2D(VkFormat format, 55 VkImageCreateFlags createFlags, 56 VkImageUsageFlags usageFlags, 57 VkExtent3D extent, 58 VkImage *imageOut, 59 VkDeviceMemory *deviceMemoryOut, 60 VkDeviceSize *deviceMemorySizeOut, 61 VkImageCreateInfo *imageCreateInfoOut); 62 bool canCreateImageExternal(VkFormat format, 63 VkImageType type, 64 VkImageTiling tiling, 65 VkImageCreateFlags createFlags, 66 VkImageUsageFlags usageFlags, 67 VkExternalMemoryHandleTypeFlagBits handleType) const; 68 VkResult createImage2DExternal(VkFormat format, 69 VkImageCreateFlags createFlags, 70 VkImageUsageFlags usageFlags, 71 const void *imageCreateInfoPNext, 72 VkExtent3D extent, 73 VkExternalMemoryHandleTypeFlags handleTypes, 74 VkImage *imageOut, 75 VkDeviceMemory *deviceMemoryOut, 76 VkDeviceSize *deviceMemorySizeOut); 77 78 // VK_KHR_external_memory_fd 79 bool canCreateImageOpaqueFd(VkFormat format, 80 VkImageType type, 81 VkImageTiling tiling, 82 VkImageCreateFlags createFlags, 83 VkImageUsageFlags usageFlags) const; 84 VkResult createImage2DOpaqueFd(VkFormat format, 85 VkImageCreateFlags createFlags, 86 VkImageUsageFlags usageFlags, 87 const void *imageCreateInfoPNext, 88 VkExtent3D extent, 89 VkImage *imageOut, 90 VkDeviceMemory *deviceMemoryOut, 91 VkDeviceSize *deviceMemorySizeOut); 92 VkResult exportMemoryOpaqueFd(VkDeviceMemory deviceMemory, int *fd); 93 94 // VK_FUCHSIA_external_memory 95 bool canCreateImageZirconVmo(VkFormat format, 96 VkImageType type, 97 VkImageTiling tiling, 98 VkImageCreateFlags createFlags, 99 VkImageUsageFlags usageFlags) const; 100 VkResult createImage2DZirconVmo(VkFormat format, 101 VkImageCreateFlags createFlags, 102 VkImageUsageFlags usageFlags, 103 const void *imageCreateInfoPNext, 104 VkExtent3D extent, 105 VkImage *imageOut, 106 VkDeviceMemory *deviceMemoryOut, 107 VkDeviceSize *deviceMemorySizeOut); 108 VkResult exportMemoryZirconVmo(VkDeviceMemory deviceMemory, zx_handle_t *vmo); 109 110 // VK_KHR_external_semaphore_fd 111 bool canCreateSemaphoreOpaqueFd() const; 112 VkResult createSemaphoreOpaqueFd(VkSemaphore *semaphore); 113 VkResult exportSemaphoreOpaqueFd(VkSemaphore semaphore, int *fd); 114 115 // VK_FUCHSIA_external_semaphore 116 bool canCreateSemaphoreZirconEvent() const; 117 VkResult createSemaphoreZirconEvent(VkSemaphore *semaphore); 118 VkResult exportSemaphoreZirconEvent(VkSemaphore semaphore, zx_handle_t *event); 119 120 // Performs a queue ownership transfer to VK_QUEUE_FAMILY_EXTERNAL on an 121 // image owned by our instance. The current image layout must be |oldLayout| 122 // and will be in |newLayout| after the memory barrier. |semaphore| 123 // will be signaled upon completion of the release operation. 124 void releaseImageAndSignalSemaphore(VkImage image, 125 VkImageLayout oldLayout, 126 VkImageLayout newLayout, 127 VkSemaphore semaphore); 128 // Just signal the given semaphore 129 void signalSemaphore(VkSemaphore semaphore); 130 131 // Performs a queue ownership transfer from VK_QUEUE_FAMILY_EXTERNAL on an 132 // image owned by an external instance. The current image layout must be 133 // |oldLayout| and will be in |newLayout| after the memory barrier. The 134 // barrier will wait for |semaphore|. 135 void waitSemaphoreAndAcquireImage(VkImage image, 136 VkImageLayout oldLayout, 137 VkImageLayout newLayout, 138 VkSemaphore semaphore); 139 140 // Writes pixels into an image. Currently only VK_FORMAT_R8G8B8A8_UNORM 141 // and VK_FORMAT_B8G8R8A8_UNORM formats are supported. 142 void writePixels(VkImage dstImage, 143 VkImageLayout imageLayout, 144 VkFormat imageFormat, 145 VkOffset3D imageOffset, 146 VkExtent3D imageExtent, 147 const void *pixels, 148 size_t pixelsSize); 149 150 // Copies pixels out of an image. Currently only VK_FORMAT_R8G8B8A8_UNORM 151 // and VK_FORMAT_B8G8R8A8_UNORM formats are supported. 152 void readPixels(VkImage srcImage, 153 VkImageLayout srcImageLayout, 154 VkFormat srcImageFormat, 155 VkOffset3D imageOffset, 156 VkExtent3D imageExtent, 157 void *pixels, 158 size_t pixelsSize); 159 160 private: 161 bool mInitializedFromANGLE = false; 162 VkInstance mInstance = VK_NULL_HANDLE; 163 VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE; 164 VkDevice mDevice = VK_NULL_HANDLE; 165 VkQueue mGraphicsQueue = VK_NULL_HANDLE; 166 VkCommandPool mCommandPool = VK_NULL_HANDLE; 167 VulkanQueueMutex mGraphicsQueueMutex; 168 169 VkPhysicalDeviceMemoryProperties mMemoryProperties = {}; 170 171 uint32_t mGraphicsQueueFamilyIndex = UINT32_MAX; 172 173 bool mHasExternalMemoryFd = false; 174 bool mHasExternalMemoryFuchsia = false; 175 bool mHasExternalSemaphoreFd = false; 176 bool mHasExternalSemaphoreFuchsia = false; 177 PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2 = 178 nullptr; 179 PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR = nullptr; 180 PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR = nullptr; 181 ANGLE_MAYBE_UNUSED_PRIVATE_FIELD PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR 182 vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = nullptr; 183 PFN_vkGetMemoryZirconHandleFUCHSIA vkGetMemoryZirconHandleFUCHSIA = nullptr; 184 PFN_vkGetSemaphoreZirconHandleFUCHSIA vkGetSemaphoreZirconHandleFUCHSIA = nullptr; 185 }; 186 187 } // namespace angle 188 189 #endif // ANGLE_TESTS_TESTUTILS_VULKANHELPER_H_ 190