Я пытаюсь экспортировать дескриптор выделения памяти, сделанный Vulkan, чтобы импортировать его в OpenGL. Но когда я добавляю vk::ExportMemoryAllocateInfo
в цепочку pNext
vk::MemoryAllocateInfo
, vk::Device::allocateMemory
выдает исключение OutOfDeviceMemory
.
Когда я не экспортирую дескриптор, распределение не происходит, но возвращенный дескриптор недействителен.
Вот код ошибки (пример на основе jherico: пример vulkan-opengl-interop-):
// 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
- Nvidia 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
и верните false с vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt
.