微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何正确加载Vulkan扩展程序?

如何解决如何正确加载Vulkan扩展程序?

我不了解Vulkan扩展系统的行为以及加载/不加载其中的某些功能,可以请有人向我解释为什么,当我拥有这些必需的扩展时:

    settings.requiredInstanceExtensions.insert(
    settings.requiredInstanceExtensions.end(),{
      VK_KHR_SURFACE_EXTENSION_NAME,VK_KHR_disPLAY_EXTENSION_NAME,VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME
    }
  );   
       
  settings.requiredDeviceExtensions.insert(
    settings.requiredDeviceExtensions.end(),{
      VK_KHR_SWAPCHAIN_EXTENSION_NAME,VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME
    }
  );

我只是在实例创建过程中检查扩展的存在:

  VkInstanceCreateInfo createInfo = {};
  createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  createInfo.pApplicationInfo = &appInfo;
  createInfo.enabledLayerCount = static_cast<uint32_t>(_validation.getValidationLayersCount());
  createInfo.ppEnabledLayerNames = _validation.getValidationLayersNames();
  _settings.requiredInstanceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);

  /// Check for available extensions.
  uint32_t extensionCount = 0;
  vkEnumerateInstanceExtensionProperties(nullptr,&extensionCount,nullptr);
  std::vector<VkExtensionProperties> availableExtensions(extensionCount);
  vkEnumerateInstanceExtensionProperties(nullptr,availableExtensions.data());

  cerrlog.debug() << "Available extensions: " << std::endl;
  for(const auto& extension : availableExtensions) {
      cerrlog.debug() << extension.extensionName << std::endl;
  }

  createInfo.enabledExtensionCount = static_cast<uint32_t>(_settings.requiredInstanceExtensions.size());
  createInfo.ppEnabledExtensionNames = _settings.requiredInstanceExtensions.data();

  VkResult result = vkCreateInstance(&createInfo,nullptr,&_instance);
  VulkanException::throwIfNotOK("Failed to create vk instance!",result);

以类似的方式,我检查扩展支持中的设备扩展,然后创建它:

  VkDeviceCreateInfo createInfo = {};
  createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  createInfo.queueCreateInfoCount = static_cast<int>(queueCreateInfos.size());
  createInfo.pQueueCreateInfos = queueCreateInfos.data();
  createInfo.pEnabledFeatures = &deviceFeatures;
  createInfo.enabledExtensionCount = static_cast<uint32_t>(_deviceExtensions.size());
  createInfo.ppEnabledExtensionNames = _deviceExtensions.data();

  if (validationEnabled) {
    createInfo.enabledLayerCount = static_cast<uint32_t>(
      validationLayers.getValidationLayersCount());
    createInfo.ppEnabledLayerNames = validationLayers.getValidationLayersNames();
  } else {
    createInfo.enabledLayerCount = 0;
  }

  VkResult result = vkCreateDevice(_physicalDevice,&createInfo,&_device);

这将导致实例的创建,并且还将通过该实例映射vulkan核心调用(即使是从实例映射的设备也是如此)。但是我仍然需要加载调试工具:

VkResult VulkanDebugLogger::CreateDebugUtilsMessengerEXT(
  VkInstance instance,const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,const VkAllocationCallbacks* pAllocator,VkDebugUtilsMessengerEXT* pCallback
)
{
  auto func = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(
    vkGetInstanceProcAddr(instance,"vkCreateDebugUtilsMessengerEXT")
  );

  if (func != nullptr) {
    return func(instance,pCreateInfo,pAllocator,pCallback);
  }
  else {
    return VK_ERROR_EXTENSION_NOT_PRESENT;
  }
}

我还需要加载这些扩展名:

void VulkanRenderer::loadExtensions()
{
  vkGetMemoryWin32HandleKHR = PFN_vkGetMemoryWin32HandleKHR(vkGetInstanceProcAddr(
    _instance,"vkGetMemoryWin32HandleKHR"
  ));

  vkGetSemaphoreWin32HandleKHR = PFN_vkGetSemaphoreWin32HandleKHR(vkGetInstanceProcAddr(
    _instance,"vkGetSemaphoreWin32HandleKHR"
  ));
}

由于这些扩展的内容不是vulkan核心,因此必须手动加载-据我了解加载过程。但是,为什么我不需要对其余必需的扩展名做同样的事情? 即:

  • VK_KHR_SURFACE_EXTENSION_NAME
  • VK_KHR_disPLAY_EXTENSION_NAME
  • VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME
  • VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME
  • VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME
  • VK_KHR_SWAPCHAIN_EXTENSION_NAME

  • VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME
  • VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME

我了解这最后两个可能是相同的,但是特定于操作系统,所以我不需要加载其他两个,因为我是手动加载它们的win32版本的

  • VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME
  • VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME

长话短说:

1。 我不明白为什么与vkdisplay和vkSwapChain相关的方法调用对我来说非常理想,而无需通过vkGetProcAdress手动映射它们。

OR

2。 为什么我需要手动加载:

PFN_vkGetSomeExtensionKHR = vkGetInstanceProcAddr(instance,“ vkCreateDebugUtilsMessengerEXT”) vkGetInstanceProcAddr(_instance,“ vkGetMemoryWin32HandleKHR”) vkGetInstanceProcAddr(_instance,“ vkGetSemaphoreWin32HandleKHR”)

而且这些也不会自动加载...有人可以向我解释在Vulkan中加载扩展程序时必要步骤的不一致吗?

解决方法

保证来自LoaderAndLayerInterface.md文档:

Windows,Linux,Android和macOS上的加载程序库将导出所有核心Vulkan和所有适当的Window System Interface(WSI)扩展。这样做是为了简化Vulkan开发入门。

否则,加载程序可能会或可能不会导出其他扩展命令。

鉴于新版本的Vulkan进行了扩展,并且基本上将其接受到原始的Vulkan中,那么那些原始扩展命令也可能会被导出。 (例如VK_KHR_get_physical_device_properties2现在是Vulkan 1.1的一部分。)但是我认为不能保证这些命令的导出,您还是应该手动加载它们。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。