title: How to properly load Vulkan extensions?
body: <p>I dont understand the behaviour of the Vulkan extension system and the loading/not loading some of them, can please somebody explain me why, when I have these required extensions:</p>
  <pre><code>    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
      }
    );
  </code></pre>
  <p>I just check the presence of extensions during the instance creation:</p>
  <pre><code>  VkInstanceCreateInfo createInfo = {};
    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    createInfo.pApplicationInfo = &amp;appInfo;
    createInfo.enabledLayerCount = static_cast&lt;uint32_t&gt;(_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, &amp;extensionCount, nullptr);
    std::vector&lt;VkExtensionProperties&gt; availableExtensions(extensionCount);
    vkEnumerateInstanceExtensionProperties(nullptr, &amp;extensionCount, availableExtensions.data());
  
    cerrlog.debug() &lt;&lt; &quot;Available extensions: &quot; &lt;&lt; std::endl;
    for(const auto&amp; extension : availableExtensions) {
        cerrlog.debug() &lt;&lt; extension.extensionName &lt;&lt; std::endl;
    }
  
    createInfo.enabledExtensionCount = static_cast&lt;uint32_t&gt;(_settings.requiredInstanceExtensions.size());
    createInfo.ppEnabledExtensionNames = _settings.requiredInstanceExtensions.data();
  
    VkResult result = vkCreateInstance(&amp;createInfo, nullptr, &amp;_instance);
    VulkanException::throwIfNotOK(&quot;Failed to create vk instance!&quot;, result);
  </code></pre>
  <p>In similar way I check the extension suppoort for device extensions and then create it:</p>
  <pre><code>  VkDeviceCreateInfo createInfo = {};
    createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    createInfo.queueCreateInfoCount = static_cast&lt;int&gt;(queueCreateInfos.size());
    createInfo.pQueueCreateInfos = queueCreateInfos.data();
    createInfo.pEnabledFeatures = &amp;deviceFeatures;
    createInfo.enabledExtensionCount = static_cast&lt;uint32_t&gt;(_deviceExtensions.size());
    createInfo.ppEnabledExtensionNames = _deviceExtensions.data();
  
    if (validationEnabled) {
      createInfo.enabledLayerCount = static_cast&lt;uint32_t&gt;(
        validationLayers.getValidationLayersCount());
      createInfo.ppEnabledLayerNames = validationLayers.getValidationLayersNames();
    } else {
      createInfo.enabledLayerCount = 0;
    }
  
    VkResult result = vkCreateDevice(_physicalDevice, &amp;createInfo, nullptr, &amp;_device);
  </code></pre>
  <p>This will lead to the creation of the instance and also maps the vulkan core calls through this instance (even for device as it is mapped from instance). But I still need to load debug utils:</p>
  <pre><code>VkResult VulkanDebugLogger::CreateDebugUtilsMessengerEXT(
    VkInstance instance,
    const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
    const VkAllocationCallbacks* pAllocator,
    VkDebugUtilsMessengerEXT* pCallback
  )
  {
    auto func = reinterpret_cast&lt;PFN_vkCreateDebugUtilsMessengerEXT&gt;(
      vkGetInstanceProcAddr(instance,&quot;vkCreateDebugUtilsMessengerEXT&quot;)
    );
  
    if (func != nullptr) {
      return func(instance, pCreateInfo, pAllocator, pCallback);
    }
    else {
      return VK_ERROR_EXTENSION_NOT_PRESENT;
    }
  }
  </code></pre>
  <p>And also I need to load these extension:</p>
  <pre><code>void VulkanRenderer::loadExtensions()
  {
    vkGetMemoryWin32HandleKHR = PFN_vkGetMemoryWin32HandleKHR(vkGetInstanceProcAddr(
      _instance,
      &quot;vkGetMemoryWin32HandleKHR&quot;
    ));
  
    vkGetSemaphoreWin32HandleKHR = PFN_vkGetSemaphoreWin32HandleKHR(vkGetInstanceProcAddr(
      _instance,
      &quot;vkGetSemaphoreWin32HandleKHR&quot;
    ));
  }
  </code></pre>
  <p>As content of these extensions is not vulkan core it must be loaded manually - as I understand loading process. But why I do not need to do the same with the rest of required extensions?
  Namely:</p>
  <ul>
  <li>VK_KHR_SURFACE_EXTENSION_NAME</li>
  <li>VK_KHR_DISPLAY_EXTENSION_NAME</li>
  <li>VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME</li>
  <li>VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME</li>
  <li>VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME</li>
  <li>VK_KHR_SWAPCHAIN_EXTENSION_NAME</li>
  </ul>
  <hr />
  <ul>
  <li>VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME</li>
  <li>VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME</li>
  </ul>
  <hr />
  <p>I understand that these last two are probably the same but OS specific so I do not need to load other two because I am manually loading the win32 versions of them</p>
  <ul>
  <li>VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME</li>
  <li>VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME</li>
  </ul>
  <p><em><strong>Long story short:</strong></em></p>
  <p><strong>1.</strong>
  I do not understand why e.g. vkDisplay and vkSwapChain related method calls works perfectly for me without manully mapping them through vkGetProcAdress...</p>
  <p>OR</p>
  <p><strong>2.</strong>
  Why I need to manually load:</p>
  <p><em>PFN_vkGetSomeExtensionKHR =
  vkGetInstanceProcAddr(instance,&quot;vkCreateDebugUtilsMessengerEXT&quot;)
  vkGetInstanceProcAddr(_instance,&quot;vkGetMemoryWin32HandleKHR&quot;)
  vkGetInstanceProcAddr(_instance,&quot;vkGetSemaphoreWin32HandleKHR&quot;)</em></p>
  <p>and these are not loaded automatically too... can somebody please explain me this inconsistency of necessary steps when loading extensions in Vulkan?</p>