1 /*------------------------------------------------------------------------- 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 Google Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * \brief Vulkan external memory utilities 20 *//*--------------------------------------------------------------------*/ 21 22 #include "vktExternalMemoryUtil.hpp" 23 24 #include "vkQueryUtil.hpp" 25 26 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) 27 # include <unistd.h> 28 # include <fcntl.h> 29 # include <errno.h> 30 # include <sys/types.h> 31 # include <sys/socket.h> 32 #endif 33 34 #if (DE_OS == DE_OS_WIN32) 35 # define WIN32_LEAN_AND_MEAN 36 # include <windows.h> 37 #endif 38 39 #if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__) 40 # include <android/hardware_buffer.h> 41 # define USE_ANDROID_O_HARDWARE_BUFFER 1 42 #endif 43 44 namespace vkt 45 { 46 namespace ExternalMemoryUtil 47 { 48 namespace 49 { 50 deUint32 chooseMemoryType (deUint32 bits) 51 { 52 DE_ASSERT(bits != 0); 53 54 for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++) 55 { 56 if ((bits & (1u << memoryTypeIndex)) != 0) 57 return memoryTypeIndex; 58 } 59 60 DE_FATAL("No supported memory types"); 61 return -1; 62 } 63 64 } // anonymous 65 66 NativeHandle::NativeHandle (void) 67 : m_fd (-1) 68 , m_win32HandleType (WIN32HANDLETYPE_LAST) 69 , m_win32Handle (DE_NULL) 70 , m_androidHardwareBuffer (DE_NULL) 71 { 72 } 73 74 NativeHandle::NativeHandle (const NativeHandle& other) 75 : m_fd (-1) 76 , m_win32HandleType (WIN32HANDLETYPE_LAST) 77 , m_win32Handle (DE_NULL) 78 , m_androidHardwareBuffer (DE_NULL) 79 { 80 if (other.m_fd >= 0) 81 { 82 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) 83 DE_ASSERT(!other.m_win32Handle.internal); 84 DE_ASSERT(!other.m_androidHardwareBuffer.internal); 85 m_fd = dup(other.m_fd); 86 TCU_CHECK(m_fd >= 0); 87 #else 88 DE_FATAL("Platform doesn't support file descriptors"); 89 #endif 90 } 91 else if (other.m_win32Handle.internal) 92 { 93 #if (DE_OS == DE_OS_WIN32) 94 m_win32HandleType = other.m_win32HandleType; 95 96 switch (other.m_win32HandleType) 97 { 98 case WIN32HANDLETYPE_NT: 99 { 100 DE_ASSERT(other.m_fd == -1); 101 DE_ASSERT(!other.m_androidHardwareBuffer.internal); 102 103 const HANDLE process = ::GetCurrentProcess(); 104 ::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS); 105 106 break; 107 } 108 109 case WIN32HANDLETYPE_KMT: 110 { 111 m_win32Handle = other.m_win32Handle; 112 break; 113 } 114 115 default: 116 DE_FATAL("Unknown win32 handle type"); 117 } 118 #else 119 DE_FATAL("Platform doesn't support win32 handles"); 120 #endif 121 } 122 #if defined(USE_ANDROID_O_HARDWARE_BUFFER) 123 else if (other.m_androidHardwareBuffer.internal) 124 { 125 DE_ASSERT(other.m_fd == -1); 126 DE_ASSERT(!other.m_win32Handle.internal); 127 m_androidHardwareBuffer = other.m_androidHardwareBuffer; 128 AHardwareBuffer_acquire((AHardwareBuffer*)m_androidHardwareBuffer.internal); 129 } 130 #endif 131 else 132 DE_FATAL("Native handle can't be duplicated"); 133 } 134 135 NativeHandle::NativeHandle (int fd) 136 : m_fd (fd) 137 , m_win32HandleType (WIN32HANDLETYPE_LAST) 138 , m_win32Handle (DE_NULL) 139 , m_androidHardwareBuffer (DE_NULL) 140 { 141 } 142 143 NativeHandle::NativeHandle (Win32HandleType handleType, vk::pt::Win32Handle handle) 144 : m_fd (-1) 145 , m_win32HandleType (handleType) 146 , m_win32Handle (handle) 147 , m_androidHardwareBuffer (DE_NULL) 148 { 149 } 150 151 NativeHandle::NativeHandle (vk::pt::AndroidHardwareBufferPtr buffer) 152 : m_fd (-1) 153 , m_win32HandleType (WIN32HANDLETYPE_LAST) 154 , m_win32Handle (DE_NULL) 155 , m_androidHardwareBuffer (buffer) 156 { 157 } 158 159 NativeHandle::~NativeHandle (void) 160 { 161 reset(); 162 } 163 164 void NativeHandle::reset (void) 165 { 166 if (m_fd >= 0) 167 { 168 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) 169 DE_ASSERT(!m_win32Handle.internal); 170 DE_ASSERT(!m_androidHardwareBuffer.internal); 171 ::close(m_fd); 172 #else 173 DE_FATAL("Platform doesn't support file descriptors"); 174 #endif 175 } 176 177 if (m_win32Handle.internal) 178 { 179 #if (DE_OS == DE_OS_WIN32) 180 switch (m_win32HandleType) 181 { 182 case WIN32HANDLETYPE_NT: 183 DE_ASSERT(m_fd == -1); 184 DE_ASSERT(!m_androidHardwareBuffer.internal); 185 ::CloseHandle((HANDLE)m_win32Handle.internal); 186 break; 187 188 case WIN32HANDLETYPE_KMT: 189 break; 190 191 default: 192 DE_FATAL("Unknown win32 handle type"); 193 } 194 #else 195 DE_FATAL("Platform doesn't support win32 handles"); 196 #endif 197 } 198 199 #if defined(USE_ANDROID_O_HARDWARE_BUFFER) 200 if (m_androidHardwareBuffer.internal) 201 { 202 DE_ASSERT(m_fd == -1); 203 DE_ASSERT(!m_win32Handle.internal); 204 AHardwareBuffer_release((AHardwareBuffer*)m_androidHardwareBuffer.internal); 205 } 206 #endif 207 208 m_fd = -1; 209 m_win32Handle = vk::pt::Win32Handle(DE_NULL); 210 m_win32HandleType = WIN32HANDLETYPE_LAST; 211 m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL); 212 } 213 214 NativeHandle& NativeHandle::operator= (int fd) 215 { 216 reset(); 217 218 m_fd = fd; 219 220 return *this; 221 } 222 223 NativeHandle& NativeHandle::operator= (vk::pt::AndroidHardwareBufferPtr buffer) 224 { 225 reset(); 226 227 m_androidHardwareBuffer = buffer; 228 229 return *this; 230 } 231 232 void NativeHandle::setWin32Handle (Win32HandleType type, vk::pt::Win32Handle handle) 233 { 234 reset(); 235 236 m_win32HandleType = type; 237 m_win32Handle = handle; 238 } 239 240 void NativeHandle::disown (void) 241 { 242 m_fd = -1; 243 m_win32Handle = vk::pt::Win32Handle(DE_NULL); 244 m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL); 245 } 246 247 vk::pt::Win32Handle NativeHandle::getWin32Handle (void) const 248 { 249 DE_ASSERT(m_fd == -1); 250 DE_ASSERT(!m_androidHardwareBuffer.internal); 251 return m_win32Handle; 252 } 253 254 int NativeHandle::getFd (void) const 255 { 256 DE_ASSERT(!m_win32Handle.internal); 257 DE_ASSERT(!m_androidHardwareBuffer.internal); 258 return m_fd; 259 } 260 261 262 vk::pt::AndroidHardwareBufferPtr NativeHandle::getAndroidHardwareBuffer (void) const 263 { 264 DE_ASSERT(m_fd == -1); 265 DE_ASSERT(!m_win32Handle.internal); 266 return m_androidHardwareBuffer; 267 } 268 269 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type) 270 { 271 switch (type) 272 { 273 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT: 274 return "opaque_fd"; 275 276 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 277 return "opaque_win32"; 278 279 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 280 return "opaque_win32_kmt"; 281 282 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT: 283 return "d3d12_fenc"; 284 285 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: 286 return "sync_fd"; 287 288 default: 289 DE_FATAL("Unknown external semaphore type"); 290 return DE_NULL; 291 } 292 } 293 294 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type) 295 { 296 switch (type) 297 { 298 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT: 299 return "opaque_fd"; 300 301 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 302 return "opaque_win32"; 303 304 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 305 return "opaque_win32_kmt"; 306 307 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT: 308 return "sync_fd"; 309 310 default: 311 DE_FATAL("Unknown external fence type"); 312 return DE_NULL; 313 } 314 } 315 316 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type) 317 { 318 switch (type) 319 { 320 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 321 return "opaque_fd"; 322 323 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT: 324 return "opaque_win32"; 325 326 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 327 return "opaque_win32_kmt"; 328 329 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT: 330 return "d3d11_texture"; 331 332 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT: 333 return "d3d11_texture_kmt"; 334 335 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT: 336 return "d3d12_heap"; 337 338 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT: 339 return "d3d12_resource"; 340 341 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID: 342 return "android_hardware_buffer"; 343 344 default: 345 DE_FATAL("Unknown external memory type"); 346 return DE_NULL; 347 } 348 } 349 350 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBits type, 351 Permanence permanence) 352 { 353 switch (type) 354 { 355 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 356 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 357 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY; 358 359 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT: 360 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY; 361 362 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: 363 return permanence == PERMANENCE_TEMPORARY; 364 365 default: 366 DE_FATAL("Unknown external semaphore type"); 367 return false; 368 } 369 } 370 371 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBits type) 372 { 373 switch (type) 374 { 375 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 376 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 377 return TRANSFERENCE_REFERENCE; 378 379 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT: 380 return TRANSFERENCE_REFERENCE; 381 382 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: 383 return TRANSFERENCE_COPY; 384 385 default: 386 DE_FATAL("Unknown external semaphore type"); 387 return TRANSFERENCE_REFERENCE; 388 } 389 } 390 391 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBits type, 392 Permanence permanence) 393 { 394 switch (type) 395 { 396 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 397 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 398 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY; 399 400 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT: 401 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY; 402 403 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT: 404 return permanence == PERMANENCE_TEMPORARY; 405 406 default: 407 DE_FATAL("Unknown external fence type"); 408 return false; 409 } 410 } 411 412 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBits type) 413 { 414 switch (type) 415 { 416 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 417 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 418 return TRANSFERENCE_REFERENCE; 419 420 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT: 421 return TRANSFERENCE_REFERENCE; 422 423 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT: 424 return TRANSFERENCE_COPY; 425 426 default: 427 DE_FATAL("Unknown external fence type"); 428 return TRANSFERENCE_REFERENCE; 429 } 430 } 431 432 int getMemoryFd (const vk::DeviceInterface& vkd, 433 vk::VkDevice device, 434 vk::VkDeviceMemory memory, 435 vk::VkExternalMemoryHandleTypeFlagBits externalType) 436 { 437 const vk::VkMemoryGetFdInfoKHR info = 438 { 439 vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, 440 DE_NULL, 441 442 memory, 443 externalType 444 }; 445 int fd = -1; 446 447 VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd)); 448 TCU_CHECK(fd >= 0); 449 450 return fd; 451 } 452 453 void getMemoryNative (const vk::DeviceInterface& vkd, 454 vk::VkDevice device, 455 vk::VkDeviceMemory memory, 456 vk::VkExternalMemoryHandleTypeFlagBits externalType, 457 NativeHandle& nativeHandle) 458 { 459 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) 460 { 461 const vk::VkMemoryGetFdInfoKHR info = 462 { 463 vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, 464 DE_NULL, 465 466 memory, 467 externalType 468 }; 469 int fd = -1; 470 471 VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd)); 472 TCU_CHECK(fd >= 0); 473 nativeHandle = fd; 474 } 475 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT 476 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) 477 { 478 const vk::VkMemoryGetWin32HandleInfoKHR info = 479 { 480 vk::VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, 481 DE_NULL, 482 483 memory, 484 externalType 485 }; 486 vk::pt::Win32Handle handle (DE_NULL); 487 488 VK_CHECK(vkd.getMemoryWin32HandleKHR(device, &info, &handle)); 489 490 switch (externalType) 491 { 492 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT: 493 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle); 494 break; 495 496 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 497 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle); 498 break; 499 500 default: 501 DE_FATAL("Unknown external memory handle type"); 502 } 503 } 504 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) 505 { 506 const vk::VkMemoryGetAndroidHardwareBufferInfoANDROID info = 507 { 508 vk::VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID, 509 DE_NULL, 510 511 memory, 512 }; 513 vk::pt::AndroidHardwareBufferPtr ahb (DE_NULL); 514 515 VK_CHECK(vkd.getMemoryAndroidHardwareBufferANDROID(device, &info, &ahb)); 516 TCU_CHECK(ahb.internal); 517 nativeHandle = ahb; 518 } 519 else 520 DE_FATAL("Unknown external memory handle type"); 521 } 522 523 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface& vkd, 524 vk::VkDevice device, 525 vk::VkExternalFenceHandleTypeFlagBits externalType) 526 { 527 const vk::VkExportFenceCreateInfo exportCreateInfo = 528 { 529 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, 530 DE_NULL, 531 (vk::VkExternalFenceHandleTypeFlags)externalType 532 }; 533 const vk::VkFenceCreateInfo createInfo = 534 { 535 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 536 &exportCreateInfo, 537 0u 538 }; 539 540 return vk::createFence(vkd, device, &createInfo); 541 } 542 543 int getFenceFd (const vk::DeviceInterface& vkd, 544 vk::VkDevice device, 545 vk::VkFence fence, 546 vk::VkExternalFenceHandleTypeFlagBits externalType) 547 { 548 const vk::VkFenceGetFdInfoKHR info = 549 { 550 vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, 551 DE_NULL, 552 553 fence, 554 externalType 555 }; 556 int fd = -1; 557 558 VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd)); 559 TCU_CHECK(fd >= 0); 560 561 return fd; 562 } 563 564 void getFenceNative (const vk::DeviceInterface& vkd, 565 vk::VkDevice device, 566 vk::VkFence fence, 567 vk::VkExternalFenceHandleTypeFlagBits externalType, 568 NativeHandle& nativeHandle) 569 { 570 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT 571 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT) 572 { 573 const vk::VkFenceGetFdInfoKHR info = 574 { 575 vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, 576 DE_NULL, 577 578 fence, 579 externalType 580 }; 581 int fd = -1; 582 583 VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd)); 584 TCU_CHECK(fd >= 0); 585 nativeHandle = fd; 586 } 587 else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT 588 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) 589 { 590 const vk::VkFenceGetWin32HandleInfoKHR info = 591 { 592 vk::VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, 593 DE_NULL, 594 595 fence, 596 externalType 597 }; 598 vk::pt::Win32Handle handle (DE_NULL); 599 600 VK_CHECK(vkd.getFenceWin32HandleKHR(device, &info, &handle)); 601 602 switch (externalType) 603 { 604 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 605 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle); 606 break; 607 608 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 609 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle); 610 break; 611 612 default: 613 DE_FATAL("Unknow external memory handle type"); 614 } 615 } 616 else 617 DE_FATAL("Unknow external fence handle type"); 618 } 619 620 void importFence (const vk::DeviceInterface& vkd, 621 const vk::VkDevice device, 622 const vk::VkFence fence, 623 vk::VkExternalFenceHandleTypeFlagBits externalType, 624 NativeHandle& handle, 625 vk::VkFenceImportFlags flags) 626 { 627 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT 628 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT) 629 { 630 const vk::VkImportFenceFdInfoKHR importInfo = 631 { 632 vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, 633 DE_NULL, 634 fence, 635 flags, 636 externalType, 637 handle.getFd() 638 }; 639 640 VK_CHECK(vkd.importFenceFdKHR(device, &importInfo)); 641 handle.disown(); 642 } 643 else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT 644 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) 645 { 646 const vk::VkImportFenceWin32HandleInfoKHR importInfo = 647 { 648 vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, 649 DE_NULL, 650 fence, 651 flags, 652 externalType, 653 handle.getWin32Handle(), 654 DE_NULL 655 }; 656 657 VK_CHECK(vkd.importFenceWin32HandleKHR(device, &importInfo)); 658 // \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way 659 handle.reset(); 660 } 661 else 662 DE_FATAL("Unknown fence external handle type"); 663 } 664 665 vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface& vkd, 666 const vk::VkDevice device, 667 vk::VkExternalFenceHandleTypeFlagBits externalType, 668 NativeHandle& handle, 669 vk::VkFenceImportFlags flags) 670 { 671 vk::Move<vk::VkFence> fence (createFence(vkd, device)); 672 673 importFence(vkd, device, *fence, externalType, handle, flags); 674 675 return fence; 676 } 677 678 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface& vkd, 679 vk::VkDevice device, 680 vk::VkExternalSemaphoreHandleTypeFlagBits externalType) 681 { 682 const vk::VkExportSemaphoreCreateInfo exportCreateInfo = 683 { 684 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, 685 DE_NULL, 686 (vk::VkExternalSemaphoreHandleTypeFlags)externalType 687 }; 688 const vk::VkSemaphoreCreateInfo createInfo = 689 { 690 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, 691 &exportCreateInfo, 692 0u 693 }; 694 695 return vk::createSemaphore(vkd, device, &createInfo); 696 } 697 698 int getSemaphoreFd (const vk::DeviceInterface& vkd, 699 vk::VkDevice device, 700 vk::VkSemaphore semaphore, 701 vk::VkExternalSemaphoreHandleTypeFlagBits externalType) 702 { 703 const vk::VkSemaphoreGetFdInfoKHR info = 704 { 705 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, 706 DE_NULL, 707 708 semaphore, 709 externalType 710 }; 711 int fd = -1; 712 713 VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd)); 714 TCU_CHECK(fd >= 0); 715 716 return fd; 717 } 718 719 void getSemaphoreNative (const vk::DeviceInterface& vkd, 720 vk::VkDevice device, 721 vk::VkSemaphore semaphore, 722 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 723 NativeHandle& nativeHandle) 724 { 725 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT 726 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) 727 { 728 const vk::VkSemaphoreGetFdInfoKHR info = 729 { 730 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, 731 DE_NULL, 732 733 semaphore, 734 externalType 735 }; 736 int fd = -1; 737 738 VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd)); 739 TCU_CHECK(fd >= 0); 740 nativeHandle = fd; 741 } 742 else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT 743 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) 744 { 745 const vk::VkSemaphoreGetWin32HandleInfoKHR info = 746 { 747 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, 748 DE_NULL, 749 750 semaphore, 751 externalType 752 }; 753 vk::pt::Win32Handle handle (DE_NULL); 754 755 VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle)); 756 757 switch (externalType) 758 { 759 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT: 760 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle); 761 break; 762 763 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: 764 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle); 765 break; 766 767 default: 768 DE_FATAL("Unknow external memory handle type"); 769 } 770 } 771 else 772 DE_FATAL("Unknow external semaphore handle type"); 773 } 774 775 void importSemaphore (const vk::DeviceInterface& vkd, 776 const vk::VkDevice device, 777 const vk::VkSemaphore semaphore, 778 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 779 NativeHandle& handle, 780 vk::VkSemaphoreImportFlags flags) 781 { 782 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT 783 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) 784 { 785 const vk::VkImportSemaphoreFdInfoKHR importInfo = 786 { 787 vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, 788 DE_NULL, 789 semaphore, 790 flags, 791 externalType, 792 handle.getFd() 793 }; 794 795 VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo)); 796 handle.disown(); 797 } 798 else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT 799 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) 800 { 801 const vk::VkImportSemaphoreWin32HandleInfoKHR importInfo = 802 { 803 vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, 804 DE_NULL, 805 semaphore, 806 flags, 807 externalType, 808 handle.getWin32Handle(), 809 DE_NULL 810 }; 811 812 VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo)); 813 // \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way 814 handle.reset(); 815 } 816 else 817 DE_FATAL("Unknown semaphore external handle type"); 818 } 819 820 vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface& vkd, 821 const vk::VkDevice device, 822 vk::VkExternalSemaphoreHandleTypeFlagBits externalType, 823 NativeHandle& handle, 824 vk::VkSemaphoreImportFlags flags) 825 { 826 vk::Move<vk::VkSemaphore> semaphore (createSemaphore(vkd, device)); 827 828 importSemaphore(vkd, device, *semaphore, externalType, handle, flags); 829 830 return semaphore; 831 } 832 833 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd, 834 vk::VkDevice device, 835 const vk::VkMemoryRequirements& requirements, 836 vk::VkExternalMemoryHandleTypeFlagBits externalType, 837 vk::VkBuffer buffer, 838 deUint32& exportedMemoryTypeIndex) 839 { 840 exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits); 841 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo = 842 { 843 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 844 DE_NULL, 845 846 (vk::VkImage)0, 847 buffer 848 }; 849 const vk::VkExportMemoryAllocateInfo exportInfo = 850 { 851 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, 852 !!buffer ? &dedicatedInfo : DE_NULL, 853 (vk::VkExternalMemoryHandleTypeFlags)externalType 854 }; 855 const vk::VkMemoryAllocateInfo info = 856 { 857 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 858 &exportInfo, 859 requirements.size, 860 exportedMemoryTypeIndex 861 }; 862 return vk::allocateMemory(vkd, device, &info); 863 } 864 865 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd, 866 vk::VkDevice device, 867 const vk::VkMemoryRequirements& requirements, 868 vk::VkExternalMemoryHandleTypeFlagBits externalType, 869 vk::VkImage image, 870 deUint32& exportedMemoryTypeIndex) 871 { 872 exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits); 873 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo = 874 { 875 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 876 DE_NULL, 877 878 image, 879 (vk::VkBuffer)0 880 }; 881 const vk::VkExportMemoryAllocateInfo exportInfo = 882 { 883 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, 884 !!image ? &dedicatedInfo : DE_NULL, 885 (vk::VkExternalMemoryHandleTypeFlags)externalType 886 }; 887 const vk::VkMemoryAllocateInfo info = 888 { 889 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 890 &exportInfo, 891 requirements.size, 892 exportedMemoryTypeIndex 893 }; 894 return vk::allocateMemory(vkd, device, &info); 895 } 896 897 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::InstanceInterface& vki, 898 vk::VkPhysicalDevice physicalDevice, 899 const vk::DeviceInterface& vkd, 900 vk::VkDevice device, 901 const vk::VkMemoryRequirements& requirements, 902 vk::VkExternalMemoryHandleTypeFlagBits externalType, 903 bool hostVisible, 904 vk::VkBuffer buffer, 905 deUint32& exportedMemoryTypeIndex) 906 { 907 const vk::VkPhysicalDeviceMemoryProperties properties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice); 908 909 for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= requirements.memoryTypeBits; memoryTypeIndex++) 910 { 911 if (((requirements.memoryTypeBits & (1u << memoryTypeIndex)) != 0) 912 && (((properties.memoryTypes[memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) == hostVisible)) 913 { 914 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo = 915 { 916 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 917 DE_NULL, 918 919 (vk::VkImage)0, 920 buffer 921 }; 922 const vk::VkExportMemoryAllocateInfo exportInfo = 923 { 924 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, 925 !!buffer ? &dedicatedInfo : DE_NULL, 926 (vk::VkExternalMemoryHandleTypeFlags)externalType 927 }; 928 const vk::VkMemoryAllocateInfo info = 929 { 930 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 931 &exportInfo, 932 requirements.size, 933 memoryTypeIndex 934 }; 935 936 exportedMemoryTypeIndex = memoryTypeIndex; 937 return vk::allocateMemory(vkd, device, &info); 938 } 939 } 940 941 TCU_THROW(NotSupportedError, "No supported memory type found"); 942 } 943 944 static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd, 945 vk::VkDevice device, 946 vk::VkBuffer buffer, 947 vk::VkImage image, 948 const vk::VkMemoryRequirements& requirements, 949 vk::VkExternalMemoryHandleTypeFlagBits externalType, 950 deUint32 memoryTypeIndex, 951 NativeHandle& handle) 952 { 953 const bool isDedicated = !!buffer || !!image; 954 955 DE_ASSERT(!buffer || !image); 956 957 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) 958 { 959 const vk::VkImportMemoryFdInfoKHR importInfo = 960 { 961 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, 962 DE_NULL, 963 externalType, 964 handle.getFd() 965 }; 966 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo = 967 { 968 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 969 &importInfo, 970 image, 971 buffer, 972 }; 973 const vk::VkMemoryAllocateInfo info = 974 { 975 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 976 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo), 977 requirements.size, 978 (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex 979 }; 980 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info)); 981 982 handle.disown(); 983 984 return memory; 985 } 986 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT 987 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) 988 { 989 const vk::VkImportMemoryWin32HandleInfoKHR importInfo = 990 { 991 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, 992 DE_NULL, 993 externalType, 994 handle.getWin32Handle(), 995 DE_NULL 996 }; 997 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo = 998 { 999 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 1000 &importInfo, 1001 image, 1002 buffer, 1003 }; 1004 const vk::VkMemoryAllocateInfo info = 1005 { 1006 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 1007 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo), 1008 requirements.size, 1009 (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex 1010 }; 1011 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info)); 1012 1013 handle.disown(); 1014 1015 return memory; 1016 } 1017 #if defined(USE_ANDROID_O_HARDWARE_BUFFER) 1018 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) 1019 { 1020 AHardwareBuffer_Desc desc; 1021 AHardwareBuffer_describe(static_cast<const AHardwareBuffer*>(handle.getAndroidHardwareBuffer().internal), &desc); 1022 1023 DE_ASSERT(desc.format == AHARDWAREBUFFER_FORMAT_BLOB || image != 0); 1024 1025 vk::VkImportAndroidHardwareBufferInfoANDROID importInfo = 1026 { 1027 vk::VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID, 1028 DE_NULL, 1029 handle.getAndroidHardwareBuffer() 1030 }; 1031 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo = 1032 { 1033 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, 1034 &importInfo, 1035 image, 1036 buffer, 1037 }; 1038 const vk::VkMemoryAllocateInfo info = 1039 { 1040 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 1041 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo), 1042 requirements.size, 1043 (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex 1044 }; 1045 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info)); 1046 1047 return memory; 1048 } 1049 #endif // (USE_ANDROID_O_HARDWARE_BUFFER) 1050 else 1051 { 1052 DE_FATAL("Unknown external memory type"); 1053 return vk::Move<vk::VkDeviceMemory>(); 1054 } 1055 } 1056 1057 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd, 1058 vk::VkDevice device, 1059 const vk::VkMemoryRequirements& requirements, 1060 vk::VkExternalMemoryHandleTypeFlagBits externalType, 1061 deUint32 memoryTypeIndex, 1062 NativeHandle& handle) 1063 { 1064 return importMemory(vkd, device, (vk::VkBuffer)0, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle); 1065 } 1066 1067 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd, 1068 vk::VkDevice device, 1069 vk::VkBuffer buffer, 1070 const vk::VkMemoryRequirements& requirements, 1071 vk::VkExternalMemoryHandleTypeFlagBits externalType, 1072 deUint32 memoryTypeIndex, 1073 NativeHandle& handle) 1074 { 1075 return importMemory(vkd, device, buffer, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle); 1076 } 1077 1078 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd, 1079 vk::VkDevice device, 1080 vk::VkImage image, 1081 const vk::VkMemoryRequirements& requirements, 1082 vk::VkExternalMemoryHandleTypeFlagBits externalType, 1083 deUint32 memoryTypeIndex, 1084 NativeHandle& handle) 1085 { 1086 return importMemory(vkd, device, (vk::VkBuffer)0, image, requirements, externalType, memoryTypeIndex, handle); 1087 } 1088 1089 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface& vkd, 1090 vk::VkDevice device, 1091 deUint32 queueFamilyIndex, 1092 vk::VkExternalMemoryHandleTypeFlagBits externalType, 1093 vk::VkDeviceSize size, 1094 vk::VkBufferCreateFlags createFlags, 1095 vk::VkBufferUsageFlags usageFlags) 1096 { 1097 const vk::VkExternalMemoryBufferCreateInfo externalCreateInfo = 1098 { 1099 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, 1100 DE_NULL, 1101 (vk::VkExternalMemoryHandleTypeFlags)externalType 1102 }; 1103 const vk::VkBufferCreateInfo createInfo = 1104 { 1105 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 1106 &externalCreateInfo, 1107 createFlags, 1108 size, 1109 usageFlags, 1110 vk::VK_SHARING_MODE_EXCLUSIVE, 1111 1u, 1112 &queueFamilyIndex 1113 }; 1114 1115 return vk::createBuffer(vkd, device, &createInfo); 1116 } 1117 1118 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface& vkd, 1119 vk::VkDevice device, 1120 deUint32 queueFamilyIndex, 1121 vk::VkExternalMemoryHandleTypeFlagBits externalType, 1122 vk::VkFormat format, 1123 deUint32 width, 1124 deUint32 height, 1125 vk::VkImageTiling tiling, 1126 vk::VkImageCreateFlags createFlags, 1127 vk::VkImageUsageFlags usageFlags, 1128 deUint32 mipLevels, 1129 deUint32 arrayLayers) 1130 { 1131 const vk::VkExternalMemoryImageCreateInfo externalCreateInfo = 1132 { 1133 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, 1134 DE_NULL, 1135 (vk::VkExternalMemoryHandleTypeFlags)externalType 1136 }; 1137 const vk::VkImageCreateInfo createInfo = 1138 { 1139 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 1140 &externalCreateInfo, 1141 createFlags, 1142 vk::VK_IMAGE_TYPE_2D, 1143 format, 1144 { width, height, 1u, }, 1145 mipLevels, 1146 arrayLayers, 1147 vk::VK_SAMPLE_COUNT_1_BIT, 1148 tiling, 1149 usageFlags, 1150 vk::VK_SHARING_MODE_EXCLUSIVE, 1151 1, 1152 &queueFamilyIndex, 1153 vk::VK_IMAGE_LAYOUT_UNDEFINED 1154 }; 1155 1156 return vk::createImage(vkd, device, &createInfo); 1157 } 1158 1159 } // ExternalMemoryUtil 1160 } // vkt 1161