• 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_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_recorder.reset(nullptr);
229 #endif // CTS_USES_VULKANSC
230 		m_driver->destroyInstance(m_instance, m_allocator);
231 	}
232 }
233 
swap(UncheckedInstance & other)234 void UncheckedInstance::swap (UncheckedInstance& other)
235 {
236 	std::swap(m_context, other.m_context);
237 #ifndef CTS_USES_VULKANSC
238 	m_recorder.swap(other.m_recorder);
239 #endif // CTS_USES_VULKANSC
240 	std::swap(m_allocator, other.m_allocator);
241 	vk::VkInstance aux = m_instance; m_instance = other.m_instance; other.m_instance = aux;
242 	m_driver.swap(other.m_driver);
243 #ifndef CTS_USES_VULKANSC
244 	Move<VkDebugReportCallbackEXT> aux2 = m_callback; m_callback = other.m_callback; other.m_callback = aux2;
245 #endif // CTS_USES_VULKANSC
246 }
247 
UncheckedInstance(UncheckedInstance && other)248 UncheckedInstance::UncheckedInstance (UncheckedInstance&& other)
249 	: UncheckedInstance()
250 {
251 	this->swap(other);
252 }
253 
operator =(UncheckedInstance && other)254 UncheckedInstance& UncheckedInstance::operator= (UncheckedInstance&& other)
255 {
256 	UncheckedInstance destroyer;
257 	destroyer.swap(other);
258 	this->swap(destroyer);
259 	return *this;
260 }
261 
operator vk::VkInstance() const262 UncheckedInstance::operator vk::VkInstance () const
263 {
264 	return m_instance;
265 }
operator bool() const266 UncheckedInstance::operator bool () const
267 {
268 	return (m_instance != DE_NULL);
269 }
270 
createCustomInstanceWithExtensions(Context & context,const std::vector<std::string> & extensions,const vk::VkAllocationCallbacks * pAllocator,bool allowLayers)271 CustomInstance createCustomInstanceWithExtensions (Context& context, const std::vector<std::string>& extensions, const vk::VkAllocationCallbacks* pAllocator, bool allowLayers)
272 {
273 	vector<const char*>	enabledLayers;
274 	vector<string>		enabledLayersStr;
275 	const auto&			cmdLine					= context.getTestContext().getCommandLine();
276 	const bool			validationRequested		= (cmdLine.isValidationEnabled() && allowLayers);
277 #ifndef CTS_USES_VULKANSC
278 	const bool			printValidationErrors	= cmdLine.printValidationErrors();
279 #endif // CTS_USES_VULKANSC
280 
281 	if (validationRequested)
282 	{
283 		enabledLayers = getValidationLayers(context.getPlatformInterface());
284 		enabledLayersStr = vector<string>(begin(enabledLayers), end(enabledLayers));
285 	}
286 
287 	const bool validationEnabled = !enabledLayers.empty();
288 
289 	// Filter extension list and throw NotSupported if a required extension is not supported.
290 	const deUint32									apiVersion			= context.getUsedApiVersion();
291 	const vk::PlatformInterface&					vkp					= context.getPlatformInterface();
292 	const vector<vk::VkExtensionProperties>			availableExtensions	= vk::enumerateInstanceExtensionProperties(vkp, DE_NULL);
293 	std::set<string>								usedExtensions;
294 
295 	// Get list of available extension names.
296 	vector<string> availableExtensionNames;
297 	for (const auto& ext : availableExtensions)
298 		availableExtensionNames.push_back(ext.extensionName);
299 
300 	// Filter duplicates and remove core extensions.
301 	for (const auto& ext : extensions)
302 	{
303 		if (!vk::isCoreInstanceExtension(apiVersion, ext))
304 			usedExtensions.insert(ext);
305 	}
306 
307 	// Add debug extension if validation is enabled.
308 	if (validationEnabled)
309 		usedExtensions.insert("VK_EXT_debug_report");
310 
311 	// Check extension support.
312 	for (const auto& ext : usedExtensions)
313 	{
314 		if (!vk::isInstanceExtensionSupported(apiVersion, availableExtensionNames, ext))
315 			TCU_THROW(NotSupportedError, ext + " is not supported");
316 	}
317 
318 #ifndef CTS_USES_VULKANSC
319 	std::unique_ptr<DebugReportRecorder> debugReportRecorder;
320 	if (validationEnabled)
321 		debugReportRecorder.reset(new DebugReportRecorder(printValidationErrors));
322 #endif // CTS_USES_VULKANSC
323 
324 	// Create custom instance.
325 	const vector<string> usedExtensionsVec(begin(usedExtensions), end(usedExtensions));
326 #ifndef CTS_USES_VULKANSC
327 	Move<VkInstance> instance = vk::createDefaultInstance(vkp, apiVersion, enabledLayersStr, usedExtensionsVec, cmdLine, debugReportRecorder.get(), pAllocator);
328 	return CustomInstance(context, instance, debugReportRecorder);
329 #else
330 	Move<VkInstance> instance = vk::createDefaultInstance(vkp, apiVersion, enabledLayersStr, usedExtensionsVec, cmdLine, pAllocator);
331 	return CustomInstance(context, instance);
332 #endif // CTS_USES_VULKANSC
333 }
334 
createCustomInstanceWithExtension(Context & context,const std::string & extension,const vk::VkAllocationCallbacks * pAllocator,bool allowLayers)335 CustomInstance createCustomInstanceWithExtension (Context& context, const std::string& extension, const vk::VkAllocationCallbacks* pAllocator, bool allowLayers)
336 {
337 	return createCustomInstanceWithExtensions(context, std::vector<std::string>(1, extension), pAllocator, allowLayers);
338 }
339 
createCustomInstanceFromContext(Context & context,const vk::VkAllocationCallbacks * pAllocator,bool allowLayers)340 CustomInstance createCustomInstanceFromContext (Context& context, const vk::VkAllocationCallbacks* pAllocator, bool allowLayers)
341 {
342 	return createCustomInstanceWithExtensions(context, std::vector<std::string>(), pAllocator, allowLayers);
343 }
344 
345 const char kDebugReportExt[] = "VK_EXT_debug_report";
346 
addDebugReportExt(const vk::PlatformInterface & vkp,const vk::VkInstanceCreateInfo & createInfo)347 vector<const char*> addDebugReportExt(const vk::PlatformInterface& vkp, const vk::VkInstanceCreateInfo& createInfo)
348 {
349 	if (!isDebugReportSupported(vkp))
350 		TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
351 
352 	vector<const char*> actualExtensions;
353 	if (createInfo.enabledExtensionCount != 0u)
354 	{
355 		for (deUint32 i = 0u; i < createInfo.enabledExtensionCount; ++i)
356 			actualExtensions.push_back(createInfo.ppEnabledExtensionNames[i]);
357 	}
358 
359 	if (std::find_if(begin(actualExtensions), end(actualExtensions), [](const char* name) { return (strcmp(name, kDebugReportExt) == 0); })
360 		== end(actualExtensions))
361 	{
362 		actualExtensions.push_back(kDebugReportExt);
363 	}
364 
365 	return actualExtensions;
366 }
367 
createCustomInstanceFromInfo(Context & context,const vk::VkInstanceCreateInfo * instanceCreateInfo,const vk::VkAllocationCallbacks * pAllocator,bool allowLayers)368 CustomInstance createCustomInstanceFromInfo (Context& context, const vk::VkInstanceCreateInfo* instanceCreateInfo, const vk::VkAllocationCallbacks* pAllocator, bool allowLayers)
369 {
370 	vector<const char*>						enabledLayers;
371 	vector<const char*>						enabledExtensions;
372 	vk::VkInstanceCreateInfo				createInfo				= *instanceCreateInfo;
373 	const auto&								cmdLine					= context.getTestContext().getCommandLine();
374 	const bool								validationEnabled		= cmdLine.isValidationEnabled();
375 #ifndef CTS_USES_VULKANSC
376 	const bool								printValidationErrors	= cmdLine.printValidationErrors();
377 #endif // CTS_USES_VULKANSC
378 	const vk::PlatformInterface&			vkp						= context.getPlatformInterface();
379 #ifndef CTS_USES_VULKANSC
380 	std::unique_ptr<DebugReportRecorder>	recorder;
381 	VkDebugReportCallbackCreateInfoEXT		callbackInfo;
382 #endif // CTS_USES_VULKANSC
383 
384 	if (validationEnabled && allowLayers)
385 	{
386 		// Activate some layers if requested.
387 		if (createInfo.enabledLayerCount == 0u)
388 		{
389 			enabledLayers = getValidationLayers(vkp);
390 			createInfo.enabledLayerCount = static_cast<deUint32>(enabledLayers.size());
391 			createInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
392 		}
393 
394 		// Make sure the debug report extension is enabled when validation is enabled.
395 		enabledExtensions = addDebugReportExt(vkp, createInfo);
396 		createInfo.enabledExtensionCount = static_cast<deUint32>(enabledExtensions.size());
397 		createInfo.ppEnabledExtensionNames = enabledExtensions.data();
398 
399 #ifndef CTS_USES_VULKANSC
400 		recorder.reset(new DebugReportRecorder(printValidationErrors));
401 		callbackInfo		= recorder->makeCreateInfo();
402 		callbackInfo.pNext	= createInfo.pNext;
403 		createInfo.pNext	= &callbackInfo;
404 #endif // CTS_USES_VULKANSC
405 	}
406 
407 #ifndef CTS_USES_VULKANSC
408 	return CustomInstance(context, vk::createInstance(vkp, &createInfo, pAllocator), recorder);
409 #else
410 	return CustomInstance(context, vk::createInstance(vkp, &createInfo, pAllocator));
411 #endif // CTS_USES_VULKANSC
412 }
413 
createUncheckedInstance(Context & context,const vk::VkInstanceCreateInfo * instanceCreateInfo,const vk::VkAllocationCallbacks * pAllocator,UncheckedInstance * instance,bool allowLayers)414 vk::VkResult createUncheckedInstance (Context& context, const vk::VkInstanceCreateInfo* instanceCreateInfo, const vk::VkAllocationCallbacks* pAllocator, UncheckedInstance* instance, bool allowLayers)
415 {
416 	vector<const char*>						enabledLayers;
417 	vector<const char*>						enabledExtensions;
418 	vk::VkInstanceCreateInfo				createInfo				= *instanceCreateInfo;
419 	const auto&								cmdLine					= context.getTestContext().getCommandLine();
420 	const bool								validationEnabled		= cmdLine.isValidationEnabled();
421 #ifndef CTS_USES_VULKANSC
422 	const bool								printValidationErrors	= cmdLine.printValidationErrors();
423 #endif // CTS_USES_VULKANSC
424 	const vk::PlatformInterface&			vkp						= context.getPlatformInterface();
425 	const bool								addLayers				= (validationEnabled && allowLayers);
426 #ifndef CTS_USES_VULKANSC
427 	std::unique_ptr<DebugReportRecorder>	recorder;
428 	VkDebugReportCallbackCreateInfoEXT		callbackInfo;
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 		// Prepare debug report recorder also for instance creation.
448 		recorder.reset(new DebugReportRecorder(printValidationErrors));
449 		callbackInfo		= recorder->makeCreateInfo();
450 		callbackInfo.pNext	= createInfo.pNext;
451 		createInfo.pNext	= &callbackInfo;
452 #endif // CTS_USES_VULKANSC
453 	}
454 
455 	vk::VkInstance	raw_instance = DE_NULL;
456 	vk::VkResult	result = vkp.createInstance(&createInfo, pAllocator, &raw_instance);
457 
458 #ifndef CTS_USES_VULKANSC
459 	*instance = UncheckedInstance(context, raw_instance, pAllocator, recorder);
460 #else
461 	*instance = UncheckedInstance(context, raw_instance, pAllocator);
462 #endif // CTS_USES_VULKANSC
463 
464 	return result;
465 }
466 
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 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)
468 {
469 	vector<const char*>		enabledLayers;
470 	vk::VkDeviceCreateInfo	createInfo		= *pCreateInfo;
471 
472 	if (createInfo.enabledLayerCount == 0u && validationEnabled)
473 	{
474 		enabledLayers = getValidationLayers(vki, physicalDevice);
475 		createInfo.enabledLayerCount = static_cast<deUint32>(enabledLayers.size());
476 		createInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
477 	}
478 
479 	return createDevice(vkp, instance, vki, physicalDevice, &createInfo, pAllocator);
480 }
481 
createUncheckedDevice(bool validationEnabled,const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice,const vk::VkDeviceCreateInfo * pCreateInfo,const vk::VkAllocationCallbacks * pAllocator,vk::VkDevice * pDevice)482 vk::VkResult createUncheckedDevice (bool validationEnabled, const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, const vk::VkDeviceCreateInfo* pCreateInfo, const vk::VkAllocationCallbacks* pAllocator, vk::VkDevice* pDevice)
483 {
484 	vector<const char*>		enabledLayers;
485 	vk::VkDeviceCreateInfo	createInfo		= *pCreateInfo;
486 
487 	if (createInfo.enabledLayerCount == 0u && validationEnabled)
488 	{
489 		enabledLayers = getValidationLayers(vki, physicalDevice);
490 		createInfo.enabledLayerCount = static_cast<deUint32>(enabledLayers.size());
491 		createInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
492 	}
493 
494 	return vki.createDevice(physicalDevice, &createInfo, pAllocator, pDevice);
495 }
496 
CustomInstanceWrapper(Context & context)497 CustomInstanceWrapper::CustomInstanceWrapper(Context& context)
498 	: instance(vkt::createCustomInstanceFromContext(context))
499 {
500 }
501 
CustomInstanceWrapper(Context & context,const std::vector<std::string> extensions)502 CustomInstanceWrapper::CustomInstanceWrapper(Context& context, const std::vector<std::string> extensions)
503 	: instance(vkt::createCustomInstanceWithExtensions(context, extensions))
504 {
505 }
checkSupport(Context & context,const VideoCodecOperationFlags videoCodecOperation)506 void VideoDevice::checkSupport (Context&						context,
507 								const VideoCodecOperationFlags	videoCodecOperation)
508 {
509 #ifndef CTS_USES_VULKANSC
510 	DE_ASSERT(videoCodecOperation != 0 && isVideoOperation(videoCodecOperation));
511 
512 	if (isVideoOperation(videoCodecOperation))
513 		context.requireDeviceFunctionality("VK_KHR_video_queue");
514 
515 	if (isVideoEncodeOperation(videoCodecOperation))
516 		context.requireDeviceFunctionality("VK_KHR_video_encode_queue");
517 
518 	if (isVideoDecodeOperation(videoCodecOperation))
519 		context.requireDeviceFunctionality("VK_KHR_video_decode_queue");
520 
521 	if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) != 0)
522 		context.requireDeviceFunctionality("VK_EXT_video_encode_h264");
523 
524 	if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) != 0)
525 		context.requireDeviceFunctionality("VK_EXT_video_encode_h265");
526 
527 	if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) != 0)
528 		context.requireDeviceFunctionality("VK_KHR_video_decode_h264");
529 
530 	if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) != 0)
531 		context.requireDeviceFunctionality("VK_KHR_video_decode_h265");
532 #else
533 	DE_UNREF(context);
534 	DE_UNREF(videoCodecOperation);
535 #endif
536 }
537 
VideoDevice(Context & context)538 VideoDevice::VideoDevice (Context& context)
539 	: m_context				(context)
540 	, m_logicalDevice		()
541 	, m_deviceDriver		()
542 	, m_allocator			()
543 	, m_queueFamilyTransfer	(VK_QUEUE_FAMILY_IGNORED)
544 	, m_queueFamilyDecode	(VK_QUEUE_FAMILY_IGNORED)
545 	, m_queueFamilyEncode	(VK_QUEUE_FAMILY_IGNORED)
546 #ifndef CTS_USES_VULKANSC
547 	, m_videoCodecOperation	(vk::VK_VIDEO_CODEC_OPERATION_NONE_KHR)
548 #else
549 	, m_videoCodecOperation	(~0u)
550 #endif
551 {
552 }
553 
VideoDevice(Context & context,const VideoCodecOperationFlags videoCodecOperation,const VideoDeviceFlags videoDeviceFlags)554 VideoDevice::VideoDevice (Context&							context,
555 						  const VideoCodecOperationFlags	videoCodecOperation,
556 						  const VideoDeviceFlags			videoDeviceFlags)
557 	: VideoDevice	(context)
558 {
559 #ifndef CTS_USES_VULKANSC
560 	const vk::VkQueueFlags	queueFlagsRequired	= getQueueFlags(videoCodecOperation);
561 	const vk::VkDevice		result				= getDeviceSupportingQueue(queueFlagsRequired, videoCodecOperation, videoDeviceFlags);
562 
563 	DE_ASSERT(result != DE_NULL);
564 	DE_UNREF(result);
565 #else
566 	DE_UNREF(videoCodecOperation);
567 	DE_UNREF(videoDeviceFlags);
568 #endif
569 }
570 
~VideoDevice(void)571 VideoDevice::~VideoDevice (void)
572 {
573 }
574 
getQueueFlags(const VideoCodecOperationFlags videoCodecOperation)575 vk::VkQueueFlags VideoDevice::getQueueFlags (const VideoCodecOperationFlags videoCodecOperation)
576 {
577 #ifndef CTS_USES_VULKANSC
578 	const vk::VkQueueFlags	queueFlagsRequired	= (isVideoEncodeOperation(videoCodecOperation) ? vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR : 0)
579 												| (isVideoDecodeOperation(videoCodecOperation) ? vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR : 0);
580 
581 	return queueFlagsRequired;
582 #else
583 	DE_UNREF(videoCodecOperation);
584 
585 	return 0;
586 #endif
587 }
588 
isVideoEncodeOperation(const VideoCodecOperationFlags videoCodecOperationFlags)589 bool VideoDevice::isVideoEncodeOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
590 {
591 #ifndef CTS_USES_VULKANSC
592 	const vk::VkVideoCodecOperationFlagsKHR	encodeOperations	= vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT
593 																| vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT;
594 
595 	return (encodeOperations & videoCodecOperationFlags) != 0;
596 #else
597 	DE_UNREF(videoCodecOperationFlags);
598 
599 	return false;
600 #endif
601 }
602 
isVideoDecodeOperation(const VideoCodecOperationFlags videoCodecOperationFlags)603 bool VideoDevice::isVideoDecodeOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
604 {
605 #ifndef CTS_USES_VULKANSC
606 	const vk::VkVideoCodecOperationFlagsKHR	decodeOperations	= vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR
607 																| vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR;
608 
609 	return (decodeOperations & videoCodecOperationFlags) != 0;
610 #else
611 	DE_UNREF(videoCodecOperationFlags);
612 
613 	return false;
614 #endif
615 }
616 
isVideoOperation(const VideoCodecOperationFlags videoCodecOperationFlags)617 bool VideoDevice::isVideoOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
618 {
619 #ifndef CTS_USES_VULKANSC
620 	return isVideoDecodeOperation(videoCodecOperationFlags) || isVideoEncodeOperation(videoCodecOperationFlags);
621 #else
622 	DE_UNREF(videoCodecOperationFlags);
623 
624 	return false;
625 #endif
626 }
627 
addVideoDeviceExtensions(std::vector<const char * > & deviceExtensions,const uint32_t apiVersion,const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags)628 void VideoDevice::addVideoDeviceExtensions (std::vector<const char*>&		deviceExtensions,
629 											const uint32_t					apiVersion,
630 											const vk::VkQueueFlags			queueFlagsRequired,
631 											const VideoCodecOperationFlags	videoCodecOperationFlags)
632 {
633 #ifndef CTS_USES_VULKANSC
634 	static const char videoQueue[]			= "VK_KHR_video_queue";
635 	static const char videoEncodeQueue[]	= "VK_KHR_video_encode_queue";
636 	static const char videoDecodeQueue[]	= "VK_KHR_video_decode_queue";
637 	static const char videoEncodeH264[]		= "VK_EXT_video_encode_h264";
638 	static const char videoEncodeH265[]		= "VK_EXT_video_encode_h265";
639 	static const char videoDecodeH264[]		= "VK_KHR_video_decode_h264";
640 	static const char videoDecodeH265[]		= "VK_KHR_video_decode_h265";
641 
642 	if (!vk::isCoreDeviceExtension(apiVersion, videoQueue))
643 		deviceExtensions.push_back(videoQueue);
644 
645 	if ((queueFlagsRequired & vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR) != 0)
646 		if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeQueue))
647 			deviceExtensions.push_back(videoEncodeQueue);
648 
649 	if ((queueFlagsRequired & vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR) != 0)
650 		if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeQueue))
651 			deviceExtensions.push_back(videoDecodeQueue);
652 
653 	if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) != 0)
654 		if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeH264))
655 			deviceExtensions.push_back(videoEncodeH264);
656 
657 	if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) != 0)
658 		if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeH265))
659 			deviceExtensions.push_back(videoEncodeH265);
660 
661 	if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) != 0)
662 		if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeH265))
663 			deviceExtensions.push_back(videoDecodeH265);
664 
665 	if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) != 0)
666 		if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeH264))
667 			deviceExtensions.push_back(videoDecodeH264);
668 #else
669 	DE_UNREF(deviceExtensions);
670 	DE_UNREF(apiVersion);
671 	DE_UNREF(queueFlagsRequired);
672 	DE_UNREF(videoCodecOperationFlags);
673 #endif
674 }
675 
getDeviceSupportingQueue(const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags,const VideoDevice::VideoDeviceFlags videoDeviceFlags)676 vk::VkDevice VideoDevice::getDeviceSupportingQueue (const vk::VkQueueFlags					queueFlagsRequired,
677 													const VideoCodecOperationFlags			videoCodecOperationFlags,
678 													const VideoDevice::VideoDeviceFlags		videoDeviceFlags)
679 {
680 #ifndef CTS_USES_VULKANSC
681 	if (*m_logicalDevice == DE_NULL)
682 	{
683 		DE_ASSERT(static_cast<deUint32>(queueFlagsRequired) != 0u);
684 		DE_ASSERT(static_cast<deUint32>(videoCodecOperationFlags) != 0u);
685 
686 		if (!createDeviceSupportingQueue(queueFlagsRequired, videoCodecOperationFlags, videoDeviceFlags))
687 			TCU_THROW(NotSupportedError, "Cannot create device with required parameters");
688 	}
689 
690 	return *m_logicalDevice;
691 #else
692 	DE_UNREF(queueFlagsRequired);
693 	DE_UNREF(videoCodecOperationFlags);
694 	DE_UNREF(videoDeviceFlags);
695 
696 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
697 #endif
698 }
699 
createDeviceSupportingQueue(const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags,const VideoDeviceFlags videoDeviceFlags)700 bool VideoDevice::createDeviceSupportingQueue (const vk::VkQueueFlags			queueFlagsRequired,
701 											   const VideoCodecOperationFlags	videoCodecOperationFlags,
702 											   const VideoDeviceFlags			videoDeviceFlags)
703 {
704 #ifndef CTS_USES_VULKANSC
705 	const vk::PlatformInterface&								vkp											= m_context.getPlatformInterface();
706 	const vk::InstanceInterface&								vki											= m_context.getInstanceInterface();
707 	const vk::VkPhysicalDevice									physicalDevice								= m_context.getPhysicalDevice();
708 	const vk::VkInstance										instance									= m_context.getInstance();
709 	const deUint32												apiVersion									= m_context.getUsedApiVersion();
710 	const bool													validationEnabled							= m_context.getTestContext().getCommandLine().isValidationEnabled();
711 	const bool													queryWithStatusForDecodeSupport				= (videoDeviceFlags & VIDEO_DEVICE_FLAG_QUERY_WITH_STATUS_FOR_DECODE_SUPPORT) != 0;
712 	const bool													requireYCBCRorNotSupported					= (videoDeviceFlags & VIDEO_DEVICE_FLAG_REQUIRE_YCBCR_OR_NOT_SUPPORTED) != 0;
713 	const bool													requireSync2orNotSupported					= (videoDeviceFlags & VIDEO_DEVICE_FLAG_REQUIRE_SYNC2_OR_NOT_SUPPORTED) != 0;
714 	const float													queueFamilyPriority							= 1.0f;
715 	deUint32													queueFamilyPropertiesCount					= 0u;
716 	deUint32													queueFamilyTransfer							= VK_QUEUE_FAMILY_IGNORED;
717 	deUint32													queueFamilyDecode							= VK_QUEUE_FAMILY_IGNORED;
718 	deUint32													queueFamilyEncode							= VK_QUEUE_FAMILY_IGNORED;
719 	vk::VkQueueFlags											queueFlagsFound								= 0;
720 	vector<vk::VkQueueFamilyProperties2>						queueFamilyProperties2;
721 	vector<vk::VkQueueFamilyVideoPropertiesKHR>				videoQueueFamilyProperties2;
722 	vector<vk::VkQueueFamilyQueryResultStatusPropertiesKHR>	VkQueueFamilyQueryResultStatusPropertiesKHR;
723 	vector<const char*>											deviceExtensions;
724 	vector<vk::VkDeviceQueueCreateInfo>							queueInfos;
725 
726 	DE_ASSERT(queueFlagsRequired != 0);
727 	DE_ASSERT(videoCodecOperationFlags != 0);
728 
729 	vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
730 
731 	if(queueFamilyPropertiesCount == 0u)
732 		TCU_FAIL("Device reports an empty set of queue family properties");
733 
734 	queueFamilyProperties2.resize(queueFamilyPropertiesCount);
735 	videoQueueFamilyProperties2.resize(queueFamilyPropertiesCount);
736 	VkQueueFamilyQueryResultStatusPropertiesKHR.resize(queueFamilyPropertiesCount);
737 
738 	for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
739 	{
740 		queueFamilyProperties2[ndx].sType											= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
741 		queueFamilyProperties2[ndx].pNext											= &videoQueueFamilyProperties2[ndx];
742 		videoQueueFamilyProperties2[ndx].sType										= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
743 		videoQueueFamilyProperties2[ndx].pNext										= &VkQueueFamilyQueryResultStatusPropertiesKHR[ndx];
744 		videoQueueFamilyProperties2[ndx].videoCodecOperations						= 0;
745 		VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].sType						= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR;
746 		VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].pNext						= DE_NULL;
747 		VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].queryResultStatusSupport	= DE_FALSE;
748 	}
749 
750 	vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties2.data());
751 
752 	if (queueFamilyPropertiesCount != queueFamilyProperties2.size())
753 		TCU_FAIL("Device returns less queue families than initially reported");
754 
755 	for (uint32_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
756 	{
757 		const vk::VkQueueFamilyProperties&	queueFamilyProperties	= queueFamilyProperties2[ndx].queueFamilyProperties;
758 		const vk::VkQueueFlags				usefulQueueFlags		= queueFamilyProperties.queueFlags & queueFlagsRequired & ~queueFlagsFound;
759 
760 		if (usefulQueueFlags != 0)
761 		{
762 			bool	assigned	= false;
763 
764 			if ((usefulQueueFlags & vk::VK_QUEUE_TRANSFER_BIT) != 0 && queueFamilyTransfer == VK_QUEUE_FAMILY_IGNORED)
765 			{
766 				queueFamilyTransfer	= ndx;
767 				assigned			= true;
768 			}
769 
770 			if ((videoQueueFamilyProperties2[ndx].videoCodecOperations & videoCodecOperationFlags) != 0)
771 			{
772 				if ((usefulQueueFlags & vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR) != 0 && queueFamilyDecode == VK_QUEUE_FAMILY_IGNORED)
773 				{
774 					if (!queryWithStatusForDecodeSupport || (queryWithStatusForDecodeSupport && VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].queryResultStatusSupport))
775 					{
776 						queueFamilyDecode	= ndx;
777 						assigned			= true;
778 					}
779 				}
780 
781 				if ((usefulQueueFlags & vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR) != 0 && queueFamilyEncode == VK_QUEUE_FAMILY_IGNORED)
782 				{
783 					queueFamilyEncode	= ndx;
784 					assigned			= true;
785 				}
786 			}
787 
788 			if (assigned)
789 			{
790 				const vk::VkDeviceQueueCreateInfo	queueInfo =
791 				{
792 					vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//  VkStructureType				sType;
793 					DE_NULL,										//  const void*					pNext;
794 					(vk::VkDeviceQueueCreateFlags)0u,				//  VkDeviceQueueCreateFlags	flags;
795 					ndx,											//  deUint32					queueFamilyIndex;
796 					1u,												//  deUint32					queueCount;
797 					&queueFamilyPriority,							//  const float*				pQueuePriorities;
798 				};
799 
800 				if (queueFamilyProperties.queueCount == 0)
801 					TCU_FAIL("Video queue returned queueCount is zero");
802 
803 				queueInfos.push_back(queueInfo);
804 
805 				queueFlagsFound |= usefulQueueFlags;
806 
807 				if (queueFlagsFound == queueFlagsRequired)
808 					break;
809 			}
810 		}
811 	}
812 
813 	if (queueFlagsFound != queueFlagsRequired)
814 		return false;
815 
816 	addVideoDeviceExtensions(deviceExtensions, apiVersion, queueFlagsRequired, videoCodecOperationFlags);
817 
818 	if (requireYCBCRorNotSupported)
819 		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_sampler_ycbcr_conversion"))
820 			deviceExtensions.push_back("VK_KHR_sampler_ycbcr_conversion");
821 
822 	if (requireSync2orNotSupported)
823 		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_synchronization2"))
824 			deviceExtensions.push_back("VK_KHR_synchronization2");
825 
826 	vk::VkPhysicalDeviceSynchronization2FeaturesKHR		synchronization2Features		=
827 	{
828 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR,	//  VkStructureType	sType;
829 		DE_NULL,																//  void*			pNext;
830 		DE_FALSE,																//  VkBool32		synchronization2;
831 	};
832 	vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures	samplerYcbcrConversionFeatures	=
833 	{
834 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,	//  VkStructureType	sType;
835 		DE_NULL,																	//  void*			pNext;
836 		DE_FALSE,																	//  VkBool32		samplerYcbcrConversion;
837 	};
838 	vk::VkPhysicalDeviceFeatures2						features2						=
839 	{
840 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,	//  VkStructureType				sType;
841 		DE_NULL,											//  void*						pNext;
842 		vk::VkPhysicalDeviceFeatures(),						//  VkPhysicalDeviceFeatures	features;
843 	};
844 
845 	if (requireYCBCRorNotSupported)
846 		appendStructurePtrToVulkanChain((const void**)&features2.pNext, &samplerYcbcrConversionFeatures);
847 
848 	if (requireSync2orNotSupported)
849 		appendStructurePtrToVulkanChain((const void**)&features2.pNext, &synchronization2Features);
850 
851 	vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
852 
853 	if (requireYCBCRorNotSupported && samplerYcbcrConversionFeatures.samplerYcbcrConversion == DE_FALSE)
854 		TCU_THROW(NotSupportedError, "samplerYcbcrConversionFeatures.samplerYcbcrConversion is required");
855 
856 	if (requireSync2orNotSupported && synchronization2Features.synchronization2 == DE_FALSE)
857 		TCU_THROW(NotSupportedError, "synchronization2Features.synchronization2 is required");
858 
859 	features2.features.robustBufferAccess = DE_FALSE;
860 
861 	const vk::VkDeviceCreateInfo						deviceCreateInfo				=
862 	{
863 		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//  VkStructureType					sType;
864 		&features2,									//  const void*						pNext;
865 		(vk::VkDeviceCreateFlags)0,					//  VkDeviceCreateFlags				flags;
866 		static_cast<uint32_t>(queueInfos.size()),	//  deUint32						queueCreateInfoCount;
867 		de::dataOrNull(queueInfos),					//  const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
868 		0u,											//  deUint32						enabledLayerCount;
869 		DE_NULL,									//  const char* const*				ppEnabledLayerNames;
870 		deUint32(deviceExtensions.size()),			//  deUint32						enabledExtensionCount;
871 		de::dataOrNull(deviceExtensions),			//  const char* const*				ppEnabledExtensionNames;
872 		DE_NULL,									//  const VkPhysicalDeviceFeatures*	pEnabledFeatures;
873 	};
874 
875 	m_logicalDevice			= createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceCreateInfo);
876 	m_deviceDriver			= de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vkp, instance, *m_logicalDevice));
877 	m_allocator				= de::MovePtr<vk::Allocator>(new vk::SimpleAllocator(*m_deviceDriver, *m_logicalDevice, getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
878 	m_queueFamilyTransfer	= queueFamilyTransfer;
879 	m_queueFamilyDecode		= queueFamilyDecode;
880 	m_queueFamilyEncode		= queueFamilyEncode;
881 	m_videoCodecOperation	= videoCodecOperationFlags;
882 
883 	return true;
884 #else
885 	DE_UNREF(queueFlagsRequired);
886 	DE_UNREF(videoCodecOperationFlags);
887 	DE_UNREF(videoDeviceFlags);
888 
889 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
890 #endif
891 }
892 
getDeviceDriver(void)893 const vk::DeviceDriver& VideoDevice::getDeviceDriver (void)
894 {
895 #ifndef CTS_USES_VULKANSC
896 	DE_ASSERT(m_deviceDriver.get() != DE_NULL);
897 
898 	return *m_deviceDriver;
899 #else
900 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
901 #endif
902 }
903 
getQueueFamilyIndexTransfer(void)904 const deUint32& VideoDevice::getQueueFamilyIndexTransfer (void)
905 {
906 #ifndef CTS_USES_VULKANSC
907 	DE_ASSERT(m_queueFamilyTransfer != VK_QUEUE_FAMILY_IGNORED);
908 
909 	return m_queueFamilyTransfer;
910 #else
911 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
912 #endif
913 }
914 
getQueueFamilyIndexDecode(void)915 const deUint32& VideoDevice::getQueueFamilyIndexDecode (void)
916 {
917 #ifndef CTS_USES_VULKANSC
918 	DE_ASSERT(m_queueFamilyDecode != VK_QUEUE_FAMILY_IGNORED);
919 
920 	return m_queueFamilyDecode;
921 #else
922 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
923 #endif
924 }
925 
getQueueFamilyIndexEncode(void)926 const deUint32& VideoDevice::getQueueFamilyIndexEncode (void)
927 {
928 #ifndef CTS_USES_VULKANSC
929 	DE_ASSERT(m_queueFamilyEncode != VK_QUEUE_FAMILY_IGNORED);
930 
931 	return m_queueFamilyEncode;
932 #else
933 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
934 #endif
935 }
936 
getQueueFamilyVideo(void)937 const deUint32& VideoDevice::getQueueFamilyVideo (void)
938 {
939 #ifndef CTS_USES_VULKANSC
940 	const bool encode = isVideoEncodeOperation(m_videoCodecOperation);
941 	const bool decode = isVideoDecodeOperation(m_videoCodecOperation);
942 
943 	DE_ASSERT((encode && !decode) || (!encode && decode));
944 	DE_UNREF(decode);
945 
946 	return encode ? getQueueFamilyIndexEncode() : getQueueFamilyIndexDecode();
947 #else
948 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
949 #endif
950 }
951 
getAllocator(void)952 vk::Allocator& VideoDevice::getAllocator (void)
953 {
954 #ifndef CTS_USES_VULKANSC
955 	DE_ASSERT(m_allocator != DE_NULL);
956 
957 	return *m_allocator;
958 #else
959 	TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
960 #endif
961 }
962 
963 }
964