导出 vulkan 内存分配句柄导致设备内存不足
Exporting vulkan memory allocation handle cause an out of device memory
我正在尝试导出 Vulkan 进行的内存分配句柄,以将其导入 OpenGL。但是当我在 vk::MemoryAllocateInfo
的 pNext
链中添加 vk::ExportMemoryAllocateInfo
时,vk::Device::allocateMemory
会抛出 OutOfDeviceMemory
异常。
当我不导出句柄时,分配不会失败但 returned 句柄无效。
这里是错误代码(基于 jherico 的例子:vulkan-opengl-interop-example):
// The physical device and the device are correct
// requirements are for a RGBA image of 1024x1024 pixels
// memory properties is just vk::MemoryPropertyFlagBits::eDeviceLocal
void IMemoryObject::Allocate(vk::PhysicalDevice physicalDevice, vk::Device device, const vk::MemoryRequirements& requirements, vk::MemoryPropertyFlags properties)
{
unsigned int memoryTypeIndex = 0;
bool memoryIndexTypeFound = false;
vk::PhysicalDeviceMemoryProperties memoryProperties = physicalDevice.getMemoryProperties();
for (unsigned int i = 0; i < memoryProperties.memoryTypeCount && !memoryIndexTypeFound; i++)
{
vk::MemoryType memoryType = memoryProperties.memoryTypes[i];
if (requirements.memoryTypeBits & 1 << i && (memoryType.propertyFlags & properties) == properties)
{
memoryTypeIndex = i;
memoryIndexTypeFound = true;
}
}
if (!memoryIndexTypeFound)
throw std::exception();
vk::ExportMemoryAllocateInfo exportAllocInfo;
exportAllocInfo.setHandleTypes(vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32);
vk::MemoryAllocateInfo allocateInfo;
allocateInfo.setPNext(&exportAllocInfo); // Remove this line and the allocation won't fail
allocateInfo.setAllocationSize(requirements.size);
allocateInfo.setMemoryTypeIndex(memoryTypeIndex);
deviceMemory_ = device.allocateMemoryUnique(allocateInfo);
// Call VkBindBufferMemory or VkBindImageMemory, never reached anyway when allocateInfo.pNext == &exportAllocInfo;
BindMemory(*deviceMemory_, 0);
}
我的系统是:
- Windows 7
- 英伟达 Quadro RTX 4000
- 驱动程序版本 431.02 或 431.94
验证层存在于我的实例中但保持沉默,扩展 VK_KHR_external_memory
和 VK_KHR_external_memory_win32
在我的设备中可用,分配大小遵守 API 限制并且 memoryIndexType 是正确。
我是做错了什么还是我错过了限制?
谢谢!
编辑:
我尝试将句柄导出为 vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt
并且分配有效。下面的代码是我如何测试分配是否需要专用分配来导出句柄类型。
bool RequireDedicatedAllocation(vk::PhysicalDevice physicalDevice, const vk::ImageCreateInfo& createInfo, vk::ExternalMemoryHandleTypeFlagBits handleType)
{
vk::PhysicalDeviceExternalImageFormatInfo externalImageFormatInfo;
externalImageFormatInfo.setHandleType(handleType);
vk::PhysicalDeviceImageFormatInfo2 imageFormatInfo;
imageFormatInfo.setUsage(createInfo.usage)
.setFormat(createInfo.format)
.setTiling(createInfo.tiling)
.setType(createInfo.imageType)
.setPNext(&externalImageFormatInfo);
vk::StructureChain<vk::ImageFormatProperties2, vk::ExternalImageFormatProperties> imageFormatPropertiesChain = physicalDevice.getImageFormatProperties2<vk::ImageFormatProperties2, vk::ExternalImageFormatProperties>(imageFormatInfo);
vk::ExternalImageFormatProperties externalImageProperties = imageFormatPropertiesChain.get<vk::ExternalImageFormatProperties>();
return static_cast<bool>(externalImageProperties.externalMemoryProperties.externalMemoryFeatures & vk::ExternalMemoryFeatureFlagBits::eDedicatedOnly);
}
在我的系统上,它抛出一个 ErrorFormatNotSupported
错误(在 vk::PhysicalDevice::getImageFormatProperties2
上)vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32
和 return false vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt
。
我终于得到了 vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt。我不需要通过 Windows' API 与它交互,只需 OpenGL。
我正在尝试导出 Vulkan 进行的内存分配句柄,以将其导入 OpenGL。但是当我在 vk::MemoryAllocateInfo
的 pNext
链中添加 vk::ExportMemoryAllocateInfo
时,vk::Device::allocateMemory
会抛出 OutOfDeviceMemory
异常。
当我不导出句柄时,分配不会失败但 returned 句柄无效。
这里是错误代码(基于 jherico 的例子:vulkan-opengl-interop-example):
// The physical device and the device are correct
// requirements are for a RGBA image of 1024x1024 pixels
// memory properties is just vk::MemoryPropertyFlagBits::eDeviceLocal
void IMemoryObject::Allocate(vk::PhysicalDevice physicalDevice, vk::Device device, const vk::MemoryRequirements& requirements, vk::MemoryPropertyFlags properties)
{
unsigned int memoryTypeIndex = 0;
bool memoryIndexTypeFound = false;
vk::PhysicalDeviceMemoryProperties memoryProperties = physicalDevice.getMemoryProperties();
for (unsigned int i = 0; i < memoryProperties.memoryTypeCount && !memoryIndexTypeFound; i++)
{
vk::MemoryType memoryType = memoryProperties.memoryTypes[i];
if (requirements.memoryTypeBits & 1 << i && (memoryType.propertyFlags & properties) == properties)
{
memoryTypeIndex = i;
memoryIndexTypeFound = true;
}
}
if (!memoryIndexTypeFound)
throw std::exception();
vk::ExportMemoryAllocateInfo exportAllocInfo;
exportAllocInfo.setHandleTypes(vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32);
vk::MemoryAllocateInfo allocateInfo;
allocateInfo.setPNext(&exportAllocInfo); // Remove this line and the allocation won't fail
allocateInfo.setAllocationSize(requirements.size);
allocateInfo.setMemoryTypeIndex(memoryTypeIndex);
deviceMemory_ = device.allocateMemoryUnique(allocateInfo);
// Call VkBindBufferMemory or VkBindImageMemory, never reached anyway when allocateInfo.pNext == &exportAllocInfo;
BindMemory(*deviceMemory_, 0);
}
我的系统是:
- Windows 7
- 英伟达 Quadro RTX 4000
- 驱动程序版本 431.02 或 431.94
验证层存在于我的实例中但保持沉默,扩展 VK_KHR_external_memory
和 VK_KHR_external_memory_win32
在我的设备中可用,分配大小遵守 API 限制并且 memoryIndexType 是正确。
我是做错了什么还是我错过了限制?
谢谢!
编辑:
我尝试将句柄导出为 vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt
并且分配有效。下面的代码是我如何测试分配是否需要专用分配来导出句柄类型。
bool RequireDedicatedAllocation(vk::PhysicalDevice physicalDevice, const vk::ImageCreateInfo& createInfo, vk::ExternalMemoryHandleTypeFlagBits handleType)
{
vk::PhysicalDeviceExternalImageFormatInfo externalImageFormatInfo;
externalImageFormatInfo.setHandleType(handleType);
vk::PhysicalDeviceImageFormatInfo2 imageFormatInfo;
imageFormatInfo.setUsage(createInfo.usage)
.setFormat(createInfo.format)
.setTiling(createInfo.tiling)
.setType(createInfo.imageType)
.setPNext(&externalImageFormatInfo);
vk::StructureChain<vk::ImageFormatProperties2, vk::ExternalImageFormatProperties> imageFormatPropertiesChain = physicalDevice.getImageFormatProperties2<vk::ImageFormatProperties2, vk::ExternalImageFormatProperties>(imageFormatInfo);
vk::ExternalImageFormatProperties externalImageProperties = imageFormatPropertiesChain.get<vk::ExternalImageFormatProperties>();
return static_cast<bool>(externalImageProperties.externalMemoryProperties.externalMemoryFeatures & vk::ExternalMemoryFeatureFlagBits::eDedicatedOnly);
}
在我的系统上,它抛出一个 ErrorFormatNotSupported
错误(在 vk::PhysicalDevice::getImageFormatProperties2
上)vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32
和 return false vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt
。
我终于得到了 vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt。我不需要通过 Windows' API 与它交互,只需 OpenGL。