Home | History | Annotate | Download | only in spirv_assembly
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2017 Google Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Utilities for Vulkan SPIR-V assembly tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktSpvAsmUtils.hpp"
     25 
     26 #include "deMemory.h"
     27 #include "deSTLUtil.hpp"
     28 #include "vkQueryUtil.hpp"
     29 #include "vkRefUtil.hpp"
     30 
     31 namespace vkt
     32 {
     33 namespace SpirVAssembly
     34 {
     35 
     36 using namespace vk;
     37 
     38 namespace
     39 {
     40 
     41 VkPhysicalDeviceFeatures filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures)
     42 {
     43 	VkPhysicalDeviceFeatures enabledDeviceFeatures = deviceFeatures;
     44 
     45 	// Disable robustness by default, as it has an impact on performance on some HW.
     46 	enabledDeviceFeatures.robustBufferAccess = false;
     47 
     48 	return enabledDeviceFeatures;
     49 }
     50 
     51 VkPhysicalDevice16BitStorageFeatures	querySupported16BitStorageFeatures (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
     52 {
     53 	VkPhysicalDevice16BitStorageFeatures	extensionFeatures	=
     54 	{
     55 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,	// sType
     56 		DE_NULL,														// pNext
     57 		false,															// storageUniformBufferBlock16
     58 		false,															// storageUniform16
     59 		false,															// storagePushConstant16
     60 		false,															// storageInputOutput16
     61 	};
     62 	VkPhysicalDeviceFeatures2			features;
     63 
     64 	deMemset(&features, 0, sizeof(features));
     65 	features.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
     66 	features.pNext	= &extensionFeatures;
     67 
     68 	// Call the getter only if supported. Otherwise above "zero" defaults are used
     69 	if(isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
     70 	{
     71 		vki.getPhysicalDeviceFeatures2(device, &features);
     72 	}
     73 
     74 	return extensionFeatures;
     75 }
     76 
     77 VkPhysicalDeviceVariablePointerFeatures querySupportedVariablePointersFeatures (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
     78 {
     79 	VkPhysicalDeviceVariablePointerFeatures extensionFeatures	=
     80 	{
     81 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR,	// sType
     82 		DE_NULL,															// pNext
     83 		false,																// variablePointersStorageBuffer
     84 		false,																// variablePointers
     85 	};
     86 
     87 	VkPhysicalDeviceFeatures2	features;
     88 	deMemset(&features, 0, sizeof(features));
     89 	features.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
     90 	features.pNext	= &extensionFeatures;
     91 
     92 	// Call the getter only if supported. Otherwise above "zero" defaults are used
     93 	if(isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
     94 	{
     95 		vki.getPhysicalDeviceFeatures2(device, &features);
     96 	}
     97 
     98 	return extensionFeatures;
     99 }
    100 
    101 } // anonymous
    102 
    103 bool is16BitStorageFeaturesSupported (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, Extension16BitStorageFeatures toCheck)
    104 {
    105 	VkPhysicalDevice16BitStorageFeatures extensionFeatures	= querySupported16BitStorageFeatures(apiVersion, vki, device, instanceExtensions);
    106 
    107 	if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK) != 0 && extensionFeatures.storageBuffer16BitAccess == VK_FALSE)
    108 		return false;
    109 
    110 	if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM) != 0 && extensionFeatures.uniformAndStorageBuffer16BitAccess == VK_FALSE)
    111 		return false;
    112 
    113 	if ((toCheck & EXT16BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant16 == VK_FALSE)
    114 		return false;
    115 
    116 	if ((toCheck & EXT16BITSTORAGEFEATURES_INPUT_OUTPUT) != 0 && extensionFeatures.storageInputOutput16 == VK_FALSE)
    117 		return false;
    118 
    119 	return true;
    120 }
    121 
    122 bool isVariablePointersFeaturesSupported (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, ExtensionVariablePointersFeatures toCheck)
    123 {
    124 	VkPhysicalDeviceVariablePointerFeatures extensionFeatures = querySupportedVariablePointersFeatures(apiVersion, vki, device, instanceExtensions);
    125 
    126 	if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER) != 0 && extensionFeatures.variablePointersStorageBuffer == VK_FALSE)
    127 		return false;
    128 
    129 	if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS) != 0 && extensionFeatures.variablePointers == VK_FALSE)
    130 		return false;
    131 
    132 	return true;
    133 }
    134 
    135 Move<VkDevice> createDeviceWithExtensions (Context&							context,
    136 										   const deUint32					queueFamilyIndex,
    137 										   const std::vector<std::string>&	supportedExtensions,
    138 										   const std::vector<std::string>&	requiredExtensions)
    139 {
    140 	const InstanceInterface&					vki							= context.getInstanceInterface();
    141 	const VkPhysicalDevice						physicalDevice				= context.getPhysicalDevice();
    142 	std::vector<const char*>					extensions;
    143 	void*										pExtension					= DE_NULL;
    144 	const VkPhysicalDeviceFeatures				deviceFeatures				= getPhysicalDeviceFeatures(vki, physicalDevice);
    145 	VkPhysicalDevice16BitStorageFeatures		ext16BitStorageFeatures;
    146 	VkPhysicalDeviceVariablePointerFeatures		extVariablePointerFeatures;
    147 
    148 	for (deUint32 extNdx = 0; extNdx < requiredExtensions.size(); ++extNdx)
    149 	{
    150 		const std::string&	ext = requiredExtensions[extNdx];
    151 
    152 		// Check that all required extensions are supported first.
    153 		if (!isDeviceExtensionSupported(context.getUsedApiVersion(), supportedExtensions, ext))
    154 		{
    155 			TCU_THROW(NotSupportedError, (std::string("Device extension not supported: ") + ext).c_str());
    156 		}
    157 
    158 		// Currently don't support enabling multiple extensions at the same time.
    159 		if (ext == "VK_KHR_16bit_storage")
    160 		{
    161 			// For the 16bit storage extension, we have four features to test. Requesting all features supported.
    162 			// Note that we don't throw NotImplemented errors here if a specific feature is not supported;
    163 			// that should be done when actually trying to use that specific feature.
    164 			ext16BitStorageFeatures	= querySupported16BitStorageFeatures(context.getUsedApiVersion(), vki, physicalDevice, context.getInstanceExtensions());
    165 			pExtension = &ext16BitStorageFeatures;
    166 		}
    167 		else if (ext == "VK_KHR_variable_pointers")
    168 		{
    169 			// For the VariablePointers extension, we have two features to test. Requesting all features supported.
    170 			extVariablePointerFeatures	= querySupportedVariablePointersFeatures(context.getUsedApiVersion(), vki, physicalDevice, context.getInstanceExtensions());
    171 			pExtension = &extVariablePointerFeatures;
    172 		}
    173 
    174 		if (!isCoreDeviceExtension(context.getUsedApiVersion(), ext))
    175 			extensions.push_back(ext.c_str());
    176 	}
    177 
    178 	const float						queuePriorities[]	= { 1.0f };
    179 	const VkDeviceQueueCreateInfo	queueInfos[]		=
    180 	{
    181 		{
    182 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    183 			DE_NULL,
    184 			(VkDeviceQueueCreateFlags)0,
    185 			queueFamilyIndex,
    186 			DE_LENGTH_OF_ARRAY(queuePriorities),
    187 			&queuePriorities[0]
    188 		}
    189 	};
    190 	const VkPhysicalDeviceFeatures	features			= filterDefaultDeviceFeatures(deviceFeatures);
    191 	const VkDeviceCreateInfo		deviceParams		=
    192 	{
    193 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
    194 		pExtension,
    195 		(VkDeviceCreateFlags)0,
    196 		DE_LENGTH_OF_ARRAY(queueInfos),
    197 		&queueInfos[0],
    198 		0u,
    199 		DE_NULL,
    200 		(deUint32)extensions.size(),
    201 		extensions.empty() ? DE_NULL : &extensions[0],
    202 		&features
    203 	};
    204 
    205 	return vk::createDevice(vki, physicalDevice, &deviceParams);
    206 }
    207 
    208 Allocator* createAllocator (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const DeviceInterface& deviceInterface, const VkDevice device)
    209 {
    210 	const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice);
    211 
    212 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
    213 	return new SimpleAllocator(deviceInterface, device, memoryProperties);
    214 }
    215 
    216 deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
    217 {
    218 	switch(version)
    219 	{
    220 	case SPIRV_VERSION_1_0:
    221 		return VK_API_VERSION_1_0;
    222 	case SPIRV_VERSION_1_1:
    223 	case SPIRV_VERSION_1_2:
    224 	case SPIRV_VERSION_1_3:
    225 		return VK_API_VERSION_1_1;
    226 	default:
    227 		DE_ASSERT(0);
    228 	}
    229 	return 0u;
    230 }
    231 
    232 std::string	getVulkanName (const deUint32 version)
    233 {
    234 	return std::string(version == VK_API_VERSION_1_1 ? "1.1" : "1.0");
    235 }
    236 
    237 } // SpirVAssembly
    238 } // vkt
    239