Skip to content

Vulkan test-harness sample doesn't check for physical device extensions support #83

@SolarianGG

Description

@SolarianGG

samples/test-harness/src/Vulkan.cpp

CreateDeviceInternal function does not check for device extensions support, but rather picks first device with graphics queue support.

This behavior results in program crash when executed on systems with multiple gpus, possibly one of them integrated to the CPU (like laptops for example).

/**
         * Create the Vulkan device and queue.
         */
        bool CreateDeviceInternal(Globals& vk, Configs::Config& config)
        {
            // Get the number of physical graphics devices
            uint32_t physicalDeviceCount = 0;
            VKCHECK(vkEnumeratePhysicalDevices(vk.instance, &physicalDeviceCount, nullptr));
            if (physicalDeviceCount == 0) return false;

            // Get the list of physical devices
            std::vector<VkPhysicalDevice> devices(physicalDeviceCount);
            VKCHECK(vkEnumeratePhysicalDevices(vk.instance, &physicalDeviceCount, devices.data()));

            // Find a physical device that supports graphics queues
            if (!FindPhysicalDeviceWithGraphicsQueue(devices, &vk.physicalDevice, &vk.queueFamilyIndex)) return false;

           ....

}

Possible fix to this would be to implement extensions check support to the FindPhysicalDeviceWithGraphicsQueue

Like this:

   bool CheckDeviceExtensions(VkPhysicalDevice device,
       const std::vector<const char*>& requiredExtensions)
   {
       uint32_t count;
       vkEnumerateDeviceExtensionProperties(device, nullptr, &count, nullptr);

       std::vector<VkExtensionProperties> available(count);
       vkEnumerateDeviceExtensionProperties(device, nullptr, &count, available.data());

       std::unordered_set<std::string> required(requiredExtensions.begin(), requiredExtensions.end());

       for (const auto& ext : available)
           required.erase(ext.extensionName);

       return required.empty();
   }

   /**
    * Search a list of physical devices for one that supports a graphics queue.
    */
   bool FindPhysicalDeviceWithGraphicsQueueAndExtensions(const std::vector<VkPhysicalDevice>& physicalDevices, const std::vector<const char*>& requiredExtensions, VkPhysicalDevice* device, int* graphicsQueueIndex)
   {
       for (uint32_t deviceIndex = 0; deviceIndex < static_cast<uint32_t>(physicalDevices.size()); deviceIndex++)
       {
           // Get the physical device
           const VkPhysicalDevice physicalDevice = physicalDevices[deviceIndex];

           // Get the number of extension properties
           if (!CheckDeviceExtensions(physicalDevice, requiredExtensions)) continue;

           // Get the number of properties
           uint32_t queueFamilyPropertyCount = 0;
           vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertyCount, nullptr);
           if (queueFamilyPropertyCount == 0) continue;

           // Get a list of the queue properties
           std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyPropertyCount);
           vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties.data());

           // Inspect the list of properties to see if the physical device supports graphics queues
           for (uint32_t propertyIndex = 0; propertyIndex < static_cast<uint32_t>(queueFamilyProperties.size()); propertyIndex++)
           {
               const VkQueueFamilyProperties props = queueFamilyProperties[propertyIndex];
               if (props.queueFlags & VK_QUEUE_GRAPHICS_BIT)
               {
                   if (device) *device = physicalDevice;
                   if (graphicsQueueIndex) *graphicsQueueIndex = propertyIndex;
                   return true;
               }
           }
       }

       return false;
   }

Although it is also not perfect, since here the code doesn't check for extension features support.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions