• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Valve Corporation.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Auxiliar functions to help create custom devices and instances.
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vkRefUtil.hpp"
26 #include "vkQueryUtil.hpp"
27 #include "vkDeviceUtil.hpp"
28 #include "vkDebugReportUtil.hpp"
29 #include "vkMemUtil.hpp"
30 #include "tcuCommandLine.hpp"
31 #include "vktCustomInstancesDevices.hpp"
32 
33 #include <algorithm>
34 #include <memory>
35 #include <set>
36 
37 using std::vector;
38 using std::string;
39 using vk::Move;
40 using vk::VkInstance;
41 #ifndef CTS_USES_VULKANSC
42 using vk::InstanceDriver;
43 using vk::DebugReportRecorder;
44 using vk::VkDebugReportCallbackCreateInfoEXT;
45 using vk::VkDebugReportCallbackEXT;
46 #else
47 using vk::InstanceDriverSC;
48 #endif // CTS_USES_VULKANSC
49 
50 namespace vkt
51 {
52 
53 namespace
54 {
55 
getValidationLayers(const vector<vk::VkLayerProperties> & supportedLayers)56 vector<const char*> getValidationLayers (const vector<vk::VkLayerProperties>& supportedLayers)
57 {
58 	static const char*	s_magicLayer		= "VK_LAYER_KHRONOS_validation";
59 	static const char*	s_defaultLayers[]	=
60 	{
61 		"VK_LAYER_LUNARG_standard_validation",		// Deprecated by at least Vulkan SDK 1.1.121.
62 		"VK_LAYER_GOOGLE_threading",				// Deprecated by at least Vulkan SDK 1.1.121.
63 		"VK_LAYER_LUNARG_parameter_validation",		// Deprecated by at least Vulkan SDK 1.1.121.
64 		"VK_LAYER_LUNARG_device_limits",
65 		"VK_LAYER_LUNARG_object_tracker",			// Deprecated by at least Vulkan SDK 1.1.121.
66 		"VK_LAYER_LUNARG_image",
67 		"VK_LAYER_LUNARG_core_validation",			// Deprecated by at least Vulkan SDK 1.1.121.
68 		"VK_LAYER_LUNARG_swapchain",
69 		"VK_LAYER_GOOGLE_unique_objects"			// Deprecated by at least Vulkan SDK 1.1.121.
70 	};
71 
72 	vector<const char*>	enabledLayers;
73 
74 	if (vk::isLayerSupported(supportedLayers, vk::RequiredLayer(s_magicLayer)))
75 		enabledLayers.push_back(s_magicLayer);
76 	else
77 	{
78 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx)
79 		{
80 			if (isLayerSupported(supportedLayers, vk::RequiredLayer(s_defaultLayers[ndx])))
81 				enabledLayers.push_back(s_defaultLayers[ndx]);
82 		}
83 	}
84 
85 	return enabledLayers;
86 }
87 
88 } // anonymous
89 
90 
getValidationLayers(const vk::PlatformInterface & vkp)91 vector<const char*> getValidationLayers (const vk::PlatformInterface& vkp)
92 {
93 	return getValidationLayers(enumerateInstanceLayerProperties(vkp));
94 }
95 
getValidationLayers(const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice)96 vector<const char*> getValidationLayers (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice)
97 {
98 	return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice));
99 }
100 
101 #ifndef CTS_USES_VULKANSC
CustomInstance(Context & context,Move<VkInstance> instance,std::unique_ptr<vk::DebugReportRecorder> & recorder)102 CustomInstance::CustomInstance(Context& context, Move<VkInstance> instance, std::unique_ptr<vk::DebugReportRecorder>& recorder)
103 #else
104 CustomInstance::CustomInstance(Context& context, Move<VkInstance> instance)
105 #endif // CTS_USES_VULKANSC
106 	: m_context		(&context)
107 #ifndef CTS_USES_VULKANSC
108 	, m_recorder	(recorder.release())
109 #endif // CTS_USES_VULKANSC
110 	, m_instance	(instance)
111 #ifndef CTS_USES_VULKANSC
112 	, m_driver		(new InstanceDriver(context.getPlatformInterface(), *m_instance))
113 	, m_callback	(m_recorder ? m_recorder->createCallback(*m_driver, *m_instance) : Move<VkDebugReportCallbackEXT>())
114 #else
115 	, m_driver		(new InstanceDriverSC(context.getPlatformInterface(), *m_instance, context.getTestContext().getCommandLine(), context.getResourceInterface()))
116 #endif // CTS_USES_VULKANSC
117 {
118 }
119 
CustomInstance()120 CustomInstance::CustomInstance ()
121 	: m_context		(nullptr)
122 #ifndef CTS_USES_VULKANSC
123 	, m_recorder	(nullptr)
124 #endif // CTS_USES_VULKANSC
125 	, m_instance	()
126 	, m_driver		(nullptr)
127 #ifndef CTS_USES_VULKANSC
128 	, m_callback	()
129 #endif // CTS_USES_VULKANSC
130 {
131 }
132 
CustomInstance(CustomInstance && other)133 CustomInstance::CustomInstance (CustomInstance&& other)
134 	: CustomInstance()
135 {
136 	this->swap(other);
137 }
138 
~CustomInstance()139 CustomInstance::~CustomInstance ()
140 {
141 	collectMessages();
142 }
143 
operator =(CustomInstance && other)144 CustomInstance&	CustomInstance::operator= (CustomInstance&& other)
145 {
146 	CustomInstance destroyer;
147 	destroyer.swap(other);
148 	this->swap(destroyer);
149 	return *this;
150 }
151 
swap(CustomInstance & other)152 void CustomInstance::swap (CustomInstance& other)
153 {
154 	std::swap(m_context, other.m_context);
155 #ifndef CTS_USES_VULKANSC
156 	m_recorder.swap(other.m_recorder);
157 #endif // CTS_USES_VULKANSC
158 	Move<VkInstance> aux = m_instance; m_instance = other.m_instance; other.m_instance = aux;
159 	m_driver.swap(other.m_driver);
160 #ifndef CTS_USES_VULKANSC
161 	Move<VkDebugReportCallbackEXT> aux2 = m_callback; m_callback = other.m_callback; other.m_callback = aux2;
162 #endif // CTS_USES_VULKANSC
163 }
164 
operator VkInstance() const165 CustomInstance::operator VkInstance () const
166 {
167 	return *m_instance;
168 }
169 
getDriver() const170 const vk::InstanceDriver& CustomInstance::getDriver() const
171 {
172 	return *m_driver;
173 }
174 
collectMessages()175 void CustomInstance::collectMessages ()
176 {
177 #ifndef CTS_USES_VULKANSC
178 	if (m_recorder)
179 		collectAndReportDebugMessages(*m_recorder, *m_context);
180 #endif // CTS_USES_VULKANSC
181 }
182 
UncheckedInstance()183 UncheckedInstance::UncheckedInstance ()
184 	: m_context		(nullptr)
185 #ifndef CTS_USES_VULKANSC
186 	, m_recorder	(nullptr)
187 #endif // CTS_USES_VULKANSC
188 	, m_allocator	(nullptr)
189 	, m_instance	(DE_NULL)
190 	, m_driver		(nullptr)
191 #ifndef CTS_USES_VULKANSC
192 	, m_callback	()
193 #endif // CTS_USES_VULKANSC
194 {
195 }
196 
197 #ifndef CTS_USES_VULKANSC
UncheckedInstance(Context & context,vk::VkInstance instance,const vk::VkAllocationCallbacks * pAllocator,std::unique_ptr<DebugReportRecorder> & recorder)198 UncheckedInstance::UncheckedInstance (Context& context, vk::VkInstance instance, const vk::VkAllocationCallbacks* pAllocator, std::unique_ptr<DebugReportRecorder>& recorder)
199 #else
200 UncheckedInstance::UncheckedInstance(Context& context, vk::VkInstance instance, const vk::VkAllocationCallbacks* pAllocator)
201 #endif // CTS_USES_VULKANSC
202 
203 	: m_context		(&context)
204 #ifndef CTS_USES_VULKANSC
205 	, m_recorder	(recorder.release())
206 #endif // CTS_USES_VULKANSC
207 	, m_allocator	(pAllocator)
208 	, m_instance	(instance)
209 #ifndef CTS_USES_VULKANSC
210 	, m_driver((m_instance != DE_NULL) ? new InstanceDriver(context.getPlatformInterface(), m_instance) : nullptr)
211 	, m_callback	((m_driver && m_recorder) ? m_recorder->createCallback(*m_driver, m_instance) : Move<VkDebugReportCallbackEXT>())
212 #else
213 	, m_driver((m_instance != DE_NULL) ? new InstanceDriverSC(context.getPlatformInterface(), m_instance, context.getTestContext().getCommandLine(), context.getResourceInterface()) : nullptr)
214 #endif // CTS_USES_VULKANSC
215 {
216 }
217 
~UncheckedInstance()218 UncheckedInstance::~UncheckedInstance ()
219 {
220 #ifndef CTS_USES_VULKANSC
221 	if (m_recorder)
222 		collectAndReportDebugMessages(*m_recorder, *m_context);
223 #endif // CTS_USES_VULKANSC
224 
225 	if (m_instance != DE_NULL)
226 	{
227 #ifndef CTS_USES_VULKANSC
228 		m_callback.~Move<vk::VkDebugReportCallbackEXT>();
229 		m_recorder.reset(nullptr);
230 #endif // CTS_USES_VULKANSC
231 		m_driver->destroyInstance(m_instance, m_allocator);
232 	}
233 }
234 
swap(UncheckedInstance & other)235 void UncheckedInstance::swap (UncheckedInstance& other)
236 {
237 	std::swap(m_context, other.m_context);
238 #ifndef CTS_USES_VULKANSC
239 	m_recorder.swap(other.m_recorder);
240 #endif // CTS_USES_VULKANSC
241 	std::swap(m_allocator, other.m_allocator);
242 	vk::VkInstance aux = m_instance; m_instance = other.m_instance; other.m_instance = aux;
243 	m_driver.swap(other.m_driver);
244 #ifndef CTS_USES_VULKANSC
245 	Move<VkDebugReportCallbackEXT> aux2 = m_callback; m_callback = other.m_callback; other.m_callback = aux2;
246 #endif // CTS_USES_VULKANSC
247 }
248 
UncheckedInstance(UncheckedInstance && other)249 UncheckedInstance::UncheckedInstance (UncheckedInstance&& other)
250 	: UncheckedInstance()
251 {
252 	this->swap(other);
253 }
254 
operator =(UncheckedInstance && other)255 UncheckedInstance& UncheckedInstance::operator= (UncheckedInstance&& other)
256 {
257 	UncheckedInstance destroyer;
258 	destroyer.swap(other);
259 	this->swap(destroyer);
260 	return *this;
261 }
262 
operator vk::VkInstance() const263 UncheckedInstance::operator vk::VkInstance () const
264 {
265 	return m_instance;
266 }
operator bool() const267 UncheckedInstance::operator bool () const
268 {
269 	return (m_instance != DE_NULL);
270 }
271 
createCustomInstanceWithExtensions(Context & context,const std::vector<std::string> & extensions,const vk::VkAllocationCallbacks * pAllocator,bool allowLayers)272 CustomInstance createCustomInstanceWithExtensions (Context& context, const std::vector<std::string>& extensions, const vk::VkAllocationCallbacks* pAllocator, bool allowLayers)
273 {
274 	vector<const char*>	enabledLayers;
275 	vector<string>		enabledLayersStr;
276 	const auto&			cmdLine					= context.getTestContext().getCommandLine();
277 	const bool			validationRequested		= (cmdLine.isValidationEnabled() && allowLayers);
278 #ifndef CTS_USES_VULKANSC
279 	const bool			printValidationErrors	= cmdLine.printValidationErrors();
280 #endif // CTS_USES_VULKANSC
281 
282 	if (validationRequested)
283 	{
284 		enabledLayers = getValidationLayers(context.getPlatformInterface());
285 		enabledLayersStr = vector<string>(begin(enabledLayers), end(enabledLayers));
286 	}
287 
288 	const bool validationEnabled = !enabledLayers.empty();
289 
290 	// Filter extension list and throw NotSupported if a required extension is not supported.
291 	const deUint32									apiVersion			= context.getUsedApiVersion();
292 	const vk::PlatformInterface&					vkp					= context.getPlatformInterface();
293 	const vector<vk::VkExtensionProperties>			availableExtensions	= vk::enumerateInstanceExtensionProperties(vkp, DE_NULL);
294 	std::set<string>								usedExtensions;
295 
296 	// Get list of available extension names.
297 	vector<string> availableExtensionNames;
298 	for (const auto& ext : availableExtensions)
299 		availableExtensionNames.push_back(ext.extensionName);
300 
301 	// Filter duplicates and remove core extensions.
302 	for (const auto& ext : extensions)
303 	{
304 		if (!vk::isCoreInstanceExtension(apiVersion, ext))
305 			usedExtensions.insert(ext);
306 	}
307 
308 	// Add debug extension if validation is enabled.
309 	if (validationEnabled)
310 		usedExtensions.insert("VK_EXT_debug_report");
311 
312 	// Check extension support.
313 	for (const auto& ext : usedExtensions)
314 	{
315 		if (!vk::isInstanceExtensionSupported(apiVersion, availableExtensionNames, ext))
316 			TCU_THROW(NotSupportedError, ext + " is not supported");
317 	}
318 
319 #ifndef CTS_USES_VULKANSC
320 	std::unique_ptr<DebugReportRecorder> debugReportRecorder;
321 	if (validationEnabled)
322 		debugReportRecorder.reset(new DebugReportRecorder(printValidationErrors));
323 #endif // CTS_USES_VULKANSC
324 
325 	// Create custom instance.
326 	const vector<string> usedExtensionsVec(begin(usedExtensions), end(usedExtensions));
327 #ifndef CTS_USES_VULKANSC
328 	Move<VkInstance> instance = vk::createDefaultInstance(vkp, apiVersion, enabledLayersStr, usedExtensionsVec, cmdLine, debugReportRecorder.get(), pAllocator);
329 	return CustomInstance(context, instance, debugReportRecorder);
330 #else
331 	Move<VkInstance> instance = vk::createDefaultInstance(vkp, apiVersion, enabledLayersStr, usedExtensionsVec, cmdLine, pAllocator);
332 	return CustomInstance(context, instance);
333 #endif // CTS_USES_VULKANSC
334 }
335 
createCustomInstanceWithExtension(Context & context,const std::string & extension,const vk::VkAllocationCallbacks * pAllocator,bool allowLayers)336 CustomInstance createCustomInstanceWithExtension (Context& context, const std::string& extension, const vk::VkAllocationCallbacks* pAllocator, bool allowLayers)
337 {
338 	return createCustomInstanceWithExtensions(context, std::vector<std::string>(1, extension), pAllocator, allowLayers);
339 }
340 
createCustomInstanceFromContext(Context & context,const vk::VkAllocationCallbacks * pAllocator,bool allowLayers)341 CustomInstance createCustomInstanceFromContext (Context& context, const vk::VkAllocationCallbacks* pAllocator, bool allowLayers)
342 {
343 	return createCustomInstanceWithExtensions(context, std::vector<std::string>(), pAllocator, allowLayers);
344 }
345 
346 const char kDebugReportExt[] = "VK_EXT_debug_report";
347 
addDebugReportExt(const vk::PlatformInterface & vkp,const vk::VkInstanceCreateInfo & createInfo)348 vector<const char*> addDebugReportExt(const vk::PlatformInterface& vkp, const vk::VkInstanceCreateInfo& createInfo)
349 {
350 	if (!isDebugReportSupported(vkp))
351 		TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
352 
353 	vector<const char*> actualExtensions;
354 	if (createInfo.enabledExtensionCount != 0u)
355 	{
356 		for (deUint32 i = 0u; i < createInfo.enabledExtensionCount; ++i)
357 			actualExtensions.push_back(createInfo.ppEnabledExtensionNames[i]);
358 	}
359 
360 	if (std::find_if(begin(actualExtensions), end(actualExtensions), [](const char* name) { return (strcmp(name, kDebugReportExt) == 0); })
361 		== end(actualExtensions))
362 	{
363 		actualExtensions.push_back(kDebugReportExt);
364 	}
365 
366 	return actualExtensions;
367 }
368 
createCustomInstanceFromInfo(Context & context,const vk::VkInstanceCreateInfo * instanceCreateInfo,const vk::VkAllocationCallbacks * pAllocator,bool allowLayers)369 CustomInstance createCustomInstanceFromInfo (Context& context, const vk::VkInstanceCreateInfo* instanceCreateInfo, const vk::VkAllocationCallbacks* pAllocator, bool allowLayers)
370 {
371 	vector<const char*>						enabledLayers;
372 	vector<const char*>						enabledExtensions;
373 	vk::VkInstanceCreateInfo				createInfo				= *instanceCreateInfo;
374 	const auto&								cmdLine					= context.getTestContext().getCommandLine();
375 	const bool								validationEnabled		= cmdLine.isValidationEnabled();
376 #ifndef CTS_USES_VULKANSC
377 	const bool								printValidationErrors	= cmdLine.printValidationErrors();
378 #endif // CTS_USES_VULKANSC
379 	const vk::PlatformInterface&			vkp						= context.getPlatformInterface();
380 #ifndef CTS_USES_VULKANSC
381 	std::unique_ptr<DebugReportRecorder>	recorder;
382 	VkDebugReportCallbackCreateInfoEXT		callbackInfo;
383 #endif // CTS_USES_VULKANSC
384 
385 	if (validationEnabled && allowLayers)
386 	{
387 		// Activate some layers if requested.
388 		if (createInfo.enabledLayerCount == 0u)
389 		{
390 			enabledLayers = getValidationLayers(vkp);
391 			createInfo.enabledLayerCount = static_cast<deUint32>(enabledLayers.size());
392 			createInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
393 		}
394 
395 		// Make sure the debug report extension is enabled when validation is enabled.
396 		enabledExtensions = addDebugReportExt(vkp, createInfo);
397 		createInfo.enabledExtensionCount = static_cast<deUint32>(enabledExtensions.size());
398 		createInfo.ppEnabledExtensionNames = enabledExtensions.data();
399 
400 #ifndef CTS_USES_VULKANSC
401 		recorder.reset(new DebugReportRecorder(printValidationErrors));
402 		callbackInfo		= recorder->makeCreateInfo();
403 		callbackInfo.pNext	= createInfo.pNext;
404 		createInfo.pNext	= &callbackInfo;
405 #endif // CTS_USES_VULKANSC
406 	}
407 
408 #ifndef CTS_USES_VULKANSC
409 	return CustomInstance(context, vk::createInstance(vkp, &createInfo, pAllocator), recorder);
410 #else
411 	return CustomInstance(context, vk::createInstance(vkp, &createInfo, pAllocator));
412 #endif // CTS_USES_VULKANSC
413 }
414 
createUncheckedInstance(Context & context,const vk::VkInstanceCreateInfo * instanceCreateInfo,const vk::VkAllocationCallbacks * pAllocator,UncheckedInstance * instance,bool allowLayers)415 vk::VkResult createUncheckedInstance (Context& context, const vk::VkInstanceCreateInfo* instanceCreateInfo, const vk::VkAllocationCallbacks* pAllocator, UncheckedInstance* instance, bool allowLayers)
416 {
417 	vector<const char*>						enabledLayers;
418 	vector<const char*>						enabledExtensions;
419 	vk::VkInstanceCreateInfo				createInfo				= *instanceCreateInfo;
420 	const auto&								cmdLine					= context.getTestContext().getCommandLine();
421 	const bool								validationEnabled		= cmdLine.isValidationEnabled();
422 #ifndef CTS_USES_VULKANSC
423 	const bool								printValidationErrors	= cmdLine.printValidationErrors();
424 #endif // CTS_USES_VULKANSC
425 	const vk::PlatformInterface&			vkp						= context.getPlatformInterface();
426 	const bool								addLayers				= (validationEnabled && allowLayers);
427 #ifndef CTS_USES_VULKANSC
428 	std::unique_ptr<DebugReportRecorder>	recorder;
429 #endif // CTS_USES_VULKANSC
430 
431 	if (addLayers)
432 	{
433 		// Activate some layers if requested.
434 		if (createInfo.enabledLayerCount == 0u)
435 		{
436 			enabledLayers = getValidationLayers(vkp);
437 			createInfo.enabledLayerCount = static_cast<deUint32>(enabledLayers.size());
438 			createInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
439 		}
440 
441 		// Make sure the debug report extension is enabled when validation is enabled.
442 		enabledExtensions = addDebugReportExt(vkp, createInfo);
443 		createInfo.enabledExtensionCount = static_cast<deUint32>(enabledExtensions.size());
444 		createInfo.ppEnabledExtensionNames = enabledExtensions.data();
445 
446 #ifndef CTS_USES_VULKANSC
447 		recorder.reset(new DebugReportRecorder(printValidationErrors));
448 		// No need to add VkDebugReportCallbackCreateInfoEXT to VkInstanceCreateInfo since we
449 		// don't want to check for errors at instance creation. This is intended since we use
450 		// UncheckedInstance to try to create invalid instances for driver stability
451 #endif // CTS_USES_VULKANSC
452 	}
453 
454 	vk::VkInstance	raw_instance = DE_NULL;
455 	vk::VkResult	result = vkp.createInstance(&createInfo, pAllocator, &raw_instance);
456 
457 #ifndef CTS_USES_VULKANSC
458 	*instance = UncheckedInstance(context, raw_instance, pAllocator, recorder);
459 #else
460 	*instance = UncheckedInstance(context, raw_instance, pAllocator);
461 #endif // CTS_USES_VULKANSC
462 
463 	return result;
464 }
465 
createCustomDevice(bool validationEnabled,const vk::PlatformInterface & vkp,vk::VkInstance instance,const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice,const vk::VkDeviceCreateInfo * pCreateInfo,const vk::VkAllocationCallbacks * pAllocator)466 vk::Move<vk::VkDevice> createCustomDevice (bool validationEnabled, const vk::PlatformInterface& vkp, vk::VkInstance instance, const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, const vk::VkDeviceCreateInfo* pCreateInfo, const vk::VkAllocationCallbacks* pAllocator)
467 {
468 	vector<const char*>		enabledLayers;
469 	vk::VkDeviceCreateInfo	createInfo		= *pCreateInfo;
470 
471 	if (createInfo.enabledLayerCount == 0u && validationEnabled)
472 	{
473 		enabledLayers = getValidationLayers(vki, physicalDevice);
474 		createInfo.enabledLayerCount = static_cast<deUint32>(enabledLayers.size());
475 		createInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
476 	}
477 
478 	return createDevice(vkp, instance, vki, physicalDevice, &createInfo, pAllocator);
479 }
480 
createUncheckedDevice(bool validationEnabled,const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice,const vk::VkDeviceCreateInfo * pCreateInfo,const vk::VkAllocationCallbacks * pAllocator,vk::VkDevice * pDevice)481 vk::VkResult createUncheckedDevice (bool validationEnabled, const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, const vk::VkDeviceCreateInfo* pCreateInfo, const vk::VkAllocationCallbacks* pAllocator, vk::VkDevice* pDevice)
482 {
483 	vector<const char*>		enabledLayers;
484 	vk::VkDeviceCreateInfo	createInfo		= *pCreateInfo;
485 
486 	if (createInfo.enabledLayerCount == 0u && validationEnabled)
487 	{
488 		enabledLayers = getValidationLayers(vki, physicalDevice);
489 		createInfo.enabledLayerCount = static_cast<deUint32>(enabledLayers.size());
490 		createInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
491 	}
492 
493 	return vki.createDevice(physicalDevice, &createInfo, pAllocator, pDevice);
494 }
495 
CustomInstanceWrapper(Context & context)496 CustomInstanceWrapper::CustomInstanceWrapper(Context& context)
497 	: instance(vkt::createCustomInstanceFromContext(context))
498 {
499 }
500 
CustomInstanceWrapper(Context & context,const std::vector<std::string> extensions)501 CustomInstanceWrapper::CustomInstanceWrapper(Context& context, const std::vector<std::string> extensions)
502 	: instance(vkt::createCustomInstanceWithExtensions(context, extensions))
503 {
504 }
checkSupport(Context & context,const VideoCodecOperationFlags videoCodecOperation)505 void VideoDevice::checkSupport (Context&						context,
506 								const VideoCodecOperationFlags	videoCodecOperation)
507 {
508 #ifndef CTS_USES_VULKANSC
509 	DE_ASSERT(videoCodecOperation != 0 && isVideoOperation(videoCodecOperation));
510 
511 	if (isVideoOperation(videoCodecOperation))
512 		context.requireDeviceFunctionality("VK_KHR_video_queue");
513 
514 	if (isVideoEncodeOperation(videoCodecOperation))
515 		context.requireDeviceFunctionality("VK_KHR_video_encode_queue");
516 
517 	if (isVideoDecodeOperation(videoCodecOperation))
518 		context.requireDeviceFunctionality("VK_KHR_video_decode_queue");
519 
520 	if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) != 0)
521 		context.requireDeviceFunctionality("VK_EXT_video_encode_h264");
522 
523 	if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) != 0)
524 		context.requireDeviceFunctionality("VK_EXT_video_encode_h265");
525 
526 	if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) != 0)
527 		context.requireDeviceFunctionality("VK_KHR_video_decode_h264");
528 
529 	if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) != 0)
530 		context.requireDeviceFunctionality("VK_KHR_video_decode_h265");
531 #else
532 	DE_UNREF(context);
533 	DE_UNREF(videoCodecOperation);
534 #endif
535 }
536 
VideoDevice(Context & context)537 VideoDevice::VideoDevice (Context& context)
538 	: m_context				(context)
539 	, m_logicalDevice		()
540 	, m_deviceDriver		()
541 	, m_allocator			()
542 	, m_queueFamilyTransfer	(VK_QUEUE_FAMILY_IGNORED)
543 	, m_queueFamilyDecode	(VK_QUEUE_FAMILY_IGNORED)
544 	, m_queueFamilyEncode	(VK_QUEUE_FAMILY_IGNORED)
545 #ifndef CTS_USES_VULKANSC
546 	, m_videoCodecOperation	(vk::VK_VIDEO_CODEC_OPERATION_NONE_KHR)
547 #else
548 	, m_videoCodecOperation	(~0u)
549 #endif
550 {
551 }
552 
VideoDevice(Context & context,const VideoCodecOperationFlags videoCodecOperation,const VideoDeviceFlags videoDeviceFlags)553 VideoDevice::VideoDevice (Context&							context,
554 						  const VideoCodecOperationFlags	videoCodecOperation,
555 						  const VideoDeviceFlags			videoDeviceFlags)
556 	: VideoDevice	(context)
557 {
558 #ifndef CTS_USES_VULKANSC
559 	const vk::VkQueueFlags	queueFlagsRequired	= getQueueFlags(videoCodecOperation);
560 	const vk::VkDevice		result				= getDeviceSupportingQueue(queueFlagsRequired, videoCodecOperation, videoDeviceFlags);
561 
562 	DE_ASSERT(result != DE_NULL);
563 	DE_UNREF(result);
564 #else
565 	DE_UNREF(videoCodecOperation);
566 	DE_UNREF(videoDeviceFlags);
567 #endif
568 }
569 
~VideoDevice(void)570 VideoDevice::~VideoDevice (void)
571 {
572 }
573 
getQueueFlags(const VideoCodecOperationFlags videoCodecOperation)574 vk::VkQueueFlags VideoDevice::getQueueFlags (const VideoCodecOperationFlags videoCodecOperation)
575 {
576 #ifndef CTS_USES_VULKANSC
577 	const vk::VkQueueFlags	queueFlagsRequired	= (isVideoEncodeOperation(videoCodecOperation) ? vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR : 0)
578 												| (isVideoDecodeOperation(videoCodecOperation) ? vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR : 0);
579 
580 	return queueFlagsRequired;
581 #else
582 	DE_UNREF(videoCodecOperation);
583 
584 	return 0;
585 #endif
586 }
587 
isVideoEncodeOperation(const VideoCodecOperationFlags videoCodecOperationFlags)588 bool VideoDevice::isVideoEncodeOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
589 {
590 #ifndef CTS_USES_VULKANSC
591 	const vk::VkVideoCodecOperationFlagsKHR	encodeOperations	= vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT
592 																| vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT;
593 
594 	return (encodeOperations & videoCodecOperationFlags) != 0;
595 #else
596 	DE_UNREF(videoCodecOperationFlags);
597 
598 	return false;
599 #endif
600 }
601 
isVideoDecodeOperation(const VideoCodecOperationFlags videoCodecOperationFlags)602 bool VideoDevice::isVideoDecodeOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
603 {
604 #ifndef CTS_USES_VULKANSC
605 	const vk::VkVideoCodecOperationFlagsKHR	decodeOperations	= vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR
606 																| vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR;
607 
608 	return (decodeOperations & videoCodecOperationFlags) != 0;
609 #else
610 	DE_UNREF(videoCodecOperationFlags);
611 
612 	return false;
613 #endif
614 }
615 
isVideoOperation(const VideoCodecOperationFlags videoCodecOperationFlags)616 bool VideoDevice::isVideoOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
617 {
618 #ifndef CTS_USES_VULKANSC
619 	return isVideoDecodeOperation(videoCodecOperationFlags) || isVideoEncodeOperation(videoCodecOperationFlags);
620 #else
621 	DE_UNREF(videoCodecOperationFlags);
622 
623 	return false;
624 #endif
625 }
626 
addVideoDeviceExtensions(std::vector<const char * > & deviceExtensions,const uint32_t apiVersion,const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags)627 void VideoDevice::addVideoDeviceExtensions (std::vector<const char*>&		deviceExtensions,
628 											const uint32_t					apiVersion,
629 											const vk::VkQueueFlags			queueFlagsRequired,
630 											const VideoCodecOperationFlags	videoCodecOperationFlags)
631 {
632 #ifndef CTS_USES_VULKANSC
633 	static const char videoQueue[]			= "VK_KHR_video_queue";
634 	static const char videoEncodeQueue[]	= "VK_KHR_video_encode_queue";
635 	static const char videoDecodeQueue[]	= "VK_KHR_video_decode_queue";
636 	static const char videoEncodeH264[]		= "VK_EXT_video_encode_h264";
637 	static const char videoEncodeH265[]		= "VK_EXT_video_encode_h265";
638 	static const char videoDecodeH264[]		= "VK_KHR_video_decode_h264";
639 	static const char videoDecodeH265[]		= "VK_KHR_video_decode_h265";
640 
641 	if (!vk::isCoreDeviceExtension(apiVersion, videoQueue))
642 		deviceExtensions.push_back(videoQueue);
643 
644 	if ((queueFlagsRequired & vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR) != 0)
645 		if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeQueue))
646 			deviceExtensions.push_back(videoEncodeQueue);
647 
648 	if ((queueFlagsRequired & vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR) != 0)
649 		if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeQueue))
650 			deviceExtensions.push_back(videoDecodeQueue);
651 
652 	if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) != 0)
653 		if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeH264))
654 			deviceExtensions.push_back(videoEncodeH264);
655 
656 	if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) != 0)
657 		if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeH265))
658 			deviceExtensions.push_back(videoEncodeH265);
659 
660 	if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) != 0)
661 		if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeH265))
662 			deviceExtensions.push_back(videoDecodeH265);
663 
664 	if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) != 0)
665 		if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeH264))
666 			deviceExtensions.push_back(videoDecodeH264);
667 #else
668 	DE_UNREF(deviceExtensions);
669 	DE_UNREF(apiVersion);
670 	DE_UNREF(queueFlagsRequired);
671 	DE_UNREF(videoCodecOperationFlags);
672 #endif
673 }
674 
getDeviceSupportingQueue(const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags,const VideoDevice::VideoDeviceFlags videoDeviceFlags)675 vk::VkDevice VideoDevice::getDeviceSupportingQueue (const vk::VkQueueFlags					queueFlagsRequired,
676 													const VideoCodecOperationFlags			videoCodecOperationFlags,
677 													const VideoDevice::VideoDeviceFlags		videoDeviceFlags)
678 {
679 #ifndef CTS_USES_VULKANSC
680 	if (*m_logicalDevice == DE_NULL)
681 	{
682 		DE_ASSERT(static_cast<deUint32>(queueFlagsRequired) != 0u);
683 		DE_ASSERT(static_cast<deUint32>(videoCodecOperationFlags) != 0u);
684 
685 		if (!createDeviceSupportingQueue(queueFlagsRequired, videoCodecOperationFlags, videoDeviceFlags))
686 			TCU_THROW(NotSupportedError, "Cannot create device with required parameters");
687 	}
688 
689 	return *m_logicalDevice;
690 #else
691 	DE_UNREF(queueFlagsRequired);
692 	DE_UNREF(videoCodecOperationFlags);
693 	DE_UNREF(videoDeviceFlags);
694 
695 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
696 #endif
697 }
698 
createDeviceSupportingQueue(const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags,const VideoDeviceFlags videoDeviceFlags)699 bool VideoDevice::createDeviceSupportingQueue (const vk::VkQueueFlags			queueFlagsRequired,
700 											   const VideoCodecOperationFlags	videoCodecOperationFlags,
701 											   const VideoDeviceFlags			videoDeviceFlags)
702 {
703 #ifndef CTS_USES_VULKANSC
704 	const vk::PlatformInterface&								vkp											= m_context.getPlatformInterface();
705 	const vk::InstanceInterface&								vki											= m_context.getInstanceInterface();
706 	const vk::VkPhysicalDevice									physicalDevice								= m_context.getPhysicalDevice();
707 	const vk::VkInstance										instance									= m_context.getInstance();
708 	const deUint32												apiVersion									= m_context.getUsedApiVersion();
709 	const bool													validationEnabled							= m_context.getTestContext().getCommandLine().isValidationEnabled();
710 	const bool													queryWithStatusForDecodeSupport				= (videoDeviceFlags & VIDEO_DEVICE_FLAG_QUERY_WITH_STATUS_FOR_DECODE_SUPPORT) != 0;
711 	const bool													requireYCBCRorNotSupported					= (videoDeviceFlags & VIDEO_DEVICE_FLAG_REQUIRE_YCBCR_OR_NOT_SUPPORTED) != 0;
712 	const bool													requireSync2orNotSupported					= (videoDeviceFlags & VIDEO_DEVICE_FLAG_REQUIRE_SYNC2_OR_NOT_SUPPORTED) != 0;
713 	const float													queueFamilyPriority							= 1.0f;
714 	deUint32													queueFamilyPropertiesCount					= 0u;
715 	deUint32													queueFamilyTransfer							= VK_QUEUE_FAMILY_IGNORED;
716 	deUint32													queueFamilyDecode							= VK_QUEUE_FAMILY_IGNORED;
717 	deUint32													queueFamilyEncode							= VK_QUEUE_FAMILY_IGNORED;
718 	vk::VkQueueFlags											queueFlagsFound								= 0;
719 	vector<vk::VkQueueFamilyProperties2>						queueFamilyProperties2;
720 	vector<vk::VkQueueFamilyVideoPropertiesKHR>				videoQueueFamilyProperties2;
721 	vector<vk::VkQueueFamilyQueryResultStatusPropertiesKHR>	VkQueueFamilyQueryResultStatusPropertiesKHR;
722 	vector<const char*>											deviceExtensions;
723 	vector<vk::VkDeviceQueueCreateInfo>							queueInfos;
724 
725 	DE_ASSERT(queueFlagsRequired != 0);
726 	DE_ASSERT(videoCodecOperationFlags != 0);
727 
728 	vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
729 
730 	if(queueFamilyPropertiesCount == 0u)
731 		TCU_FAIL("Device reports an empty set of queue family properties");
732 
733 	queueFamilyProperties2.resize(queueFamilyPropertiesCount);
734 	videoQueueFamilyProperties2.resize(queueFamilyPropertiesCount);
735 	VkQueueFamilyQueryResultStatusPropertiesKHR.resize(queueFamilyPropertiesCount);
736 
737 	for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
738 	{
739 		queueFamilyProperties2[ndx].sType											= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
740 		queueFamilyProperties2[ndx].pNext											= &videoQueueFamilyProperties2[ndx];
741 		videoQueueFamilyProperties2[ndx].sType										= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
742 		videoQueueFamilyProperties2[ndx].pNext										= &VkQueueFamilyQueryResultStatusPropertiesKHR[ndx];
743 		videoQueueFamilyProperties2[ndx].videoCodecOperations						= 0;
744 		VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].sType						= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR;
745 		VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].pNext						= DE_NULL;
746 		VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].queryResultStatusSupport	= DE_FALSE;
747 	}
748 
749 	vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties2.data());
750 
751 	if (queueFamilyPropertiesCount != queueFamilyProperties2.size())
752 		TCU_FAIL("Device returns less queue families than initially reported");
753 
754 	for (uint32_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
755 	{
756 		const vk::VkQueueFamilyProperties&	queueFamilyProperties	= queueFamilyProperties2[ndx].queueFamilyProperties;
757 		const vk::VkQueueFlags				usefulQueueFlags		= queueFamilyProperties.queueFlags & queueFlagsRequired & ~queueFlagsFound;
758 
759 		if (usefulQueueFlags != 0)
760 		{
761 			bool	assigned	= false;
762 
763 			if ((usefulQueueFlags & vk::VK_QUEUE_TRANSFER_BIT) != 0 && queueFamilyTransfer == VK_QUEUE_FAMILY_IGNORED)
764 			{
765 				queueFamilyTransfer	= ndx;
766 				assigned			= true;
767 			}
768 
769 			if ((videoQueueFamilyProperties2[ndx].videoCodecOperations & videoCodecOperationFlags) != 0)
770 			{
771 				if ((usefulQueueFlags & vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR) != 0 && queueFamilyDecode == VK_QUEUE_FAMILY_IGNORED)
772 				{
773 					if (!queryWithStatusForDecodeSupport || (queryWithStatusForDecodeSupport && VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].queryResultStatusSupport))
774 					{
775 						queueFamilyDecode	= ndx;
776 						assigned			= true;
777 					}
778 				}
779 
780 				if ((usefulQueueFlags & vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR) != 0 && queueFamilyEncode == VK_QUEUE_FAMILY_IGNORED)
781 				{
782 					queueFamilyEncode	= ndx;
783 					assigned			= true;
784 				}
785 			}
786 
787 			if (assigned)
788 			{
789 				const vk::VkDeviceQueueCreateInfo	queueInfo =
790 				{
791 					vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//  VkStructureType				sType;
792 					DE_NULL,										//  const void*					pNext;
793 					(vk::VkDeviceQueueCreateFlags)0u,				//  VkDeviceQueueCreateFlags	flags;
794 					ndx,											//  deUint32					queueFamilyIndex;
795 					1u,												//  deUint32					queueCount;
796 					&queueFamilyPriority,							//  const float*				pQueuePriorities;
797 				};
798 
799 				if (queueFamilyProperties.queueCount == 0)
800 					TCU_FAIL("Video queue returned queueCount is zero");
801 
802 				queueInfos.push_back(queueInfo);
803 
804 				queueFlagsFound |= usefulQueueFlags;
805 
806 				if (queueFlagsFound == queueFlagsRequired)
807 					break;
808 			}
809 		}
810 	}
811 
812 	if (queueFlagsFound != queueFlagsRequired)
813 		return false;
814 
815 	addVideoDeviceExtensions(deviceExtensions, apiVersion, queueFlagsRequired, videoCodecOperationFlags);
816 
817 	if (requireYCBCRorNotSupported)
818 		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_sampler_ycbcr_conversion"))
819 			deviceExtensions.push_back("VK_KHR_sampler_ycbcr_conversion");
820 
821 	if (requireSync2orNotSupported)
822 		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_synchronization2"))
823 			deviceExtensions.push_back("VK_KHR_synchronization2");
824 
825 	vk::VkPhysicalDeviceSynchronization2FeaturesKHR		synchronization2Features		=
826 	{
827 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR,	//  VkStructureType	sType;
828 		DE_NULL,																//  void*			pNext;
829 		DE_FALSE,																//  VkBool32		synchronization2;
830 	};
831 	vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures	samplerYcbcrConversionFeatures	=
832 	{
833 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,	//  VkStructureType	sType;
834 		DE_NULL,																	//  void*			pNext;
835 		DE_FALSE,																	//  VkBool32		samplerYcbcrConversion;
836 	};
837 	vk::VkPhysicalDeviceFeatures2						features2						=
838 	{
839 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,	//  VkStructureType				sType;
840 		DE_NULL,											//  void*						pNext;
841 		vk::VkPhysicalDeviceFeatures(),						//  VkPhysicalDeviceFeatures	features;
842 	};
843 
844 	if (requireYCBCRorNotSupported)
845 		appendStructurePtrToVulkanChain((const void**)&features2.pNext, &samplerYcbcrConversionFeatures);
846 
847 	if (requireSync2orNotSupported)
848 		appendStructurePtrToVulkanChain((const void**)&features2.pNext, &synchronization2Features);
849 
850 	vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
851 
852 	if (requireYCBCRorNotSupported && samplerYcbcrConversionFeatures.samplerYcbcrConversion == DE_FALSE)
853 		TCU_THROW(NotSupportedError, "samplerYcbcrConversionFeatures.samplerYcbcrConversion is required");
854 
855 	if (requireSync2orNotSupported && synchronization2Features.synchronization2 == DE_FALSE)
856 		TCU_THROW(NotSupportedError, "synchronization2Features.synchronization2 is required");
857 
858 	features2.features.robustBufferAccess = DE_FALSE;
859 
860 	const vk::VkDeviceCreateInfo						deviceCreateInfo				=
861 	{
862 		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//  VkStructureType					sType;
863 		&features2,									//  const void*						pNext;
864 		(vk::VkDeviceCreateFlags)0,					//  VkDeviceCreateFlags				flags;
865 		static_cast<uint32_t>(queueInfos.size()),	//  deUint32						queueCreateInfoCount;
866 		de::dataOrNull(queueInfos),					//  const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
867 		0u,											//  deUint32						enabledLayerCount;
868 		DE_NULL,									//  const char* const*				ppEnabledLayerNames;
869 		deUint32(deviceExtensions.size()),			//  deUint32						enabledExtensionCount;
870 		de::dataOrNull(deviceExtensions),			//  const char* const*				ppEnabledExtensionNames;
871 		DE_NULL,									//  const VkPhysicalDeviceFeatures*	pEnabledFeatures;
872 	};
873 
874 	m_logicalDevice			= createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceCreateInfo);
875 	m_deviceDriver			= de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vkp, instance, *m_logicalDevice));
876 	m_allocator				= de::MovePtr<vk::Allocator>(new vk::SimpleAllocator(*m_deviceDriver, *m_logicalDevice, getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
877 	m_queueFamilyTransfer	= queueFamilyTransfer;
878 	m_queueFamilyDecode		= queueFamilyDecode;
879 	m_queueFamilyEncode		= queueFamilyEncode;
880 	m_videoCodecOperation	= videoCodecOperationFlags;
881 
882 	return true;
883 #else
884 	DE_UNREF(queueFlagsRequired);
885 	DE_UNREF(videoCodecOperationFlags);
886 	DE_UNREF(videoDeviceFlags);
887 
888 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
889 #endif
890 }
891 
getDeviceDriver(void)892 const vk::DeviceDriver& VideoDevice::getDeviceDriver (void)
893 {
894 #ifndef CTS_USES_VULKANSC
895 	DE_ASSERT(m_deviceDriver.get() != DE_NULL);
896 
897 	return *m_deviceDriver;
898 #else
899 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
900 #endif
901 }
902 
getQueueFamilyIndexTransfer(void)903 const deUint32& VideoDevice::getQueueFamilyIndexTransfer (void)
904 {
905 #ifndef CTS_USES_VULKANSC
906 	DE_ASSERT(m_queueFamilyTransfer != VK_QUEUE_FAMILY_IGNORED);
907 
908 	return m_queueFamilyTransfer;
909 #else
910 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
911 #endif
912 }
913 
getQueueFamilyIndexDecode(void)914 const deUint32& VideoDevice::getQueueFamilyIndexDecode (void)
915 {
916 #ifndef CTS_USES_VULKANSC
917 	DE_ASSERT(m_queueFamilyDecode != VK_QUEUE_FAMILY_IGNORED);
918 
919 	return m_queueFamilyDecode;
920 #else
921 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
922 #endif
923 }
924 
getQueueFamilyIndexEncode(void)925 const deUint32& VideoDevice::getQueueFamilyIndexEncode (void)
926 {
927 #ifndef CTS_USES_VULKANSC
928 	DE_ASSERT(m_queueFamilyEncode != VK_QUEUE_FAMILY_IGNORED);
929 
930 	return m_queueFamilyEncode;
931 #else
932 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
933 #endif
934 }
935 
getQueueFamilyVideo(void)936 const deUint32& VideoDevice::getQueueFamilyVideo (void)
937 {
938 #ifndef CTS_USES_VULKANSC
939 	const bool encode = isVideoEncodeOperation(m_videoCodecOperation);
940 	const bool decode = isVideoDecodeOperation(m_videoCodecOperation);
941 
942 	DE_ASSERT((encode && !decode) || (!encode && decode));
943 	DE_UNREF(decode);
944 
945 	return encode ? getQueueFamilyIndexEncode() : getQueueFamilyIndexDecode();
946 #else
947 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
948 #endif
949 }
950 
getAllocator(void)951 vk::Allocator& VideoDevice::getAllocator (void)
952 {
953 #ifndef CTS_USES_VULKANSC
954 	DE_ASSERT(m_allocator != DE_NULL);
955 
956 	return *m_allocator;
957 #else
958 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
959 #endif
960 }
961 
962 }
963