/*------------------------------------------------------------------------- * Vulkan Conformance Tests * ------------------------ * * Copyright (c) 2015 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Vulkan test case base classes *//*--------------------------------------------------------------------*/ #include "vktTestCase.hpp" #include "vkRef.hpp" #include "vkRefUtil.hpp" #include "vkQueryUtil.hpp" #include "vkDeviceUtil.hpp" #include "vkMemUtil.hpp" #include "vkPlatform.hpp" #include "vkDebugReportUtil.hpp" #include "tcuCommandLine.hpp" #include "tcuTestLog.hpp" #include "deSTLUtil.hpp" #include "deMemory.h" #if defined(DEQP_HAVE_VKRUNNER) #include #endif #include struct vk_executor; namespace vkt { // Default device utilities using std::vector; using std::string; using std::set; using namespace vk; namespace { vector getValidationLayers (const vector& 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 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 getValidationLayers (const PlatformInterface& vkp) { return getValidationLayers(enumerateInstanceLayerProperties(vkp)); } vector getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice) { return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice)); } vector filterExtensions (const vector& extensions) { vector enabledExtensions; const char* extensionGroups[] = { "VK_KHR_", "VK_EXT_", "VK_KHX_" }; for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++) { for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++) { if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx])) enabledExtensions.push_back(extensions[extNdx].extensionName); } } return enabledExtensions; } vector addExtensions (const vector& a, const vector& b) { vector res (a); for (vector::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter) { if (!de::contains(res.begin(), res.end(), string(*bIter))) res.push_back(string(*bIter)); } return res; } vector removeExtensions (const vector& a, const vector& b) { vector res; set removeExts (b.begin(), b.end()); for (vector::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter) { if (!de::contains(removeExts, *aIter)) res.push_back(*aIter); } return res; } vector addCoreInstanceExtensions (const vector& extensions, deUint32 instanceVersion) { vector coreExtensions; getCoreInstanceExtensions(instanceVersion, coreExtensions); return addExtensions(extensions, coreExtensions); } vector addCoreDeviceExtensions(const vector& extensions, deUint32 instanceVersion) { vector coreExtensions; getCoreDeviceExtensions(instanceVersion, coreExtensions); return addExtensions(extensions, coreExtensions); } deUint32 getTargetInstanceVersion (const PlatformInterface& vkp) { deUint32 version = pack(ApiVersion(1, 0, 0)); if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS) TCU_THROW(InternalError, "Enumerate instance version error"); return version; } std::pair determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine) { Move preinstance = createDefaultInstance(vkp, apiVersion); InstanceDriver preinterface (vkp, preinstance.get()); const vector devices = enumeratePhysicalDevices(preinterface, preinstance.get()); deUint32 lowestDeviceVersion = 0xFFFFFFFFu; for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx) { const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]); if (props.apiVersion < lowestDeviceVersion) lowestDeviceVersion = props.apiVersion; } const vk::VkPhysicalDevice choosenDevice = chooseDevice(preinterface, *preinstance, cmdLine); const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, choosenDevice); const deUint32 choosenDeviceVersion = props.apiVersion; return std::make_pair(choosenDeviceVersion, lowestDeviceVersion); } Move createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector& enabledExtensions, const tcu::CommandLine& cmdLine) { const bool isValidationEnabled = cmdLine.isValidationEnabled(); vector enabledLayers; // \note Extensions in core are not explicitly enabled even though // they are in the extension list advertised to tests. vector coreExtensions; getCoreInstanceExtensions(apiVersion, coreExtensions); vector nonCoreExtensions (removeExtensions(enabledExtensions, coreExtensions)); 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, apiVersion, enabledLayers, nonCoreExtensions); } static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps) { const vector queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice); for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++) { if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps) return (deUint32)queueNdx; } TCU_THROW(NotSupportedError, "No matching queue found"); } Move createDefaultDevice (const PlatformInterface& vkp, VkInstance instance, const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const deUint32 apiVersion, deUint32 queueIndex, deUint32 sparseQueueIndex, const VkPhysicalDeviceFeatures2& enabledFeatures, const vector& enabledExtensions, const tcu::CommandLine& cmdLine) { VkDeviceQueueCreateInfo queueInfo[2]; VkDeviceCreateInfo deviceInfo; vector enabledLayers; vector layerPtrs; vector extensionPtrs; const float queuePriority = 1.0f; const deUint32 numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1; 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(); // \note Extensions in core are not explicitly enabled even though // they are in the extension list advertised to tests. vector coreExtensions; getCoreDeviceExtensions(apiVersion, coreExtensions); vector nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions)); extensionPtrs.resize(nonCoreExtensions.size()); for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx) extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str(); queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueInfo[0].pNext = DE_NULL; queueInfo[0].flags = (VkDeviceQueueCreateFlags)0u; queueInfo[0].queueFamilyIndex = queueIndex; queueInfo[0].queueCount = 1u; queueInfo[0].pQueuePriorities = &queuePriority; if (numQueues > 1) { queueInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueInfo[1].pNext = DE_NULL; queueInfo[1].flags = (VkDeviceQueueCreateFlags)0u; queueInfo[1].queueFamilyIndex = sparseQueueIndex; queueInfo[1].queueCount = 1u; queueInfo[1].pQueuePriorities = &queuePriority; } // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; deviceInfo.pNext = enabledFeatures.pNext ? &enabledFeatures : DE_NULL; deviceInfo.queueCreateInfoCount = numQueues; deviceInfo.pQueueCreateInfos = queueInfo; 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.pNext ? DE_NULL : &enabledFeatures.features; return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo); }; bool isPhysicalDeviceFeatures2Supported (const deUint32 version, const vector& instanceExtensions) { return isInstanceExtensionSupported(version, instanceExtensions, "VK_KHR_get_physical_device_properties2"); } class DeviceFeatures { public: VkPhysicalDeviceFeatures2 coreFeatures; VkPhysicalDeviceSamplerYcbcrConversionFeatures samplerYCbCrConversionFeatures; VkPhysicalDevice8BitStorageFeaturesKHR eightBitStorageFeatures; VkPhysicalDevice16BitStorageFeatures sixteenBitStorageFeatures; VkPhysicalDeviceVariablePointerFeatures variablePointerFeatures; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertexAttributeDivisorFeatures; VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptorIndexingFeatures; VkPhysicalDeviceInlineUniformBlockFeaturesEXT inlineUniformBlockFeatures; VkPhysicalDeviceVulkanMemoryModelFeaturesKHR vulkanMemoryModelFeatures; VkPhysicalDeviceShaderAtomicInt64FeaturesKHR shaderAtomicInt64Features; VkPhysicalDeviceConditionalRenderingFeaturesEXT conditionalRenderingFeatures; VkPhysicalDeviceScalarBlockLayoutFeaturesEXT scalarBlockLayoutFeatures; VkPhysicalDeviceFloat16Int8FeaturesKHR float16Int8Features; DeviceFeatures (const InstanceInterface& vki, const deUint32 apiVersion, const VkPhysicalDevice& physicalDevice, const vector& instanceExtensions, const vector& deviceExtensions) { deMemset(&coreFeatures, 0, sizeof(coreFeatures)); deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures)); deMemset(&eightBitStorageFeatures, 0, sizeof(eightBitStorageFeatures)); deMemset(&sixteenBitStorageFeatures, 0, sizeof(sixteenBitStorageFeatures)); deMemset(&variablePointerFeatures, 0, sizeof(variablePointerFeatures)); deMemset(&descriptorIndexingFeatures, 0, sizeof(descriptorIndexingFeatures)); deMemset(&inlineUniformBlockFeatures, 0, sizeof(inlineUniformBlockFeatures)); deMemset(&float16Int8Features, 0, sizeof(float16Int8Features)); deMemset(&vertexAttributeDivisorFeatures, 0, sizeof(vertexAttributeDivisorFeatures)); deMemset(&descriptorIndexingFeatures, 0, sizeof(descriptorIndexingFeatures)); deMemset(&inlineUniformBlockFeatures, 0, sizeof(inlineUniformBlockFeatures)); deMemset(&vulkanMemoryModelFeatures, 0, sizeof(vulkanMemoryModelFeatures)); deMemset(&shaderAtomicInt64Features, 0, sizeof(shaderAtomicInt64Features)); deMemset(&conditionalRenderingFeatures, 0, sizeof(conditionalRenderingFeatures)); deMemset(&scalarBlockLayoutFeatures, 0, sizeof(scalarBlockLayoutFeatures)); coreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; samplerYCbCrConversionFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES; eightBitStorageFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR; sixteenBitStorageFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR; variablePointerFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR; descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; inlineUniformBlockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT; float16Int8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR; vertexAttributeDivisorFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT; descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; inlineUniformBlockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT; vulkanMemoryModelFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR; shaderAtomicInt64Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR; conditionalRenderingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT; scalarBlockLayoutFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT; vector deviceExtensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL); if (isPhysicalDeviceFeatures2Supported(apiVersion, instanceExtensions)) { void** nextPtr = &coreFeatures.pNext; if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion")) { *nextPtr = &samplerYCbCrConversionFeatures; nextPtr = &samplerYCbCrConversionFeatures.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_8bit_storage")) { *nextPtr = &eightBitStorageFeatures; nextPtr = &eightBitStorageFeatures.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_16bit_storage")) { *nextPtr = &sixteenBitStorageFeatures; nextPtr = &sixteenBitStorageFeatures.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_variable_pointers")) { *nextPtr = &variablePointerFeatures; nextPtr = &variablePointerFeatures.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_descriptor_indexing")) { *nextPtr = &descriptorIndexingFeatures; nextPtr = &descriptorIndexingFeatures.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_inline_uniform_block")) { *nextPtr = &inlineUniformBlockFeatures; nextPtr = &inlineUniformBlockFeatures.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_shader_float16_int8")) { *nextPtr = &float16Int8Features; nextPtr = &float16Int8Features.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_vertex_attribute_divisor")) { *nextPtr = &vertexAttributeDivisorFeatures; nextPtr = &vertexAttributeDivisorFeatures.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_vulkan_memory_model")) { for (size_t i = 0; i < deviceExtensionProperties.size(); ++i) { if (deStringEqual(deviceExtensionProperties[i].extensionName, "VK_KHR_vulkan_memory_model")) { if (deviceExtensionProperties[i].specVersion == VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION) { *nextPtr = &vulkanMemoryModelFeatures; nextPtr = &vulkanMemoryModelFeatures.pNext; } break; } } } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_shader_atomic_int64")) { *nextPtr = &shaderAtomicInt64Features; nextPtr = &shaderAtomicInt64Features.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_conditional_rendering")) { *nextPtr = &conditionalRenderingFeatures; nextPtr = &conditionalRenderingFeatures.pNext; } if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_scalar_block_layout")) { *nextPtr = &scalarBlockLayoutFeatures; nextPtr = &scalarBlockLayoutFeatures.pNext; } vki.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures); } else coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice); // Disable robustness by default, as it has an impact on performance on some HW. coreFeatures.features.robustBufferAccess = false; } }; } // anonymous class DefaultDevice { public: DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine); ~DefaultDevice (void); VkInstance getInstance (void) const { return *m_instance; } const InstanceInterface& getInstanceInterface (void) const { return m_instanceInterface; } deUint32 getAvailableInstanceVersion (void) const { return m_availableInstanceVersion; } const vector& getInstanceExtensions (void) const { return m_instanceExtensions; } VkPhysicalDevice getPhysicalDevice (void) const { return m_physicalDevice; } deUint32 getDeviceVersion (void) const { return m_deviceVersion; } const VkPhysicalDeviceFeatures& getDeviceFeatures (void) const { return m_deviceFeatures.coreFeatures.features; } const VkPhysicalDeviceFeatures2& getDeviceFeatures2 (void) const { return m_deviceFeatures.coreFeatures; } const VkPhysicalDeviceSamplerYcbcrConversionFeatures& getSamplerYCbCrConversionFeatures (void) const { return m_deviceFeatures.samplerYCbCrConversionFeatures; } const VkPhysicalDevice8BitStorageFeaturesKHR& get8BitStorageFeatures (void) const { return m_deviceFeatures.eightBitStorageFeatures; } const VkPhysicalDevice16BitStorageFeatures& get16BitStorageFeatures (void) const { return m_deviceFeatures.sixteenBitStorageFeatures; } const VkPhysicalDeviceVariablePointerFeatures& getVariablePointerFeatures (void) const { return m_deviceFeatures.variablePointerFeatures; } const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&getVertexAttributeDivisorFeatures (void) const { return m_deviceFeatures.vertexAttributeDivisorFeatures; } const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR& getVulkanMemoryModelFeatures (void) const { return m_deviceFeatures.vulkanMemoryModelFeatures; } const VkPhysicalDeviceShaderAtomicInt64FeaturesKHR& getShaderAtomicInt64Features (void) const { return m_deviceFeatures.shaderAtomicInt64Features; } const VkPhysicalDeviceConditionalRenderingFeaturesEXT& getConditionalRenderingFeatures (void) const { return m_deviceFeatures.conditionalRenderingFeatures; } const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& getScalarBlockLayoutFeatures (void) const { return m_deviceFeatures.scalarBlockLayoutFeatures; } const VkPhysicalDeviceFloat16Int8FeaturesKHR& getFloat16Int8Features (void) const { return m_deviceFeatures.float16Int8Features; } 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& getDeviceExtensions (void) const { return m_deviceExtensions; } deUint32 getUsedApiVersion (void) const { return m_usedApiVersion; } deUint32 getUniversalQueueFamilyIndex (void) const { return m_universalQueueFamilyIndex; } VkQueue getUniversalQueue (void) const; deUint32 getSparseQueueFamilyIndex (void) const { return m_sparseQueueFamilyIndex; } VkQueue getSparseQueue (void) const; private: const deUint32 m_availableInstanceVersion; const std::pair m_deviceVersions; const deUint32 m_usedApiVersion; const vector m_instanceExtensions; const Unique m_instance; const InstanceDriver m_instanceInterface; const VkPhysicalDevice m_physicalDevice; const deUint32 m_deviceVersion; const vector m_deviceExtensions; const DeviceFeatures m_deviceFeatures; const deUint32 m_universalQueueFamilyIndex; const deUint32 m_sparseQueueFamilyIndex; const VkPhysicalDeviceProperties m_deviceProperties; const Unique m_device; const DeviceDriver m_deviceInterface; }; static deUint32 sanitizeApiVersion(deUint32 v) { return VK_MAKE_VERSION( VK_VERSION_MAJOR(v), VK_VERSION_MINOR(v), 0 ); } DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine) : m_availableInstanceVersion (getTargetInstanceVersion(vkPlatform)) , m_deviceVersions (determineDeviceVersions(vkPlatform, m_availableInstanceVersion, cmdLine)) , m_usedApiVersion (sanitizeApiVersion(deMinu32(m_availableInstanceVersion, m_deviceVersions.first))) , m_instanceExtensions (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion)) , m_instance (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine)) , m_instanceInterface (vkPlatform, *m_instance) , m_physicalDevice (chooseDevice(m_instanceInterface, *m_instance, cmdLine)) , m_deviceVersion (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion) , m_deviceExtensions (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion)) , m_deviceFeatures (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions) , m_universalQueueFamilyIndex (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT)) , m_sparseQueueFamilyIndex (m_deviceFeatures.coreFeatures.features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0) , m_deviceProperties (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice)) , m_device (createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.coreFeatures, m_deviceExtensions, cmdLine)) , m_deviceInterface (vkPlatform, *m_instance, *m_device) { DE_ASSERT(m_deviceVersions.first == m_deviceVersion); } DefaultDevice::~DefaultDevice (void) { } VkQueue DefaultDevice::getUniversalQueue (void) const { return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0); } VkQueue DefaultDevice::getSparseQueue (void) const { if (!m_deviceFeatures.coreFeatures.features.sparseBinding) TCU_THROW(NotSupportedError, "Sparse binding not supported."); return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0); } namespace { // Allocator utilities vk::Allocator* createAllocator (DefaultDevice* device) { const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice()); // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time) return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties); } } // anonymous // Context void Context::errorCb(const char* message, void* user_data) { Context* context = (Context*) user_data; context->getTestContext().getLog() << tcu::TestLog::Message << message << "\n" << tcu::TestLog::EndMessage; } Context::Context (tcu::TestContext& testCtx, const vk::PlatformInterface& platformInterface, vk::BinaryCollection& progCollection) : m_testCtx (testCtx) , m_platformInterface (platformInterface) , m_progCollection (progCollection) , m_device (new DefaultDevice(m_platformInterface, testCtx.getCommandLine())) , m_allocator (createAllocator(m_device.get())) { #if defined(DEQP_HAVE_VKRUNNER) m_config = vr_config_new(); vr_config_set_user_data(m_config, this); vr_config_set_error_cb(m_config, errorCb); m_executor = vr_executor_new(m_config); vr_executor_set_device(m_executor, getInstanceProc, this, getPhysicalDevice(), getUniversalQueueFamilyIndex(), getDevice()); #endif } Context::~Context (void) { #if defined(DEQP_HAVE_VKRUNNER) vr_config_free(m_config); vr_executor_free(m_executor); #endif } deUint32 Context::getAvailableInstanceVersion (void) const { return m_device->getAvailableInstanceVersion(); } const vector& Context::getInstanceExtensions (void) const { return m_device->getInstanceExtensions(); } 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(); } deUint32 Context::getDeviceVersion (void) const { return m_device->getDeviceVersion(); } const vk::VkPhysicalDeviceFeatures& Context::getDeviceFeatures (void) const { return m_device->getDeviceFeatures(); } const vk::VkPhysicalDeviceFeatures2& Context::getDeviceFeatures2 (void) const { return m_device->getDeviceFeatures2(); } const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures& Context::getSamplerYCbCrConversionFeatures (void) const { return m_device->getSamplerYCbCrConversionFeatures(); } const vk::VkPhysicalDevice8BitStorageFeaturesKHR& Context::get8BitStorageFeatures (void) const { return m_device->get8BitStorageFeatures(); } const vk::VkPhysicalDevice16BitStorageFeatures& Context::get16BitStorageFeatures (void) const { return m_device->get16BitStorageFeatures(); } const vk::VkPhysicalDeviceVariablePointerFeatures& Context::getVariablePointerFeatures (void) const { return m_device->getVariablePointerFeatures(); } const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT& Context::getVertexAttributeDivisorFeatures (void) const { return m_device->getVertexAttributeDivisorFeatures(); } const vk::VkPhysicalDeviceVulkanMemoryModelFeaturesKHR& Context::getVulkanMemoryModelFeatures (void) const { return m_device->getVulkanMemoryModelFeatures(); } const vk::VkPhysicalDeviceShaderAtomicInt64FeaturesKHR& Context::getShaderAtomicInt64Features (void) const { return m_device->getShaderAtomicInt64Features(); } const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT& Context::getConditionalRenderingFeatures(void) const { return m_device->getConditionalRenderingFeatures(); } const vk::VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& Context::getScalarBlockLayoutFeatures (void) const { return m_device->getScalarBlockLayoutFeatures(); } const vk::VkPhysicalDeviceFloat16Int8FeaturesKHR& Context::getFloat16Int8Features (void) const { return m_device->getFloat16Int8Features(); } const vk::VkPhysicalDeviceProperties& Context::getDeviceProperties (void) const { return m_device->getDeviceProperties(); } const vector& 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(); } deUint32 Context::getSparseQueueFamilyIndex (void) const { return m_device->getSparseQueueFamilyIndex(); } vk::VkQueue Context::getSparseQueue (void) const { return m_device->getSparseQueue(); } vk::Allocator& Context::getDefaultAllocator (void) const { return *m_allocator; } deUint32 Context::getUsedApiVersion (void) const { return m_device->getUsedApiVersion(); } vr_executor* Context::getExecutor (void) const { return m_executor; } bool Context::contextSupports (const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const { return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); } bool Context::contextSupports (const ApiVersion version) const { return m_device->getUsedApiVersion() >= pack(version); } bool Context::contextSupports (const deUint32 requiredApiVersionBits) const { return m_device->getUsedApiVersion() >= requiredApiVersionBits; } bool Context::requireDeviceExtension (const std::string& required) { if (!isDeviceExtensionSupported(getUsedApiVersion(), getDeviceExtensions(), required)) TCU_THROW(NotSupportedError, required + " is not supported"); return true; } bool Context::requireInstanceExtension (const std::string& required) { if (!isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), required)) TCU_THROW(NotSupportedError, required + " is not supported"); return true; } struct DeviceCoreFeaturesTable { const char* featureName; const deUint32 featureArrayIndex; const deUint32 featureArrayOffset; }; #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME) DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME) #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME) { #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) } const DeviceCoreFeaturesTable deviceCoreFeaturesTable[] = { DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS , robustBufferAccess ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32 , fullDrawIndexUint32 ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY , imageCubeArray ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND , independentBlend ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER , geometryShader ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER , tessellationShader ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING , sampleRateShading ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND , dualSrcBlend ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP , logicOp ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT , multiDrawIndirect ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE , drawIndirectFirstInstance ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP , depthClamp ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP , depthBiasClamp ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID , fillModeNonSolid ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS , depthBounds ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES , wideLines ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS , largePoints ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE , alphaToOne ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT , multiViewport ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY , samplerAnisotropy ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2 , textureCompressionETC2 ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR , textureCompressionASTC_LDR ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC , textureCompressionBC ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE , occlusionQueryPrecise ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY , pipelineStatisticsQuery ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS , vertexPipelineStoresAndAtomics ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS , fragmentStoresAndAtomics ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE , shaderTessellationAndGeometryPointSize ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED , shaderImageGatherExtended ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS , shaderStorageImageExtendedFormats ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE , shaderStorageImageMultisample ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT , shaderStorageImageReadWithoutFormat ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT , shaderStorageImageWriteWithoutFormat ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING , shaderUniformBufferArrayDynamicIndexing ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING , shaderSampledImageArrayDynamicIndexing ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING , shaderStorageBufferArrayDynamicIndexing ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING , shaderStorageImageArrayDynamicIndexing ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE , shaderClipDistance ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE , shaderCullDistance ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64 , shaderFloat64 ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64 , shaderInt64 ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16 , shaderInt16 ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY , shaderResourceResidency ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD , shaderResourceMinLod ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING , sparseBinding ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER , sparseResidencyBuffer ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D , sparseResidencyImage2D ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D , sparseResidencyImage3D ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES , sparseResidency2Samples ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES , sparseResidency4Samples ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES , sparseResidency8Samples ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES , sparseResidency16Samples ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED , sparseResidencyAliased ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE , variableMultisampleRate ), DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES , inheritedQueries ), }; bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature) { const vk::VkPhysicalDeviceFeatures& featuresAvailable = getDeviceFeatures(); const vk::VkBool32* featuresAvailableArray = (vk::VkBool32*)(&featuresAvailable); const deUint32 requiredFeatureIndex = static_cast(requiredFeature); DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable)); DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset); if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE) TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName)); return true; } void* Context::getInstanceProc (const char* name, void* user_data) { Context *context = (Context*) user_data; return (void*) context->m_platformInterface.getInstanceProcAddr(context->getInstance(), name); } // TestCase void TestCase::initPrograms (SourceCollections&) const { } void TestCase::checkSupport (Context&) const { } } // vkt