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 = vk::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 #ifdef CTS_USES_VULKANSC
479 // Add fault callback if there isn't one already.
480 VkFaultCallbackInfo faultCallbackInfo =
481 {
482 VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO, // VkStructureType sType;
483 DE_NULL, // void* pNext;
484 0U, // uint32_t faultCount;
485 nullptr, // VkFaultData* pFaults;
486 Context::faultCallbackFunction // PFN_vkFaultCallbackFunction pfnFaultCallback;
487 };
488
489 if (!findStructureInChain(createInfo.pNext, getStructureType<VkFaultCallbackInfo>()))
490 {
491 // XXX workaround incorrect constness on faultCallbackInfo.pNext.
492 faultCallbackInfo.pNext = const_cast<void *>(createInfo.pNext);
493 createInfo.pNext = &faultCallbackInfo;
494 }
495 #endif // CTS_USES_VULKANSC
496
497 return createDevice(vkp, instance, vki, physicalDevice, &createInfo, pAllocator);
498 }
499
createUncheckedDevice(bool validationEnabled,const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice,const vk::VkDeviceCreateInfo * pCreateInfo,const vk::VkAllocationCallbacks * pAllocator,vk::VkDevice * pDevice)500 vk::VkResult createUncheckedDevice (bool validationEnabled, const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, const vk::VkDeviceCreateInfo* pCreateInfo, const vk::VkAllocationCallbacks* pAllocator, vk::VkDevice* pDevice)
501 {
502 vector<const char*> enabledLayers;
503 vk::VkDeviceCreateInfo createInfo = *pCreateInfo;
504
505 if (createInfo.enabledLayerCount == 0u && validationEnabled)
506 {
507 enabledLayers = getValidationLayers(vki, physicalDevice);
508 createInfo.enabledLayerCount = static_cast<deUint32>(enabledLayers.size());
509 createInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
510 }
511
512 #ifdef CTS_USES_VULKANSC
513 // Add fault callback if there isn't one already.
514 VkFaultCallbackInfo faultCallbackInfo =
515 {
516 VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO, // VkStructureType sType;
517 DE_NULL, // void* pNext;
518 0U, // uint32_t faultCount;
519 nullptr, // VkFaultData* pFaults;
520 Context::faultCallbackFunction // PFN_vkFaultCallbackFunction pfnFaultCallback;
521 };
522
523 if (!findStructureInChain(createInfo.pNext, getStructureType<VkFaultCallbackInfo>()))
524 {
525 // XXX workaround incorrect constness on faultCallbackInfo.pNext.
526 faultCallbackInfo.pNext = const_cast<void *>(createInfo.pNext);
527 createInfo.pNext = &faultCallbackInfo;
528 }
529 #endif // CTS_USES_VULKANSC
530
531 return vki.createDevice(physicalDevice, &createInfo, pAllocator, pDevice);
532 }
533
CustomInstanceWrapper(Context & context)534 CustomInstanceWrapper::CustomInstanceWrapper(Context& context)
535 : instance(vkt::createCustomInstanceFromContext(context))
536 {
537 }
538
CustomInstanceWrapper(Context & context,const std::vector<std::string> extensions)539 CustomInstanceWrapper::CustomInstanceWrapper(Context& context, const std::vector<std::string> extensions)
540 : instance(vkt::createCustomInstanceWithExtensions(context, extensions))
541 {
542 }
checkSupport(Context & context,const VideoCodecOperationFlags videoCodecOperation)543 void VideoDevice::checkSupport (Context& context,
544 const VideoCodecOperationFlags videoCodecOperation)
545 {
546 #ifndef CTS_USES_VULKANSC
547 DE_ASSERT(videoCodecOperation != 0 && isVideoOperation(videoCodecOperation));
548
549 if (isVideoOperation(videoCodecOperation))
550 context.requireDeviceFunctionality("VK_KHR_video_queue");
551
552 if (isVideoEncodeOperation(videoCodecOperation))
553 context.requireDeviceFunctionality("VK_KHR_video_encode_queue");
554
555 if (isVideoDecodeOperation(videoCodecOperation))
556 context.requireDeviceFunctionality("VK_KHR_video_decode_queue");
557
558 if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) != 0)
559 context.requireDeviceFunctionality("VK_EXT_video_encode_h264");
560
561 if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) != 0)
562 context.requireDeviceFunctionality("VK_EXT_video_encode_h265");
563
564 if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) != 0)
565 context.requireDeviceFunctionality("VK_KHR_video_decode_h264");
566
567 if ((videoCodecOperation & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) != 0)
568 context.requireDeviceFunctionality("VK_KHR_video_decode_h265");
569 #else
570 DE_UNREF(context);
571 DE_UNREF(videoCodecOperation);
572 #endif
573 }
574
VideoDevice(Context & context)575 VideoDevice::VideoDevice (Context& context)
576 : m_context (context)
577 , m_logicalDevice ()
578 , m_deviceDriver ()
579 , m_allocator ()
580 , m_queueFamilyTransfer (VK_QUEUE_FAMILY_IGNORED)
581 , m_queueFamilyDecode (VK_QUEUE_FAMILY_IGNORED)
582 , m_queueFamilyEncode (VK_QUEUE_FAMILY_IGNORED)
583 #ifndef CTS_USES_VULKANSC
584 , m_videoCodecOperation (vk::VK_VIDEO_CODEC_OPERATION_NONE_KHR)
585 #else
586 , m_videoCodecOperation (~0u)
587 #endif
588 {
589 }
590
VideoDevice(Context & context,const VideoCodecOperationFlags videoCodecOperation,const VideoDeviceFlags videoDeviceFlags)591 VideoDevice::VideoDevice (Context& context,
592 const VideoCodecOperationFlags videoCodecOperation,
593 const VideoDeviceFlags videoDeviceFlags)
594 : VideoDevice (context)
595 {
596 #ifndef CTS_USES_VULKANSC
597 const vk::VkQueueFlags queueFlagsRequired = getQueueFlags(videoCodecOperation);
598 const vk::VkDevice result = getDeviceSupportingQueue(queueFlagsRequired, videoCodecOperation, videoDeviceFlags);
599
600 DE_ASSERT(result != DE_NULL);
601 DE_UNREF(result);
602 #else
603 DE_UNREF(videoCodecOperation);
604 DE_UNREF(videoDeviceFlags);
605 #endif
606 }
607
~VideoDevice(void)608 VideoDevice::~VideoDevice (void)
609 {
610 }
611
getQueueFlags(const VideoCodecOperationFlags videoCodecOperation)612 vk::VkQueueFlags VideoDevice::getQueueFlags (const VideoCodecOperationFlags videoCodecOperation)
613 {
614 #ifndef CTS_USES_VULKANSC
615 const vk::VkQueueFlags queueFlagsRequired = (isVideoEncodeOperation(videoCodecOperation) ? vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR : 0)
616 | (isVideoDecodeOperation(videoCodecOperation) ? vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR : 0);
617
618 return queueFlagsRequired;
619 #else
620 DE_UNREF(videoCodecOperation);
621
622 return 0;
623 #endif
624 }
625
isVideoEncodeOperation(const VideoCodecOperationFlags videoCodecOperationFlags)626 bool VideoDevice::isVideoEncodeOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
627 {
628 #ifndef CTS_USES_VULKANSC
629 const vk::VkVideoCodecOperationFlagsKHR encodeOperations = vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT
630 | vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT;
631
632 return (encodeOperations & videoCodecOperationFlags) != 0;
633 #else
634 DE_UNREF(videoCodecOperationFlags);
635
636 return false;
637 #endif
638 }
639
isVideoDecodeOperation(const VideoCodecOperationFlags videoCodecOperationFlags)640 bool VideoDevice::isVideoDecodeOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
641 {
642 #ifndef CTS_USES_VULKANSC
643 const vk::VkVideoCodecOperationFlagsKHR decodeOperations = vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR
644 | vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR;
645
646 return (decodeOperations & videoCodecOperationFlags) != 0;
647 #else
648 DE_UNREF(videoCodecOperationFlags);
649
650 return false;
651 #endif
652 }
653
isVideoOperation(const VideoCodecOperationFlags videoCodecOperationFlags)654 bool VideoDevice::isVideoOperation (const VideoCodecOperationFlags videoCodecOperationFlags)
655 {
656 #ifndef CTS_USES_VULKANSC
657 return isVideoDecodeOperation(videoCodecOperationFlags) || isVideoEncodeOperation(videoCodecOperationFlags);
658 #else
659 DE_UNREF(videoCodecOperationFlags);
660
661 return false;
662 #endif
663 }
664
addVideoDeviceExtensions(std::vector<const char * > & deviceExtensions,const uint32_t apiVersion,const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags)665 void VideoDevice::addVideoDeviceExtensions (std::vector<const char*>& deviceExtensions,
666 const uint32_t apiVersion,
667 const vk::VkQueueFlags queueFlagsRequired,
668 const VideoCodecOperationFlags videoCodecOperationFlags)
669 {
670 #ifndef CTS_USES_VULKANSC
671 static const char videoQueue[] = "VK_KHR_video_queue";
672 static const char videoEncodeQueue[] = "VK_KHR_video_encode_queue";
673 static const char videoDecodeQueue[] = "VK_KHR_video_decode_queue";
674 static const char videoEncodeH264[] = "VK_EXT_video_encode_h264";
675 static const char videoEncodeH265[] = "VK_EXT_video_encode_h265";
676 static const char videoDecodeH264[] = "VK_KHR_video_decode_h264";
677 static const char videoDecodeH265[] = "VK_KHR_video_decode_h265";
678
679 if (!vk::isCoreDeviceExtension(apiVersion, videoQueue))
680 deviceExtensions.push_back(videoQueue);
681
682 if ((queueFlagsRequired & vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR) != 0)
683 if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeQueue))
684 deviceExtensions.push_back(videoEncodeQueue);
685
686 if ((queueFlagsRequired & vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR) != 0)
687 if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeQueue))
688 deviceExtensions.push_back(videoDecodeQueue);
689
690 if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) != 0)
691 if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeH264))
692 deviceExtensions.push_back(videoEncodeH264);
693
694 if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) != 0)
695 if (!vk::isCoreDeviceExtension(apiVersion, videoEncodeH265))
696 deviceExtensions.push_back(videoEncodeH265);
697
698 if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) != 0)
699 if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeH265))
700 deviceExtensions.push_back(videoDecodeH265);
701
702 if ((videoCodecOperationFlags & vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) != 0)
703 if (!vk::isCoreDeviceExtension(apiVersion, videoDecodeH264))
704 deviceExtensions.push_back(videoDecodeH264);
705 #else
706 DE_UNREF(deviceExtensions);
707 DE_UNREF(apiVersion);
708 DE_UNREF(queueFlagsRequired);
709 DE_UNREF(videoCodecOperationFlags);
710 #endif
711 }
712
getDeviceSupportingQueue(const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags,const VideoDevice::VideoDeviceFlags videoDeviceFlags)713 vk::VkDevice VideoDevice::getDeviceSupportingQueue (const vk::VkQueueFlags queueFlagsRequired,
714 const VideoCodecOperationFlags videoCodecOperationFlags,
715 const VideoDevice::VideoDeviceFlags videoDeviceFlags)
716 {
717 #ifndef CTS_USES_VULKANSC
718 if (*m_logicalDevice == DE_NULL)
719 {
720 DE_ASSERT(static_cast<deUint32>(queueFlagsRequired) != 0u);
721 DE_ASSERT(static_cast<deUint32>(videoCodecOperationFlags) != 0u);
722
723 if (!createDeviceSupportingQueue(queueFlagsRequired, videoCodecOperationFlags, videoDeviceFlags))
724 TCU_THROW(NotSupportedError, "Cannot create device with required parameters");
725 }
726
727 return *m_logicalDevice;
728 #else
729 DE_UNREF(queueFlagsRequired);
730 DE_UNREF(videoCodecOperationFlags);
731 DE_UNREF(videoDeviceFlags);
732
733 TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
734 #endif
735 }
736
createDeviceSupportingQueue(const vk::VkQueueFlags queueFlagsRequired,const VideoCodecOperationFlags videoCodecOperationFlags,const VideoDeviceFlags videoDeviceFlags)737 bool VideoDevice::createDeviceSupportingQueue (const vk::VkQueueFlags queueFlagsRequired,
738 const VideoCodecOperationFlags videoCodecOperationFlags,
739 const VideoDeviceFlags videoDeviceFlags)
740 {
741 #ifndef CTS_USES_VULKANSC
742 const vk::PlatformInterface& vkp = m_context.getPlatformInterface();
743 const vk::InstanceInterface& vki = m_context.getInstanceInterface();
744 const vk::VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
745 const vk::VkInstance instance = m_context.getInstance();
746 const deUint32 apiVersion = m_context.getUsedApiVersion();
747 const bool validationEnabled = m_context.getTestContext().getCommandLine().isValidationEnabled();
748 const bool queryWithStatusForDecodeSupport = (videoDeviceFlags & VIDEO_DEVICE_FLAG_QUERY_WITH_STATUS_FOR_DECODE_SUPPORT) != 0;
749 const bool requireYCBCRorNotSupported = (videoDeviceFlags & VIDEO_DEVICE_FLAG_REQUIRE_YCBCR_OR_NOT_SUPPORTED) != 0;
750 const bool requireSync2orNotSupported = (videoDeviceFlags & VIDEO_DEVICE_FLAG_REQUIRE_SYNC2_OR_NOT_SUPPORTED) != 0;
751 const float queueFamilyPriority = 1.0f;
752 deUint32 queueFamilyPropertiesCount = 0u;
753 deUint32 queueFamilyTransfer = VK_QUEUE_FAMILY_IGNORED;
754 deUint32 queueFamilyDecode = VK_QUEUE_FAMILY_IGNORED;
755 deUint32 queueFamilyEncode = VK_QUEUE_FAMILY_IGNORED;
756 vk::VkQueueFlags queueFlagsFound = 0;
757 vector<vk::VkQueueFamilyProperties2> queueFamilyProperties2;
758 vector<vk::VkQueueFamilyVideoPropertiesKHR> videoQueueFamilyProperties2;
759 vector<vk::VkQueueFamilyQueryResultStatusPropertiesKHR> VkQueueFamilyQueryResultStatusPropertiesKHR;
760 vector<const char*> deviceExtensions;
761 vector<vk::VkDeviceQueueCreateInfo> queueInfos;
762
763 DE_ASSERT(queueFlagsRequired != 0);
764 DE_ASSERT(videoCodecOperationFlags != 0);
765
766 vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
767
768 if(queueFamilyPropertiesCount == 0u)
769 TCU_FAIL("Device reports an empty set of queue family properties");
770
771 queueFamilyProperties2.resize(queueFamilyPropertiesCount);
772 videoQueueFamilyProperties2.resize(queueFamilyPropertiesCount);
773 VkQueueFamilyQueryResultStatusPropertiesKHR.resize(queueFamilyPropertiesCount);
774
775 for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
776 {
777 queueFamilyProperties2[ndx].sType = vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
778 queueFamilyProperties2[ndx].pNext = &videoQueueFamilyProperties2[ndx];
779 videoQueueFamilyProperties2[ndx].sType = vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
780 videoQueueFamilyProperties2[ndx].pNext = &VkQueueFamilyQueryResultStatusPropertiesKHR[ndx];
781 videoQueueFamilyProperties2[ndx].videoCodecOperations = 0;
782 VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].sType = vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR;
783 VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].pNext = DE_NULL;
784 VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].queryResultStatusSupport = DE_FALSE;
785 }
786
787 vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties2.data());
788
789 if (queueFamilyPropertiesCount != queueFamilyProperties2.size())
790 TCU_FAIL("Device returns less queue families than initially reported");
791
792 for (uint32_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
793 {
794 const vk::VkQueueFamilyProperties& queueFamilyProperties = queueFamilyProperties2[ndx].queueFamilyProperties;
795 const vk::VkQueueFlags usefulQueueFlags = queueFamilyProperties.queueFlags & queueFlagsRequired & ~queueFlagsFound;
796
797 if (usefulQueueFlags != 0)
798 {
799 bool assigned = false;
800
801 if ((usefulQueueFlags & vk::VK_QUEUE_TRANSFER_BIT) != 0 && queueFamilyTransfer == VK_QUEUE_FAMILY_IGNORED)
802 {
803 queueFamilyTransfer = ndx;
804 assigned = true;
805 }
806
807 if ((videoQueueFamilyProperties2[ndx].videoCodecOperations & videoCodecOperationFlags) != 0)
808 {
809 if ((usefulQueueFlags & vk::VK_QUEUE_VIDEO_DECODE_BIT_KHR) != 0 && queueFamilyDecode == VK_QUEUE_FAMILY_IGNORED)
810 {
811 if (!queryWithStatusForDecodeSupport || (queryWithStatusForDecodeSupport && VkQueueFamilyQueryResultStatusPropertiesKHR[ndx].queryResultStatusSupport))
812 {
813 queueFamilyDecode = ndx;
814 assigned = true;
815 }
816 }
817
818 if ((usefulQueueFlags & vk::VK_QUEUE_VIDEO_ENCODE_BIT_KHR) != 0 && queueFamilyEncode == VK_QUEUE_FAMILY_IGNORED)
819 {
820 queueFamilyEncode = ndx;
821 assigned = true;
822 }
823 }
824
825 if (assigned)
826 {
827 const vk::VkDeviceQueueCreateInfo queueInfo =
828 {
829 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
830 DE_NULL, // const void* pNext;
831 (vk::VkDeviceQueueCreateFlags)0u, // VkDeviceQueueCreateFlags flags;
832 ndx, // deUint32 queueFamilyIndex;
833 1u, // deUint32 queueCount;
834 &queueFamilyPriority, // const float* pQueuePriorities;
835 };
836
837 if (queueFamilyProperties.queueCount == 0)
838 TCU_FAIL("Video queue returned queueCount is zero");
839
840 queueInfos.push_back(queueInfo);
841
842 queueFlagsFound |= usefulQueueFlags;
843
844 if (queueFlagsFound == queueFlagsRequired)
845 break;
846 }
847 }
848 }
849
850 if (queueFlagsFound != queueFlagsRequired)
851 return false;
852
853 addVideoDeviceExtensions(deviceExtensions, apiVersion, queueFlagsRequired, videoCodecOperationFlags);
854
855 if (requireYCBCRorNotSupported)
856 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_sampler_ycbcr_conversion"))
857 deviceExtensions.push_back("VK_KHR_sampler_ycbcr_conversion");
858
859 if (requireSync2orNotSupported)
860 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_synchronization2"))
861 deviceExtensions.push_back("VK_KHR_synchronization2");
862
863 vk::VkPhysicalDeviceSynchronization2FeaturesKHR synchronization2Features =
864 {
865 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR, // VkStructureType sType;
866 DE_NULL, // void* pNext;
867 DE_FALSE, // VkBool32 synchronization2;
868 };
869 vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures samplerYcbcrConversionFeatures =
870 {
871 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, // VkStructureType sType;
872 DE_NULL, // void* pNext;
873 DE_FALSE, // VkBool32 samplerYcbcrConversion;
874 };
875 vk::VkPhysicalDeviceFeatures2 features2 =
876 {
877 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, // VkStructureType sType;
878 DE_NULL, // void* pNext;
879 vk::VkPhysicalDeviceFeatures(), // VkPhysicalDeviceFeatures features;
880 };
881
882 if (requireYCBCRorNotSupported)
883 appendStructurePtrToVulkanChain((const void**)&features2.pNext, &samplerYcbcrConversionFeatures);
884
885 if (requireSync2orNotSupported)
886 appendStructurePtrToVulkanChain((const void**)&features2.pNext, &synchronization2Features);
887
888 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
889
890 if (requireYCBCRorNotSupported && samplerYcbcrConversionFeatures.samplerYcbcrConversion == DE_FALSE)
891 TCU_THROW(NotSupportedError, "samplerYcbcrConversionFeatures.samplerYcbcrConversion is required");
892
893 if (requireSync2orNotSupported && synchronization2Features.synchronization2 == DE_FALSE)
894 TCU_THROW(NotSupportedError, "synchronization2Features.synchronization2 is required");
895
896 features2.features.robustBufferAccess = DE_FALSE;
897
898 const vk::VkDeviceCreateInfo deviceCreateInfo =
899 {
900 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
901 &features2, // const void* pNext;
902 (vk::VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
903 static_cast<uint32_t>(queueInfos.size()), // deUint32 queueCreateInfoCount;
904 de::dataOrNull(queueInfos), // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
905 0u, // deUint32 enabledLayerCount;
906 DE_NULL, // const char* const* ppEnabledLayerNames;
907 deUint32(deviceExtensions.size()), // deUint32 enabledExtensionCount;
908 de::dataOrNull(deviceExtensions), // const char* const* ppEnabledExtensionNames;
909 DE_NULL, // const VkPhysicalDeviceFeatures* pEnabledFeatures;
910 };
911
912 m_logicalDevice = createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceCreateInfo);
913 m_deviceDriver = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vkp, instance, *m_logicalDevice, apiVersion));
914 m_allocator = de::MovePtr<vk::Allocator>(new vk::SimpleAllocator(*m_deviceDriver, *m_logicalDevice, getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
915 m_queueFamilyTransfer = queueFamilyTransfer;
916 m_queueFamilyDecode = queueFamilyDecode;
917 m_queueFamilyEncode = queueFamilyEncode;
918 m_videoCodecOperation = videoCodecOperationFlags;
919
920 return true;
921 #else
922 DE_UNREF(queueFlagsRequired);
923 DE_UNREF(videoCodecOperationFlags);
924 DE_UNREF(videoDeviceFlags);
925
926 TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
927 #endif
928 }
929
getDeviceDriver(void)930 const vk::DeviceDriver& VideoDevice::getDeviceDriver (void)
931 {
932 #ifndef CTS_USES_VULKANSC
933 DE_ASSERT(m_deviceDriver.get() != DE_NULL);
934
935 return *m_deviceDriver;
936 #else
937 TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
938 #endif
939 }
940
getQueueFamilyIndexTransfer(void) const941 deUint32 VideoDevice::getQueueFamilyIndexTransfer (void) const
942 {
943 #ifndef CTS_USES_VULKANSC
944 DE_ASSERT(m_queueFamilyTransfer != VK_QUEUE_FAMILY_IGNORED);
945
946 return m_queueFamilyTransfer;
947 #else
948 TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
949 #endif
950 }
951
getQueueFamilyIndexDecode(void) const952 deUint32 VideoDevice::getQueueFamilyIndexDecode (void) const
953 {
954 #ifndef CTS_USES_VULKANSC
955 DE_ASSERT(m_queueFamilyDecode != VK_QUEUE_FAMILY_IGNORED);
956
957 return m_queueFamilyDecode;
958 #else
959 TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
960 #endif
961 }
962
getQueueFamilyIndexEncode(void) const963 deUint32 VideoDevice::getQueueFamilyIndexEncode (void) const
964 {
965 #ifndef CTS_USES_VULKANSC
966 DE_ASSERT(m_queueFamilyEncode != VK_QUEUE_FAMILY_IGNORED);
967
968 return m_queueFamilyEncode;
969 #else
970 TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
971 #endif
972 }
973
getQueueFamilyVideo(void) const974 deUint32 VideoDevice::getQueueFamilyVideo (void) const
975 {
976 #ifndef CTS_USES_VULKANSC
977 const bool encode = isVideoEncodeOperation(m_videoCodecOperation);
978 const bool decode = isVideoDecodeOperation(m_videoCodecOperation);
979
980 DE_ASSERT((encode && !decode) || (!encode && decode));
981 DE_UNREF(decode);
982
983 return encode ? getQueueFamilyIndexEncode() : getQueueFamilyIndexDecode();
984 #else
985 TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
986 #endif
987 }
988
getAllocator(void)989 vk::Allocator& VideoDevice::getAllocator (void)
990 {
991 #ifndef CTS_USES_VULKANSC
992 DE_ASSERT(m_allocator != DE_NULL);
993
994 return *m_allocator;
995 #else
996 TCU_THROW(NotSupportedError, "Video is not supported for Vulkan SC");
997 #endif
998 }
999
1000 }
1001