1 #ifndef _VKTEXTERNALMEMORYUTIL_HPP 2 #define _VKTEXTERNALMEMORYUTIL_HPP 3 /*------------------------------------------------------------------------- 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2016 Google Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 * \brief Vulkan external memory utilities 22 *//*--------------------------------------------------------------------*/ 23 24 #include "tcuDefs.hpp" 25 26 #include "vkPlatform.hpp" 27 #include "vkRefUtil.hpp" 28 29 #include "deMemory.h" 30 #include "deInt32.h" 31 32 #ifndef CTS_USES_VULKANSC 33 34 namespace vkt 35 { 36 37 namespace ExternalMemoryUtil 38 { 39 40 41 class NativeHandle 42 { 43 public: 44 enum Win32HandleType 45 { 46 WIN32HANDLETYPE_NT = 0, 47 WIN32HANDLETYPE_KMT, 48 49 WIN32HANDLETYPE_LAST 50 }; 51 52 NativeHandle (void); 53 NativeHandle (const NativeHandle& other); 54 NativeHandle (int fd); 55 NativeHandle (Win32HandleType type, vk::pt::Win32Handle handle); 56 NativeHandle (vk::pt::AndroidHardwareBufferPtr buffer); 57 ~NativeHandle (void); 58 59 NativeHandle& operator= (int fd); 60 NativeHandle& operator= (vk::pt::AndroidHardwareBufferPtr buffer); 61 62 void setZirconHandle (vk::pt::zx_handle_t zirconHandle); 63 void setWin32Handle (Win32HandleType type, vk::pt::Win32Handle handle); 64 vk::pt::Win32Handle getWin32Handle (void) const; 65 void setHostPtr (void* hostPtr); 66 void* getHostPtr (void) const; 67 int getFd (void) const; 68 vk::pt::AndroidHardwareBufferPtr getAndroidHardwareBuffer (void) const; 69 vk::pt::zx_handle_t getZirconHandle (void) const; 70 void disown (void); 71 void reset (void); 72 73 private: 74 int m_fd; 75 vk::pt::zx_handle_t m_zirconHandle; 76 Win32HandleType m_win32HandleType; 77 vk::pt::Win32Handle m_win32Handle; 78 vk::pt::AndroidHardwareBufferPtr m_androidHardwareBuffer; 79 void* m_hostPtr; 80 81 // Disabled 82 NativeHandle& operator= (const NativeHandle&); 83 }; 84 85 class AndroidHardwareBufferExternalApi 86 { 87 public: 88 89 /** 90 * getInstance obtains the object, that provides an interface to AHB system APIs . 91 * If the AHB system API is not supported or if it is not built as supported with the CTS, 92 * then this function would return a null object. 93 */ 94 static AndroidHardwareBufferExternalApi* getInstance(); 95 96 /* Is AndroidHardwareBuffer supported? */ 97 static bool supportsAhb(); 98 99 /* Are Cube maps supported on current api level? */ 100 static bool supportsCubeMap(); 101 102 /** 103 * Allocates a buffer that backs an AHardwareBuffer using the passed parameter as follows: 104 * width; - width in pixels 105 * height; - height in pixels 106 * layers; - number of images 107 * format; - One of AHARDWAREBUFFER_FORMAT_* 108 * usage; - Combination of AHARDWAREBUFFER_USAGE_* 109 * 110 * Returns a valid AndroidHardwareBufferPtr object on success, or an null AndroidHardwareBufferPtr if 111 * the allocation fails for any reason. 112 */ 113 virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32 height, deUint32 layers, deUint32 format, deUint64 usage) = 0; 114 115 /** 116 * Acquire a reference on the given AHardwareBuffer object. This prevents the 117 * object from being deleted until the last reference is removed. 118 */ 119 virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer) = 0; 120 121 /** 122 * Remove a reference that was previously acquired with 123 * AHardwareBuffer_acquire(). 124 */ 125 virtual void release(vk::pt::AndroidHardwareBufferPtr buffer) = 0; 126 127 /** 128 * Return a description of the AHardwareBuffer in the passed in the following fields, if not NULL: 129 * width; - width in pixels 130 * height; - height in pixels 131 * layers; - number of images 132 * format; - One of AHARDWAREBUFFER_FORMAT_* 133 * usage; - Combination of AHARDWAREBUFFER_USAGE_* 134 * 135 */ 136 virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer, 137 deUint32* width, 138 deUint32* height, 139 deUint32* layers, 140 deUint32* format, 141 deUint64* usage, 142 deUint32* stride) = 0; 143 144 145 virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag) = 0; 146 virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag) = 0; 147 virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat) = 0; 148 virtual deUint64 mustSupportAhbUsageFlags() = 0; 149 virtual bool ahbFormatIsBlob(deUint32 format) = 0; 150 151 virtual ~AndroidHardwareBufferExternalApi(); 152 153 protected: 154 // Protected Constructor 155 AndroidHardwareBufferExternalApi(); 156 157 private: 158 // Stop the compiler generating methods of copy the object 159 AndroidHardwareBufferExternalApi(AndroidHardwareBufferExternalApi const& copy); // Not Implemented 160 AndroidHardwareBufferExternalApi& operator=(AndroidHardwareBufferExternalApi const& copy); // Not Implemented 161 162 static bool loadAhbDynamicApis(deInt32 sdkVersion); 163 }; 164 165 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type); 166 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type); 167 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type); 168 169 enum Permanence 170 { 171 PERMANENCE_PERMANENT = 0, 172 PERMANENCE_TEMPORARY 173 }; 174 175 enum Transference 176 { 177 TRANSFERENCE_COPY = 0, 178 TRANSFERENCE_REFERENCE 179 }; 180 181 struct ExternalHostMemory 182 { ExternalHostMemoryvkt::ExternalMemoryUtil::ExternalHostMemory183 ExternalHostMemory(vk::VkDeviceSize aSize, vk::VkDeviceSize aAlignment) 184 : size(deAlignSize(static_cast<size_t>(aSize), static_cast<size_t>(aAlignment))) 185 { 186 data = deAlignedMalloc(this->size, static_cast<size_t>(aAlignment)); 187 } 188 ~ExternalHostMemoryvkt::ExternalMemoryUtil::ExternalHostMemory189 ~ExternalHostMemory() 190 { 191 if (data != DE_NULL) 192 { 193 deAlignedFree(data); 194 } 195 } 196 197 size_t size; 198 void* data; 199 }; 200 201 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBits type, 202 Permanence permanence); 203 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBits type); 204 205 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBits type, 206 Permanence permanence); 207 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBits type); 208 209 int getMemoryFd (const vk::DeviceInterface& vkd, 210 vk::VkDevice device, 211 vk::VkDeviceMemory memory, 212 vk::VkExternalMemoryHandleTypeFlagBits externalType); 213 214 void getMemoryNative (const vk::DeviceInterface& vkd, 215 vk::VkDevice device, 216 vk::VkDeviceMemory memory, 217 vk::VkExternalMemoryHandleTypeFlagBits externalType, 218 NativeHandle& nativeHandle); 219 220 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface& vkd, 221 vk::VkDevice device, 222 vk::VkExternalSemaphoreHandleTypeFlagBits externalType); 223 224 vk::Move<vk::VkSemaphore> createExportableSemaphoreType (const vk::DeviceInterface& vkd, 225 vk::VkDevice device, 226 vk::VkSemaphoreType semaphoreType, 227 vk::VkExternalSemaphoreHandleTypeFlagBits externalType); 228 229 int getSemaphoreFd (const vk::DeviceInterface& vkd, 230 vk::VkDevice device, 231 vk::VkSemaphore semaphore, 232 vk::VkExternalSemaphoreHandleTypeFlagBits externalType); 233 234 void getSemaphoreNative (const vk::DeviceInterface& vkd, 235 vk::VkDevice device, 236 vk::VkSemaphore semaphore, 237 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 238 NativeHandle& nativeHandle); 239 240 void importSemaphore (const vk::DeviceInterface& vkd, 241 const vk::VkDevice device, 242 const vk::VkSemaphore semaphore, 243 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 244 NativeHandle& handle, 245 vk::VkSemaphoreImportFlags flags); 246 247 vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface& vkd, 248 const vk::VkDevice device, 249 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 250 NativeHandle& handle, 251 vk::VkSemaphoreImportFlags flags); 252 253 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface& vkd, 254 vk::VkDevice device, 255 vk::VkExternalFenceHandleTypeFlagBits externalType); 256 257 int getFenceFd (const vk::DeviceInterface& vkd, 258 vk::VkDevice device, 259 vk::VkFence fence, 260 vk::VkExternalFenceHandleTypeFlagBits externalType); 261 262 void getFenceNative (const vk::DeviceInterface& vkd, 263 vk::VkDevice device, 264 vk::VkFence fence, 265 vk::VkExternalFenceHandleTypeFlagBits externalType, 266 NativeHandle& nativeHandle, 267 bool expectFenceUnsignaled = true); 268 269 void importFence (const vk::DeviceInterface& vkd, 270 const vk::VkDevice device, 271 const vk::VkFence fence, 272 vk::VkExternalFenceHandleTypeFlagBits externalType, 273 NativeHandle& handle, 274 vk::VkFenceImportFlags flags); 275 276 vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface& vkd, 277 const vk::VkDevice device, 278 vk::VkExternalFenceHandleTypeFlagBits externalType, 279 NativeHandle& handle, 280 vk::VkFenceImportFlags flags); 281 282 deUint32 chooseMemoryType (deUint32 bits); 283 284 deUint32 chooseHostVisibleMemoryType (deUint32 bits, 285 const vk::VkPhysicalDeviceMemoryProperties properties); 286 287 vk::VkMemoryRequirements getImageMemoryRequirements (const vk::DeviceInterface& vkd, 288 vk::VkDevice device, 289 vk::VkImage image, 290 vk::VkExternalMemoryHandleTypeFlagBits externalType); 291 292 // If buffer is not null use dedicated allocation 293 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd, 294 vk::VkDevice device, 295 vk::VkDeviceSize allocationSize, 296 deUint32 memoryTypeIndex, 297 vk::VkExternalMemoryHandleTypeFlagBits externalType, 298 vk::VkBuffer buffer); 299 300 // If image is not null use dedicated allocation 301 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd, 302 vk::VkDevice device, 303 vk::VkDeviceSize allocationSize, 304 deUint32 memoryTypeIndex, 305 vk::VkExternalMemoryHandleTypeFlagBits externalType, 306 vk::VkImage image); 307 308 /* 309 // \note hostVisible argument is strict. Setting it to false will cause NotSupportedError to be thrown if non-host visible memory doesn't exist. 310 // If buffer is not null use dedicated allocation 311 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::InstanceInterface& vki, 312 vk::VkPhysicalDevice physicalDevice, 313 const vk::DeviceInterface& vkd, 314 vk::VkDevice device, 315 const vk::VkMemoryRequirements& requirements, 316 vk::VkExternalMemoryHandleTypeFlagBits externalType, 317 bool hostVisible, 318 vk::VkBuffer buffer, 319 deUint32& exportedMemoryTypeIndex); 320 */ 321 322 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd, 323 vk::VkDevice device, 324 const vk::VkMemoryRequirements& requirements, 325 vk::VkExternalMemoryHandleTypeFlagBits externalType, 326 deUint32 memoryTypeIndex, 327 NativeHandle& handle); 328 329 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd, 330 vk::VkDevice device, 331 vk::VkBuffer buffer, 332 const vk::VkMemoryRequirements& requirements, 333 vk::VkExternalMemoryHandleTypeFlagBits externalType, 334 deUint32 memoryTypeIndex, 335 NativeHandle& handle); 336 337 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd, 338 vk::VkDevice device, 339 vk::VkImage image, 340 const vk::VkMemoryRequirements& requirements, 341 vk::VkExternalMemoryHandleTypeFlagBits externalType, 342 deUint32 memoryTypeIndex, 343 NativeHandle& handle); 344 345 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface& vkd, 346 vk::VkDevice device, 347 deUint32 queueFamilyIndex, 348 vk::VkExternalMemoryHandleTypeFlagBits externalType, 349 vk::VkDeviceSize size, 350 vk::VkBufferCreateFlags createFlags, 351 vk::VkBufferUsageFlags usageFlags); 352 353 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface& vkd, 354 vk::VkDevice device, 355 deUint32 queueFamilyIndex, 356 vk::VkExternalMemoryHandleTypeFlagBits externalType, 357 vk::VkFormat format, 358 deUint32 width, 359 deUint32 height, 360 vk::VkImageTiling tiling, 361 vk::VkImageCreateFlags createFlags, 362 vk::VkImageUsageFlags usageFlags, 363 deUint32 mipLevels = 1u, 364 deUint32 arrayLayers = 1u); 365 366 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface& vki, 367 vk::VkPhysicalDevice physicalDevice); 368 369 } // ExternalMemoryUtil 370 371 } // vkt 372 373 #endif // CTS_USES_VULKANSC 374 375 #endif // _VKTEXTERNALMEMORYUTIL_HPP 376