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 // VulkanExternalHelper.h : Helper for allocating & managing vulkan external objects.
7 
8 #ifndef ANGLE_TESTS_TESTUTILS_VULKANEXTERNALHELPER_H_
9 #define ANGLE_TESTS_TESTUTILS_VULKANEXTERNALHELPER_H_
10 
11 #include "common/vulkan/vk_headers.h"
12 #include "vulkan/vulkan_fuchsia_ext.h"
13 
14 namespace angle
15 {
16 
17 class VulkanExternalHelper
18 {
19   public:
20     VulkanExternalHelper();
21     ~VulkanExternalHelper();
22 
23     void initialize(bool useSwiftshader, bool enableValidationLayers);
24 
getInstance()25     VkInstance getInstance() const { return mInstance; }
getPhysicalDevice()26     VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; }
getDevice()27     VkDevice getDevice() const { return mDevice; }
getGraphicsQueue()28     VkQueue getGraphicsQueue() const { return mGraphicsQueue; }
29 
30     bool canCreateImageExternal(VkFormat format,
31                                 VkImageType type,
32                                 VkImageTiling tiling,
33                                 VkImageCreateFlags createFlags,
34                                 VkImageUsageFlags usageFlags,
35                                 VkExternalMemoryHandleTypeFlagBits handleType) const;
36     VkResult createImage2DExternal(VkFormat format,
37                                    VkImageCreateFlags createFlags,
38                                    VkImageUsageFlags usageFlags,
39                                    VkExtent3D extent,
40                                    VkExternalMemoryHandleTypeFlags handleTypes,
41                                    VkImage *imageOut,
42                                    VkDeviceMemory *deviceMemoryOut,
43                                    VkDeviceSize *deviceMemorySizeOut);
44 
45     // VK_KHR_external_memory_fd
46     bool canCreateImageOpaqueFd(VkFormat format,
47                                 VkImageType type,
48                                 VkImageTiling tiling,
49                                 VkImageCreateFlags createFlags,
50                                 VkImageUsageFlags usageFlags) const;
51     VkResult createImage2DOpaqueFd(VkFormat format,
52                                    VkImageCreateFlags createFlags,
53                                    VkImageUsageFlags usageFlags,
54                                    VkExtent3D extent,
55                                    VkImage *imageOut,
56                                    VkDeviceMemory *deviceMemoryOut,
57                                    VkDeviceSize *deviceMemorySizeOut);
58     VkResult exportMemoryOpaqueFd(VkDeviceMemory deviceMemory, int *fd);
59 
60     // VK_FUCHSIA_external_memory
61     bool canCreateImageZirconVmo(VkFormat format,
62                                  VkImageType type,
63                                  VkImageTiling tiling,
64                                  VkImageCreateFlags createFlags,
65                                  VkImageUsageFlags usageFlags) const;
66     VkResult createImage2DZirconVmo(VkFormat format,
67                                     VkImageCreateFlags createFlags,
68                                     VkImageUsageFlags usageFlags,
69                                     VkExtent3D extent,
70                                     VkImage *imageOut,
71                                     VkDeviceMemory *deviceMemoryOut,
72                                     VkDeviceSize *deviceMemorySizeOut);
73     VkResult exportMemoryZirconVmo(VkDeviceMemory deviceMemory, zx_handle_t *vmo);
74 
75     // VK_KHR_external_semaphore_fd
76     bool canCreateSemaphoreOpaqueFd() const;
77     VkResult createSemaphoreOpaqueFd(VkSemaphore *semaphore);
78     VkResult exportSemaphoreOpaqueFd(VkSemaphore semaphore, int *fd);
79 
80     // VK_FUCHSIA_external_semaphore
81     bool canCreateSemaphoreZirconEvent() const;
82     VkResult createSemaphoreZirconEvent(VkSemaphore *semaphore);
83     VkResult exportSemaphoreZirconEvent(VkSemaphore semaphore, zx_handle_t *event);
84 
85     // Performs a queue ownership transfer to VK_QUEUE_FAMILY_EXTERNAL on an
86     // image owned by our instance. The current image layout must be |oldLayout|
87     // and will be in |newLayout| after the memory barrier. |semaphore|
88     // will be signaled upon completion of the release operation.
89     void releaseImageAndSignalSemaphore(VkImage image,
90                                         VkImageLayout oldLayout,
91                                         VkImageLayout newLayout,
92                                         VkSemaphore semaphore);
93 
94     // Performs a queue ownership transfer from VK_QUEUE_FAMILY_EXTERNAL on an
95     // image owned by an external instance. The current image layout must be
96     // |oldLayout| and will be in |newLayout| after the memory barrier. The
97     // barrier will wait for |semaphore|.
98     void waitSemaphoreAndAcquireImage(VkImage image,
99                                       VkImageLayout oldLayout,
100                                       VkImageLayout newLayout,
101                                       VkSemaphore semaphore);
102 
103     // Copies pixels out of an image. Currently only VK_FORMAT_R8G8B8A8_UNORM
104     // and VK_FORMAT_B8G8R8A8_UNORM formats are supported.
105     void readPixels(VkImage srcImage,
106                     VkImageLayout srcImageLayout,
107                     VkFormat srcImageFormat,
108                     VkOffset3D imageOffset,
109                     VkExtent3D imageExtent,
110                     void *pixels,
111                     size_t pixelsSize);
112 
113   private:
114     VkInstance mInstance             = VK_NULL_HANDLE;
115     VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
116     VkDevice mDevice                 = VK_NULL_HANDLE;
117     VkQueue mGraphicsQueue           = VK_NULL_HANDLE;
118     VkCommandPool mCommandPool       = VK_NULL_HANDLE;
119 
120     VkPhysicalDeviceMemoryProperties mMemoryProperties = {};
121 
122     uint32_t mGraphicsQueueFamilyIndex = UINT32_MAX;
123 
124     bool mHasExternalMemoryFd         = false;
125     bool mHasExternalMemoryFuchsia    = false;
126     bool mHasExternalSemaphoreFd      = false;
127     bool mHasExternalSemaphoreFuchsia = false;
128     PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2 =
129         nullptr;
130     PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR       = nullptr;
131     PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR = nullptr;
132     PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR
133         vkGetPhysicalDeviceExternalSemaphorePropertiesKHR                   = nullptr;
134     PFN_vkGetMemoryZirconHandleFUCHSIA vkGetMemoryZirconHandleFUCHSIA       = nullptr;
135     PFN_vkGetSemaphoreZirconHandleFUCHSIA vkGetSemaphoreZirconHandleFUCHSIA = nullptr;
136 };
137 
138 }  // namespace angle
139 
140 #endif  // ANGLE_TESTS_TESTUTILS_VULKANEXTERNALHELPER_H_
141