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