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 bool hasValidFd (void) const; 68 int getFd (void) const; 69 vk::pt::AndroidHardwareBufferPtr getAndroidHardwareBuffer (void) const; 70 vk::pt::zx_handle_t getZirconHandle (void) const; 71 void disown (void); 72 void reset (void); 73 74 private: 75 int m_fd; 76 vk::pt::zx_handle_t m_zirconHandle; 77 Win32HandleType m_win32HandleType; 78 vk::pt::Win32Handle m_win32Handle; 79 vk::pt::AndroidHardwareBufferPtr m_androidHardwareBuffer; 80 void* m_hostPtr; 81 82 // Disabled 83 NativeHandle& operator= (const NativeHandle&); 84 }; 85 86 class AndroidHardwareBufferExternalApi 87 { 88 public: 89 90 /** 91 * getInstance obtains the object, that provides an interface to AHB system APIs . 92 * If the AHB system API is not supported or if it is not built as supported with the CTS, 93 * then this function would return a null object. 94 */ 95 static AndroidHardwareBufferExternalApi* getInstance(); 96 97 /* Is AndroidHardwareBuffer supported? */ 98 static bool supportsAhb(); 99 100 /* Are Cube maps supported on current api level? */ 101 static bool supportsCubeMap(); 102 103 /** 104 * Allocates a buffer that backs an AHardwareBuffer using the passed parameter as follows: 105 * width; - width in pixels 106 * height; - height in pixels 107 * layers; - number of images 108 * format; - One of AHARDWAREBUFFER_FORMAT_* 109 * usage; - Combination of AHARDWAREBUFFER_USAGE_* 110 * 111 * Returns a valid AndroidHardwareBufferPtr object on success, or an null AndroidHardwareBufferPtr if 112 * the allocation fails for any reason. 113 */ 114 virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32 height, deUint32 layers, deUint32 format, deUint64 usage) = 0; 115 116 /** 117 * Acquire a reference on the given AHardwareBuffer object. This prevents the 118 * object from being deleted until the last reference is removed. 119 */ 120 virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer) = 0; 121 122 /** 123 * Remove a reference that was previously acquired with 124 * AHardwareBuffer_acquire(). 125 */ 126 virtual void release(vk::pt::AndroidHardwareBufferPtr buffer) = 0; 127 128 /** 129 * Return a description of the AHardwareBuffer in the passed in the following fields, if not NULL: 130 * width; - width in pixels 131 * height; - height in pixels 132 * layers; - number of images 133 * format; - One of AHARDWAREBUFFER_FORMAT_* 134 * usage; - Combination of AHARDWAREBUFFER_USAGE_* 135 * 136 */ 137 virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer, 138 deUint32* width, 139 deUint32* height, 140 deUint32* layers, 141 deUint32* format, 142 deUint64* usage, 143 deUint32* stride) = 0; 144 145 146 virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag) = 0; 147 virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag) = 0; 148 virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat) = 0; 149 virtual deUint64 mustSupportAhbUsageFlags() = 0; 150 virtual bool ahbFormatIsBlob(deUint32 format) = 0; 151 152 virtual ~AndroidHardwareBufferExternalApi(); 153 154 protected: 155 // Protected Constructor 156 AndroidHardwareBufferExternalApi(); 157 158 private: 159 // Stop the compiler generating methods of copy the object 160 AndroidHardwareBufferExternalApi(AndroidHardwareBufferExternalApi const& copy); // Not Implemented 161 AndroidHardwareBufferExternalApi& operator=(AndroidHardwareBufferExternalApi const& copy); // Not Implemented 162 163 static bool loadAhbDynamicApis(deInt32 sdkVersion); 164 }; 165 166 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type); 167 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type); 168 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type); 169 170 enum Permanence 171 { 172 PERMANENCE_PERMANENT = 0, 173 PERMANENCE_TEMPORARY 174 }; 175 176 enum Transference 177 { 178 TRANSFERENCE_COPY = 0, 179 TRANSFERENCE_REFERENCE 180 }; 181 182 struct ExternalHostMemory 183 { ExternalHostMemoryvkt::ExternalMemoryUtil::ExternalHostMemory184 ExternalHostMemory(vk::VkDeviceSize aSize, vk::VkDeviceSize aAlignment) 185 : size(deAlignSize(static_cast<size_t>(aSize), static_cast<size_t>(aAlignment))) 186 { 187 data = deAlignedMalloc(this->size, static_cast<size_t>(aAlignment)); 188 } 189 ~ExternalHostMemoryvkt::ExternalMemoryUtil::ExternalHostMemory190 ~ExternalHostMemory() 191 { 192 if (data != DE_NULL) 193 { 194 deAlignedFree(data); 195 } 196 } 197 198 size_t size; 199 void* data; 200 }; 201 202 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBits type, 203 Permanence permanence); 204 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBits type); 205 206 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBits type, 207 Permanence permanence); 208 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBits type); 209 210 int getMemoryFd (const vk::DeviceInterface& vkd, 211 vk::VkDevice device, 212 vk::VkDeviceMemory memory, 213 vk::VkExternalMemoryHandleTypeFlagBits externalType); 214 215 void getMemoryNative (const vk::DeviceInterface& vkd, 216 vk::VkDevice device, 217 vk::VkDeviceMemory memory, 218 vk::VkExternalMemoryHandleTypeFlagBits externalType, 219 NativeHandle& nativeHandle); 220 221 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface& vkd, 222 vk::VkDevice device, 223 vk::VkExternalSemaphoreHandleTypeFlagBits externalType); 224 225 vk::Move<vk::VkSemaphore> createExportableSemaphoreType (const vk::DeviceInterface& vkd, 226 vk::VkDevice device, 227 vk::VkSemaphoreType semaphoreType, 228 vk::VkExternalSemaphoreHandleTypeFlagBits externalType); 229 230 int getSemaphoreFd (const vk::DeviceInterface& vkd, 231 vk::VkDevice device, 232 vk::VkSemaphore semaphore, 233 vk::VkExternalSemaphoreHandleTypeFlagBits externalType); 234 235 void getSemaphoreNative (const vk::DeviceInterface& vkd, 236 vk::VkDevice device, 237 vk::VkSemaphore semaphore, 238 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 239 NativeHandle& nativeHandle); 240 241 void importSemaphore (const vk::DeviceInterface& vkd, 242 const vk::VkDevice device, 243 const vk::VkSemaphore semaphore, 244 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 245 NativeHandle& handle, 246 vk::VkSemaphoreImportFlags flags); 247 248 vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface& vkd, 249 const vk::VkDevice device, 250 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 251 NativeHandle& handle, 252 vk::VkSemaphoreImportFlags flags); 253 254 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface& vkd, 255 vk::VkDevice device, 256 vk::VkExternalFenceHandleTypeFlagBits externalType); 257 258 int getFenceFd (const vk::DeviceInterface& vkd, 259 vk::VkDevice device, 260 vk::VkFence fence, 261 vk::VkExternalFenceHandleTypeFlagBits externalType); 262 263 void getFenceNative (const vk::DeviceInterface& vkd, 264 vk::VkDevice device, 265 vk::VkFence fence, 266 vk::VkExternalFenceHandleTypeFlagBits externalType, 267 NativeHandle& nativeHandle, 268 bool expectFenceUnsignaled = true); 269 270 void importFence (const vk::DeviceInterface& vkd, 271 const vk::VkDevice device, 272 const vk::VkFence fence, 273 vk::VkExternalFenceHandleTypeFlagBits externalType, 274 NativeHandle& handle, 275 vk::VkFenceImportFlags flags); 276 277 vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface& vkd, 278 const vk::VkDevice device, 279 vk::VkExternalFenceHandleTypeFlagBits externalType, 280 NativeHandle& handle, 281 vk::VkFenceImportFlags flags); 282 283 deUint32 chooseMemoryType (deUint32 bits); 284 285 deUint32 chooseHostVisibleMemoryType (deUint32 bits, 286 const vk::VkPhysicalDeviceMemoryProperties properties); 287 288 vk::VkMemoryRequirements getImageMemoryRequirements (const vk::DeviceInterface& vkd, 289 vk::VkDevice device, 290 vk::VkImage image, 291 vk::VkExternalMemoryHandleTypeFlagBits externalType); 292 293 // If buffer is not null use dedicated allocation 294 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd, 295 vk::VkDevice device, 296 vk::VkDeviceSize allocationSize, 297 deUint32 memoryTypeIndex, 298 vk::VkExternalMemoryHandleTypeFlagBits externalType, 299 vk::VkBuffer buffer); 300 301 // If image is not null use dedicated allocation 302 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd, 303 vk::VkDevice device, 304 vk::VkDeviceSize allocationSize, 305 deUint32 memoryTypeIndex, 306 vk::VkExternalMemoryHandleTypeFlagBits externalType, 307 vk::VkImage image); 308 309 /* 310 // \note hostVisible argument is strict. Setting it to false will cause NotSupportedError to be thrown if non-host visible memory doesn't exist. 311 // If buffer is not null use dedicated allocation 312 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::InstanceInterface& vki, 313 vk::VkPhysicalDevice physicalDevice, 314 const vk::DeviceInterface& vkd, 315 vk::VkDevice device, 316 const vk::VkMemoryRequirements& requirements, 317 vk::VkExternalMemoryHandleTypeFlagBits externalType, 318 bool hostVisible, 319 vk::VkBuffer buffer, 320 deUint32& exportedMemoryTypeIndex); 321 */ 322 323 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd, 324 vk::VkDevice device, 325 const vk::VkMemoryRequirements& requirements, 326 vk::VkExternalMemoryHandleTypeFlagBits externalType, 327 deUint32 memoryTypeIndex, 328 NativeHandle& handle); 329 330 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd, 331 vk::VkDevice device, 332 vk::VkBuffer buffer, 333 const vk::VkMemoryRequirements& requirements, 334 vk::VkExternalMemoryHandleTypeFlagBits externalType, 335 deUint32 memoryTypeIndex, 336 NativeHandle& handle); 337 338 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd, 339 vk::VkDevice device, 340 vk::VkImage image, 341 const vk::VkMemoryRequirements& requirements, 342 vk::VkExternalMemoryHandleTypeFlagBits externalType, 343 deUint32 memoryTypeIndex, 344 NativeHandle& handle); 345 346 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface& vkd, 347 vk::VkDevice device, 348 deUint32 queueFamilyIndex, 349 vk::VkExternalMemoryHandleTypeFlagBits externalType, 350 vk::VkDeviceSize size, 351 vk::VkBufferCreateFlags createFlags, 352 vk::VkBufferUsageFlags usageFlags); 353 354 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface& vkd, 355 vk::VkDevice device, 356 deUint32 queueFamilyIndex, 357 vk::VkExternalMemoryHandleTypeFlagBits externalType, 358 vk::VkFormat format, 359 deUint32 width, 360 deUint32 height, 361 vk::VkImageTiling tiling, 362 vk::VkImageCreateFlags createFlags, 363 vk::VkImageUsageFlags usageFlags, 364 deUint32 mipLevels = 1u, 365 deUint32 arrayLayers = 1u); 366 367 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface& vki, 368 vk::VkPhysicalDevice physicalDevice); 369 370 } // ExternalMemoryUtil 371 372 } // vkt 373 374 #endif // CTS_USES_VULKANSC 375 376 #endif // _VKTEXTERNALMEMORYUTIL_HPP 377