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