• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
filterDefaultDeviceFeatures(const VkPhysicalDeviceFeatures & deviceFeatures)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 
querySupported16BitStorageFeatures(const InstanceInterface & vki,VkPhysicalDevice device,const std::vector<std::string> & instanceExtensions)51 VkPhysicalDevice16BitStorageFeaturesKHR	querySupported16BitStorageFeatures (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
52 {
53 	VkPhysicalDevice16BitStorageFeaturesKHR	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 	VkPhysicalDeviceFeatures2KHR			features;
63 
64 	deMemset(&features, 0, sizeof(features));
65 	features.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
66 	features.pNext	= &extensionFeatures;
67 
68 	// Call the getter only if supported. Otherwise above "zero" defaults are used
69 	if (de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2"))
70 	{
71 		vki.getPhysicalDeviceFeatures2KHR(device, &features);
72 	}
73 
74 	return extensionFeatures;
75 }
76 
querySupportedVariablePointersFeatures(const InstanceInterface & vki,VkPhysicalDevice device,const std::vector<std::string> & instanceExtensions)77 VkPhysicalDeviceVariablePointerFeaturesKHR querySupportedVariablePointersFeatures (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
78 {
79 	VkPhysicalDeviceVariablePointerFeaturesKHR 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 	VkPhysicalDeviceFeatures2KHR	features;
88 	deMemset(&features, 0, sizeof(features));
89 	features.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
90 	features.pNext	= &extensionFeatures;
91 
92 	// Call the getter only if supported. Otherwise above "zero" defaults are used
93 	if (de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2"))
94 	{
95 		vki.getPhysicalDeviceFeatures2KHR(device, &features);
96 	}
97 
98 	return extensionFeatures;
99 }
100 
101 } // anonymous
102 
is16BitStorageFeaturesSupported(const InstanceInterface & vki,VkPhysicalDevice device,const std::vector<std::string> & instanceExtensions,Extension16BitStorageFeatures toCheck)103 bool is16BitStorageFeaturesSupported (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, Extension16BitStorageFeatures toCheck)
104 {
105 	VkPhysicalDevice16BitStorageFeaturesKHR extensionFeatures	= querySupported16BitStorageFeatures(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 
isVariablePointersFeaturesSupported(const InstanceInterface & vki,VkPhysicalDevice device,const std::vector<std::string> & instanceExtensions,ExtensionVariablePointersFeatures toCheck)122 bool isVariablePointersFeaturesSupported (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, ExtensionVariablePointersFeatures toCheck)
123 {
124 	VkPhysicalDeviceVariablePointerFeaturesKHR extensionFeatures = querySupportedVariablePointersFeatures(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 
createDeviceWithExtensions(Context & context,const deUint32 queueFamilyIndex,const std::vector<std::string> & supportedExtensions,const std::vector<std::string> & requiredExtensions)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					(requiredExtensions.size());
143 	void*										pExtension					= DE_NULL;
144 	const VkPhysicalDeviceFeatures				deviceFeatures				= getPhysicalDeviceFeatures(vki, physicalDevice);
145 	VkPhysicalDevice16BitStorageFeaturesKHR		ext16BitStorageFeatures;
146 	VkPhysicalDeviceVariablePointerFeaturesKHR	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 (!de::contains(supportedExtensions.begin(), supportedExtensions.end(), 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(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(vki, physicalDevice, context.getInstanceExtensions());
171 			pExtension = &extVariablePointerFeatures;
172 		}
173 
174 		extensions[extNdx] = ext.c_str();
175 	}
176 
177 	const float						queuePriorities[]	= { 1.0f };
178 	const VkDeviceQueueCreateInfo	queueInfos[]		=
179 	{
180 		{
181 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
182 			DE_NULL,
183 			(VkDeviceQueueCreateFlags)0,
184 			queueFamilyIndex,
185 			DE_LENGTH_OF_ARRAY(queuePriorities),
186 			&queuePriorities[0]
187 		}
188 	};
189 	const VkPhysicalDeviceFeatures	features			= filterDefaultDeviceFeatures(deviceFeatures);
190 	const VkDeviceCreateInfo		deviceParams		=
191 	{
192 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
193 		pExtension,
194 		(VkDeviceCreateFlags)0,
195 		DE_LENGTH_OF_ARRAY(queueInfos),
196 		&queueInfos[0],
197 		0u,
198 		DE_NULL,
199 		(deUint32)extensions.size(),
200 		extensions.empty() ? DE_NULL : &extensions[0],
201 		&features
202 	};
203 
204 	return vk::createDevice(vki, physicalDevice, &deviceParams);
205 }
206 
createAllocator(const InstanceInterface & instanceInterface,const VkPhysicalDevice physicalDevice,const DeviceInterface & deviceInterface,const VkDevice device)207 Allocator* createAllocator (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const DeviceInterface& deviceInterface, const VkDevice device)
208 {
209 	const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice);
210 
211 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
212 	return new SimpleAllocator(deviceInterface, device, memoryProperties);
213 }
214 
215 } // SpirVAssembly
216 } // vkt
217