Use all KHR and EXT extensions by default
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / vktTestCase.cpp
index 42c6532..cc4268f 100644 (file)
@@ -29,6 +29,9 @@
 #include "vkDeviceUtil.hpp"
 #include "vkMemUtil.hpp"
 #include "vkPlatform.hpp"
+#include "vkDebugReportUtil.hpp"
+
+#include "tcuCommandLine.hpp"
 
 #include "deMemory.h"
 
@@ -38,8 +41,91 @@ namespace vkt
 // Default device utilities
 
 using std::vector;
+using std::string;
 using namespace vk;
 
+vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
+{
+       static const char*      s_magicLayer            = "VK_LAYER_LUNARG_standard_validation";
+       static const char*      s_defaultLayers[]       =
+       {
+               "VK_LAYER_GOOGLE_threading",
+               "VK_LAYER_LUNARG_parameter_validation",
+               "VK_LAYER_LUNARG_device_limits",
+               "VK_LAYER_LUNARG_object_tracker",
+               "VK_LAYER_LUNARG_image",
+               "VK_LAYER_LUNARG_core_validation",
+               "VK_LAYER_LUNARG_swapchain",
+               "VK_LAYER_GOOGLE_unique_objects"
+       };
+
+       vector<string>          enabledLayers;
+
+       if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
+               enabledLayers.push_back(s_magicLayer);
+       else
+       {
+               for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
+               {
+                       if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
+                               enabledLayers.push_back(s_defaultLayers[ndx]);
+               }
+       }
+
+       return enabledLayers;
+}
+
+vector<string> getValidationLayers (const PlatformInterface& vkp)
+{
+       return getValidationLayers(enumerateInstanceLayerProperties(vkp));
+}
+
+vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
+{
+       return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
+}
+
+vector<string> filterExtensions(const vector<VkExtensionProperties>& deviceExtensions)
+{
+       vector<string>  enabledExtensions;
+       const char*             extensionGroups[] =
+       {
+               "VK_KHR_",
+               "VK_EXT_"
+       };
+
+       for (size_t deviceExtNdx = 0; deviceExtNdx < deviceExtensions.size(); deviceExtNdx++)
+       {
+               for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
+               {
+                       if (deStringBeginsWith(deviceExtensions[deviceExtNdx].extensionName, extensionGroups[extGroupNdx]))
+                               enabledExtensions.push_back(deviceExtensions[deviceExtNdx].extensionName);
+               }
+       }
+
+       return enabledExtensions;
+}
+
+Move<VkInstance> createInstance (const PlatformInterface& vkp, const tcu::CommandLine& cmdLine)
+{
+       const bool                                                      isValidationEnabled     = cmdLine.isValidationEnabled();
+       vector<string>                                          enabledLayers;
+       const vector<VkExtensionProperties>     extensionProperties     = enumerateInstanceExtensionProperties(vkp, DE_NULL);
+       const vector<string>                            enabledExtensions       = filterExtensions(extensionProperties);
+
+       if (isValidationEnabled)
+       {
+               if (!isDebugReportSupported(vkp))
+                       TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
+
+               enabledLayers = getValidationLayers(vkp);
+               if (enabledLayers.empty())
+                       TCU_THROW(NotSupportedError, "No validation layers found");
+       }
+
+       return createDefaultInstance(vkp, enabledLayers, enabledExtensions);
+}
+
 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
 {
        const vector<VkQueueFamilyProperties>   queueProps      = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
@@ -53,15 +139,40 @@ static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstanc
        TCU_THROW(NotSupportedError, "No matching queue found");
 }
 
-Move<VkDevice> createDefaultDevice (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 queueIndex, const VkPhysicalDeviceFeatures& enabledFeatures)
+Move<VkDevice> createDefaultDevice (const InstanceInterface&           vki,
+                                                                       VkPhysicalDevice                                physicalDevice,
+                                                                       deUint32                                                queueIndex,
+                                                                       const VkPhysicalDeviceFeatures& enabledFeatures,
+                                                                       const vector<string>&                   enabledExtensions,
+                                                                       const tcu::CommandLine&                 cmdLine)
 {
        VkDeviceQueueCreateInfo         queueInfo;
        VkDeviceCreateInfo                      deviceInfo;
+       vector<string>                          enabledLayers;
+       vector<const char*>                     layerPtrs;
+       vector<const char*>                     extensionPtrs;
        const float                                     queuePriority   = 1.0f;
 
        deMemset(&queueInfo,    0, sizeof(queueInfo));
        deMemset(&deviceInfo,   0, sizeof(deviceInfo));
 
+       if (cmdLine.isValidationEnabled())
+       {
+               enabledLayers = getValidationLayers(vki, physicalDevice);
+               if (enabledLayers.empty())
+                       TCU_THROW(NotSupportedError, "No validation layers found");
+       }
+
+       layerPtrs.resize(enabledLayers.size());
+
+       for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
+               layerPtrs[ndx] = enabledLayers[ndx].c_str();
+
+       extensionPtrs.resize(enabledExtensions.size());
+
+       for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
+               extensionPtrs[ndx] = enabledExtensions[ndx].c_str();
+
        queueInfo.sType                                                 = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        queueInfo.pNext                                                 = DE_NULL;
        queueInfo.flags                                                 = (VkDeviceQueueCreateFlags)0u;
@@ -73,10 +184,10 @@ Move<VkDevice> createDefaultDevice (const InstanceInterface& vki, VkPhysicalDevi
        deviceInfo.pNext                                                = DE_NULL;
        deviceInfo.queueCreateInfoCount                 = 1u;
        deviceInfo.pQueueCreateInfos                    = &queueInfo;
-       deviceInfo.enabledExtensionCount                = 0u;
-       deviceInfo.ppEnabledExtensionNames              = DE_NULL;
-       deviceInfo.enabledLayerCount                    = 0u;
-       deviceInfo.ppEnabledLayerNames                  = DE_NULL;
+       deviceInfo.enabledExtensionCount                = (deUint32)extensionPtrs.size();
+       deviceInfo.ppEnabledExtensionNames              = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
+       deviceInfo.enabledLayerCount                    = (deUint32)layerPtrs.size();
+       deviceInfo.ppEnabledLayerNames                  = (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
        deviceInfo.pEnabledFeatures                             = &enabledFeatures;
 
        return createDevice(vki, physicalDevice, &deviceInfo);
@@ -96,12 +207,14 @@ public:
        VkDevice                                                        getDevice                                               (void) const    { return *m_device;                                             }
        const DeviceInterface&                          getDeviceInterface                              (void) const    { return m_deviceInterface;                             }
        const VkPhysicalDeviceProperties&       getDeviceProperties                             (void) const    { return m_deviceProperties;                    }
+       const vector<string>&                           getDeviceExtensions                             (void) const    { return m_deviceExtensions;                    }
 
        deUint32                                                        getUniversalQueueFamilyIndex    (void) const    { return m_universalQueueFamilyIndex;   }
        VkQueue                                                         getUniversalQueue                               (void) const;
 
 private:
        static VkPhysicalDeviceFeatures         filterDefaultDeviceFeatures             (const VkPhysicalDeviceFeatures& deviceFeatures);
+       static vector<string>                           filterDefaultDeviceExtensions   (const vector<VkExtensionProperties>& deviceExtensions);
 
        const Unique<VkInstance>                        m_instance;
        const InstanceDriver                            m_instanceInterface;
@@ -111,19 +224,21 @@ private:
        const deUint32                                          m_universalQueueFamilyIndex;
        const VkPhysicalDeviceFeatures          m_deviceFeatures;
        const VkPhysicalDeviceProperties        m_deviceProperties;
+       const vector<string>                            m_deviceExtensions;
 
        const Unique<VkDevice>                          m_device;
        const DeviceDriver                                      m_deviceInterface;
 };
 
 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
-       : m_instance                                    (createDefaultInstance(vkPlatform))
+       : m_instance                                    (createInstance(vkPlatform, cmdLine))
        , m_instanceInterface                   (vkPlatform, *m_instance)
        , m_physicalDevice                              (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
        , m_universalQueueFamilyIndex   (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
        , m_deviceFeatures                              (filterDefaultDeviceFeatures(getPhysicalDeviceFeatures(m_instanceInterface, m_physicalDevice)))
-       , m_deviceProperties                    (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice)) // \note All supported features are enabled
-       , m_device                                              (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_deviceFeatures))
+       , m_deviceProperties                    (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
+       , m_deviceExtensions                    (filterDefaultDeviceExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)))
+       , m_device                                              (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_deviceFeatures, m_deviceExtensions, cmdLine))
        , m_deviceInterface                             (m_instanceInterface, *m_device)
 {
 }
@@ -149,6 +264,11 @@ VkPhysicalDeviceFeatures DefaultDevice::filterDefaultDeviceFeatures (const VkPhy
        return enabledDeviceFeatures;
 }
 
+vector<string> DefaultDevice::filterDefaultDeviceExtensions (const vector<VkExtensionProperties>& deviceExtensions)
+{
+       return filterExtensions(deviceExtensions);
+}
+
 // Allocator utilities
 
 vk::Allocator* createAllocator (DefaultDevice* device)
@@ -176,16 +296,17 @@ Context::~Context (void)
 {
 }
 
-vk::VkInstance                                         Context::getInstance                                    (void) const { return m_device->getInstance();                                  }
-const vk::InstanceInterface&           Context::getInstanceInterface                   (void) const { return m_device->getInstanceInterface();                 }
-vk::VkPhysicalDevice                           Context::getPhysicalDevice                              (void) const { return m_device->getPhysicalDevice();                    }
-const vk::VkPhysicalDeviceFeatures&    Context::getDeviceFeatures                              (void) const { return m_device->getDeviceFeatures();                    }
-const vk::VkPhysicalDeviceProperties&  Context::getDeviceProperties            (void) const { return m_device->getDeviceProperties();                  }
-vk::VkDevice                                           Context::getDevice                                              (void) const { return m_device->getDevice();                                    }
-const vk::DeviceInterface&                     Context::getDeviceInterface                             (void) const { return m_device->getDeviceInterface();                   }
-deUint32                                                       Context::getUniversalQueueFamilyIndex   (void) const { return m_device->getUniversalQueueFamilyIndex(); }
-vk::VkQueue                                                    Context::getUniversalQueue                              (void) const { return m_device->getUniversalQueue();                    }
-vk::Allocator&                                         Context::getDefaultAllocator                    (void) const { return *m_allocator;                                                             }
+vk::VkInstance                                                 Context::getInstance                                    (void) const { return m_device->getInstance();                                  }
+const vk::InstanceInterface&                   Context::getInstanceInterface                   (void) const { return m_device->getInstanceInterface();                 }
+vk::VkPhysicalDevice                                   Context::getPhysicalDevice                              (void) const { return m_device->getPhysicalDevice();                    }
+const vk::VkPhysicalDeviceFeatures&            Context::getDeviceFeatures                              (void) const { return m_device->getDeviceFeatures();                    }
+const vk::VkPhysicalDeviceProperties&  Context::getDeviceProperties                    (void) const { return m_device->getDeviceProperties();                  }
+const vector<string>&                                  Context::getDeviceExtensions                    (void) const { return m_device->getDeviceExtensions();                  }
+vk::VkDevice                                                   Context::getDevice                                              (void) const { return m_device->getDevice();                                    }
+const vk::DeviceInterface&                             Context::getDeviceInterface                             (void) const { return m_device->getDeviceInterface();                   }
+deUint32                                                               Context::getUniversalQueueFamilyIndex   (void) const { return m_device->getUniversalQueueFamilyIndex(); }
+vk::VkQueue                                                            Context::getUniversalQueue                              (void) const { return m_device->getUniversalQueue();                    }
+vk::Allocator&                                                 Context::getDefaultAllocator                    (void) const { return *m_allocator;                                                             }
 
 // TestCase