• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 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 Vulkan test case base classes
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktTestCase.hpp"
25 
26 #include "vkRef.hpp"
27 #include "vkRefUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkDeviceUtil.hpp"
30 #include "vkMemUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkDebugReportUtil.hpp"
33 
34 #include "tcuCommandLine.hpp"
35 
36 #include "deMemory.h"
37 
38 namespace vkt
39 {
40 
41 // Default device utilities
42 
43 using std::vector;
44 using std::string;
45 using namespace vk;
46 
getValidationLayers(const vector<VkLayerProperties> & supportedLayers)47 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers)
48 {
49 	static const char*	s_magicLayer		= "VK_LAYER_LUNARG_standard_validation";
50 	static const char*	s_defaultLayers[]	=
51 	{
52 		"VK_LAYER_GOOGLE_threading",
53 		"VK_LAYER_LUNARG_parameter_validation",
54 		"VK_LAYER_LUNARG_device_limits",
55 		"VK_LAYER_LUNARG_object_tracker",
56 		"VK_LAYER_LUNARG_image",
57 		"VK_LAYER_LUNARG_core_validation",
58 		"VK_LAYER_LUNARG_swapchain",
59 		"VK_LAYER_GOOGLE_unique_objects"
60 	};
61 
62 	vector<string>		enabledLayers;
63 
64 	if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer)))
65 		enabledLayers.push_back(s_magicLayer);
66 	else
67 	{
68 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
69 		{
70 			if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx])))
71 				enabledLayers.push_back(s_defaultLayers[ndx]);
72 		}
73 	}
74 
75 	return enabledLayers;
76 }
77 
getValidationLayers(const PlatformInterface & vkp)78 vector<string> getValidationLayers (const PlatformInterface& vkp)
79 {
80 	return getValidationLayers(enumerateInstanceLayerProperties(vkp));
81 }
82 
getValidationLayers(const InstanceInterface & vki,VkPhysicalDevice physicalDevice)83 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
84 {
85 	return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
86 }
87 
createInstance(const PlatformInterface & vkp,const tcu::CommandLine & cmdLine)88 Move<VkInstance> createInstance (const PlatformInterface& vkp, const tcu::CommandLine& cmdLine)
89 {
90 	const bool		isValidationEnabled	= cmdLine.isValidationEnabled();
91 	vector<string>	enabledExtensions;
92 	vector<string>	enabledLayers;
93 
94 	if (isValidationEnabled)
95 	{
96 		if (isDebugReportSupported(vkp))
97 			enabledExtensions.push_back("VK_EXT_debug_report");
98 		else
99 			TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
100 
101 		enabledLayers = getValidationLayers(vkp);
102 		if (enabledLayers.empty())
103 			TCU_THROW(NotSupportedError, "No validation layers found");
104 	}
105 
106 	return createDefaultInstance(vkp, enabledLayers, enabledExtensions);
107 }
108 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)109 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
110 {
111 	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
112 
113 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
114 	{
115 		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
116 			return (deUint32)queueNdx;
117 	}
118 
119 	TCU_THROW(NotSupportedError, "No matching queue found");
120 }
121 
createDefaultDevice(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,deUint32 queueIndex,const VkPhysicalDeviceFeatures & enabledFeatures,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine)122 Move<VkDevice> createDefaultDevice (const InstanceInterface&		vki,
123 									VkPhysicalDevice				physicalDevice,
124 									deUint32						queueIndex,
125 									const VkPhysicalDeviceFeatures&	enabledFeatures,
126 									const vector<string>&			enabledExtensions,
127 									const tcu::CommandLine&			cmdLine)
128 {
129 	VkDeviceQueueCreateInfo		queueInfo;
130 	VkDeviceCreateInfo			deviceInfo;
131 	vector<string>				enabledLayers;
132 	vector<const char*>			layerPtrs;
133 	vector<const char*>			extensionPtrs;
134 	const float					queuePriority	= 1.0f;
135 
136 	deMemset(&queueInfo,	0, sizeof(queueInfo));
137 	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
138 
139 	if (cmdLine.isValidationEnabled())
140 	{
141 		enabledLayers = getValidationLayers(vki, physicalDevice);
142 		if (enabledLayers.empty())
143 			TCU_THROW(NotSupportedError, "No validation layers found");
144 	}
145 
146 	layerPtrs.resize(enabledLayers.size());
147 
148 	for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
149 		layerPtrs[ndx] = enabledLayers[ndx].c_str();
150 
151 	extensionPtrs.resize(enabledExtensions.size());
152 
153 	for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
154 		extensionPtrs[ndx] = enabledExtensions[ndx].c_str();
155 
156 	queueInfo.sType							= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
157 	queueInfo.pNext							= DE_NULL;
158 	queueInfo.flags							= (VkDeviceQueueCreateFlags)0u;
159 	queueInfo.queueFamilyIndex				= queueIndex;
160 	queueInfo.queueCount					= 1u;
161 	queueInfo.pQueuePriorities				= &queuePriority;
162 
163 	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
164 	deviceInfo.pNext						= DE_NULL;
165 	deviceInfo.queueCreateInfoCount			= 1u;
166 	deviceInfo.pQueueCreateInfos			= &queueInfo;
167 	deviceInfo.enabledExtensionCount		= (deUint32)extensionPtrs.size();
168 	deviceInfo.ppEnabledExtensionNames		= (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
169 	deviceInfo.enabledLayerCount			= (deUint32)layerPtrs.size();
170 	deviceInfo.ppEnabledLayerNames			= (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
171 	deviceInfo.pEnabledFeatures				= &enabledFeatures;
172 
173 	return createDevice(vki, physicalDevice, &deviceInfo);
174 };
175 
176 class DefaultDevice
177 {
178 public:
179 										DefaultDevice					(const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
180 										~DefaultDevice					(void);
181 
getInstance(void) const182 	VkInstance							getInstance						(void) const	{ return *m_instance;					}
getInstanceInterface(void) const183 	const InstanceInterface&			getInstanceInterface			(void) const	{ return m_instanceInterface;			}
184 
getPhysicalDevice(void) const185 	VkPhysicalDevice					getPhysicalDevice				(void) const	{ return m_physicalDevice;				}
getDeviceFeatures(void) const186 	const VkPhysicalDeviceFeatures&		getDeviceFeatures				(void) const	{ return m_deviceFeatures;				}
getDevice(void) const187 	VkDevice							getDevice						(void) const	{ return *m_device;						}
getDeviceInterface(void) const188 	const DeviceInterface&				getDeviceInterface				(void) const	{ return m_deviceInterface;				}
getDeviceProperties(void) const189 	const VkPhysicalDeviceProperties&	getDeviceProperties				(void) const	{ return m_deviceProperties;			}
getDeviceExtensions(void) const190 	const vector<string>&				getDeviceExtensions				(void) const	{ return m_deviceExtensions;			}
191 
getUniversalQueueFamilyIndex(void) const192 	deUint32							getUniversalQueueFamilyIndex	(void) const	{ return m_universalQueueFamilyIndex;	}
193 	VkQueue								getUniversalQueue				(void) const;
194 
195 private:
196 	static VkPhysicalDeviceFeatures		filterDefaultDeviceFeatures		(const VkPhysicalDeviceFeatures& deviceFeatures);
197 	static vector<string>				filterDefaultDeviceExtensions	(const vector<VkExtensionProperties>& deviceExtensions);
198 
199 	const Unique<VkInstance>			m_instance;
200 	const InstanceDriver				m_instanceInterface;
201 
202 	const VkPhysicalDevice				m_physicalDevice;
203 
204 	const deUint32						m_universalQueueFamilyIndex;
205 	const VkPhysicalDeviceFeatures		m_deviceFeatures;
206 	const VkPhysicalDeviceProperties	m_deviceProperties;
207 	const vector<string>				m_deviceExtensions;
208 
209 	const Unique<VkDevice>				m_device;
210 	const DeviceDriver					m_deviceInterface;
211 };
212 
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine)213 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
214 	: m_instance					(createInstance(vkPlatform, cmdLine))
215 	, m_instanceInterface			(vkPlatform, *m_instance)
216 	, m_physicalDevice				(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
217 	, m_universalQueueFamilyIndex	(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
218 	, m_deviceFeatures				(filterDefaultDeviceFeatures(getPhysicalDeviceFeatures(m_instanceInterface, m_physicalDevice)))
219 	, m_deviceProperties			(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
220 	, m_deviceExtensions			(filterDefaultDeviceExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)))
221 	, m_device						(createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_deviceFeatures, m_deviceExtensions, cmdLine))
222 	, m_deviceInterface				(m_instanceInterface, *m_device)
223 {
224 }
225 
~DefaultDevice(void)226 DefaultDevice::~DefaultDevice (void)
227 {
228 }
229 
getUniversalQueue(void) const230 VkQueue DefaultDevice::getUniversalQueue (void) const
231 {
232 	VkQueue	queue	= 0;
233 	m_deviceInterface.getDeviceQueue(*m_device, m_universalQueueFamilyIndex, 0, &queue);
234 	return queue;
235 }
236 
filterDefaultDeviceFeatures(const VkPhysicalDeviceFeatures & deviceFeatures)237 VkPhysicalDeviceFeatures DefaultDevice::filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures)
238 {
239 	VkPhysicalDeviceFeatures enabledDeviceFeatures = deviceFeatures;
240 
241 	// Disable robustness by default, as it has an impact on performance on some HW.
242 	enabledDeviceFeatures.robustBufferAccess = false;
243 
244 	return enabledDeviceFeatures;
245 }
246 
filterDefaultDeviceExtensions(const vector<VkExtensionProperties> & deviceExtensions)247 vector<string> DefaultDevice::filterDefaultDeviceExtensions (const vector<VkExtensionProperties>& deviceExtensions)
248 {
249 	vector<string> enabledExtensions;
250 
251 	// The only extension we enable always (when supported) is
252 	// VK_KHR_sampler_mirror_clamp_to_edge that is defined in
253 	// the core spec and supported widely.
254 	const char* const	mirrorClampToEdgeExt	= "VK_KHR_sampler_mirror_clamp_to_edge";
255 	if (vk::isExtensionSupported(deviceExtensions, vk::RequiredExtension(mirrorClampToEdgeExt)))
256 		enabledExtensions.push_back(mirrorClampToEdgeExt);
257 
258 	return enabledExtensions;
259 }
260 
261 // Allocator utilities
262 
createAllocator(DefaultDevice * device)263 vk::Allocator* createAllocator (DefaultDevice* device)
264 {
265 	const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
266 
267 	// \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
268 	return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
269 }
270 
271 // Context
272 
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::ProgramCollection<vk::ProgramBinary> & progCollection)273 Context::Context (tcu::TestContext&							testCtx,
274 				  const vk::PlatformInterface&				platformInterface,
275 				  vk::ProgramCollection<vk::ProgramBinary>&	progCollection)
276 	: m_testCtx				(testCtx)
277 	, m_platformInterface	(platformInterface)
278 	, m_progCollection		(progCollection)
279 	, m_device				(new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
280 	, m_allocator			(createAllocator(m_device.get()))
281 {
282 }
283 
~Context(void)284 Context::~Context (void)
285 {
286 }
287 
getInstance(void) const288 vk::VkInstance							Context::getInstance					(void) const { return m_device->getInstance();					}
getInstanceInterface(void) const289 const vk::InstanceInterface&			Context::getInstanceInterface			(void) const { return m_device->getInstanceInterface();			}
getPhysicalDevice(void) const290 vk::VkPhysicalDevice					Context::getPhysicalDevice				(void) const { return m_device->getPhysicalDevice();			}
getDeviceFeatures(void) const291 const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures				(void) const { return m_device->getDeviceFeatures();			}
getDeviceProperties(void) const292 const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties			(void) const { return m_device->getDeviceProperties();			}
getDeviceExtensions(void) const293 const vector<string>&					Context::getDeviceExtensions			(void) const { return m_device->getDeviceExtensions();			}
getDevice(void) const294 vk::VkDevice							Context::getDevice						(void) const { return m_device->getDevice();					}
getDeviceInterface(void) const295 const vk::DeviceInterface&				Context::getDeviceInterface				(void) const { return m_device->getDeviceInterface();			}
getUniversalQueueFamilyIndex(void) const296 deUint32								Context::getUniversalQueueFamilyIndex	(void) const { return m_device->getUniversalQueueFamilyIndex();	}
getUniversalQueue(void) const297 vk::VkQueue								Context::getUniversalQueue				(void) const { return m_device->getUniversalQueue();			}
getDefaultAllocator(void) const298 vk::Allocator&							Context::getDefaultAllocator			(void) const { return *m_allocator;								}
299 
300 // TestCase
301 
initPrograms(SourceCollections &) const302 void TestCase::initPrograms (SourceCollections&) const
303 {
304 }
305 
306 } // vkt
307