387 {
388 auto memtype = (vk::ExternalMemoryHandleTypeFlagBits)exportInfos.
memoryType;
389
390#ifdef WIN32
391 if (memtype != vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32)
392#else
393 if (memtype != vk::ExternalMemoryHandleTypeFlagBits::eOpaqueFd)
394#endif
395 {
396 throw HvtResult::HVT_ERROR_UNSUPPORTED_MEMORY_TYPE;
397 }
398
399 auto isDepth = (bool)exportInfos.
depth;
400 auto& stream = readStreams.at(exportInfos.
streamIndex);
401 auto format = isDepth ? stream.depthFormat : stream.colorFormat;
402 auto& slots = isDepth ? stream.depthSlots : stream.colorSlots;
403
405 throw HvtResult::HVT_ERROR_WRONG_BUFFER_SIZE;
406 }
407
408 vk::ImageCreateInfo imgCreateInfo(
409 {},
410 vk::ImageType::e2D,
411 format,
412 vk::Extent3D(stream.resolution.x, stream.resolution.y, 1),
413 1,
414 1,
415 vk::SampleCountFlagBits::e1,
416 vk::ImageTiling::eOptimal,
417 vk::ImageUsageFlagBits::eTransferDst,
418 vk::SharingMode::eExclusive,
419 {},
420 vk::ImageLayout::eUndefined
421 );
422
423 for (int i = 0; i < numSlots; i++) {
424 auto memoryInfos = exportInfos.
pImages[i];
425
426 auto imgImportInfo = vk::ExternalMemoryImageCreateInfo(memtype);
427 auto createChain = vk::StructureChain(imgCreateInfo, imgImportInfo);
428
429 auto image = device->createImageUnique(createChain.get<vk::ImageCreateInfo>());
430 auto reqs = device->getImageMemoryRequirements(*image);
431
432 auto memIndex = findMemoryType(reqs.memoryTypeBits, vk::MemoryPropertyFlagBits::eDeviceLocal);
433
434 assert(reqs.size == memoryInfos.size);
435 assert(reqs.alignment == memoryInfos.alignment);
436
437 auto memoryAllocInfo = vk::StructureChain(
438 vk::MemoryAllocateInfo(reqs.size, memIndex),
439#ifdef WIN32
440 vk::ImportMemoryWin32HandleInfoKHR(memtype, memoryInfos.handle)
441#else
442 vk::ImportMemoryFdInfoKHR(memtype, memoryInfos.handle)
443#endif
444 );
445
446 auto memory = device->allocateMemoryUnique(memoryAllocInfo.get<vk::MemoryAllocateInfo>());
447
448 device->bindImageMemory(*image, *memory, 0);
449
450
451 oneTimeSubmit([&](vk::CommandBuffer& cmd) {
452 vk::ImageMemoryBarrier colorMemoryBarrier(
453 {},
454 vk::AccessFlagBits::eTransferWrite,
455 vk::ImageLayout::eUndefined,
456 vk::ImageLayout::eTransferDstOptimal,
457 VK_QUEUE_FAMILY_IGNORED,
458 VK_QUEUE_FAMILY_IGNORED,
459 *image,
460 vk::ImageSubresourceRange(
461 vk::ImageAspectFlagBits::ePlane0 | vk::ImageAspectFlagBits::ePlane1 | vk::ImageAspectFlagBits::ePlane2,
462 0, 1,
463 0, 1));
464
465 vk::ImageMemoryBarrier depthMemoryBarrier(
466 {},
467 vk::AccessFlagBits::eTransferWrite,
468 vk::ImageLayout::eUndefined,
469 vk::ImageLayout::eTransferDstOptimal,
470 VK_QUEUE_FAMILY_IGNORED,
471 VK_QUEUE_FAMILY_IGNORED,
472 *image,
473 vk::ImageSubresourceRange(
474 vk::ImageAspectFlagBits::eColor,
475 0, 1,
476 0, 1));
477
478 cmd.pipelineBarrier(
479 vk::PipelineStageFlagBits::eTransfer,
480 vk::PipelineStageFlagBits::eTransfer,
481 vk::DependencyFlagBits::eByRegion,
482 {},
483 {},
484 isDepth ? depthMemoryBarrier : colorMemoryBarrier);
485 });
486
487 slots.at(i) = ImageSlot{
488 .image = std::move(image),
489 .memory = std::move(memory)
490 };
491 }
492 (isDepth ? stream.importedDepth : stream.importedColor) = true;
493 }
HvtImageMemoryType memoryType
HvtStreamImageMemoryInfo * pImages