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