#include "vkDeviceUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPlatform.hpp"
+#include "vkDebugReportUtil.hpp"
+
+#include "tcuCommandLine.hpp"
#include "deMemory.h"
// 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);
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;
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);
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;
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)
{
}
return enabledDeviceFeatures;
}
+vector<string> DefaultDevice::filterDefaultDeviceExtensions (const vector<VkExtensionProperties>& deviceExtensions)
+{
+ return filterExtensions(deviceExtensions);
+}
+
// Allocator utilities
vk::Allocator* createAllocator (DefaultDevice* device)
{
}
-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