• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Synchronization semaphore basic tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSynchronizationBasicSemaphoreTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktSynchronizationUtil.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28 
29 #include "vkDefs.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkDeviceUtil.hpp"
34 #include "vkRef.hpp"
35 #include "vkSafetyCriticalUtil.hpp"
36 
37 #include <thread>
38 
39 #include "tcuCommandLine.hpp"
40 
41 namespace vkt
42 {
43 namespace synchronization
44 {
45 namespace
46 {
47 
48 using namespace vk;
49 using vkt::synchronization::VideoCodecOperationFlags;
50 
51 struct TestConfig
52 {
53 	bool						useTypeCreate;
54 	VkSemaphoreType				semaphoreType;
55 	SynchronizationType			type;
56 	VideoCodecOperationFlags	videoCodecOperationFlags;
57 };
58 
59 #ifdef CTS_USES_VULKANSC
60 static const int basicChainLength	= 1024;
61 #else
62 static const int basicChainLength	= 32768;
63 #endif
64 
createTestSemaphore(Context & context,const DeviceInterface & vk,const VkDevice device,const TestConfig & config)65 Move<VkSemaphore> createTestSemaphore(Context& context, const DeviceInterface& vk, const VkDevice device, const TestConfig& config)
66 {
67 	if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE && !context.getTimelineSemaphoreFeatures().timelineSemaphore)
68 		TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
69 
70 	return Move<VkSemaphore>(config.useTypeCreate ? createSemaphoreType(vk, device, config.semaphoreType) : createSemaphore(vk, device));
71 }
72 
73 #define FENCE_WAIT	~0ull
74 
basicOneQueueCase(Context & context,const TestConfig config)75 tcu::TestStatus basicOneQueueCase (Context& context, const TestConfig config)
76 {
77 	de::MovePtr<VideoDevice>		videoDevice					(config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
78 	const DeviceInterface&			vk							= getSyncDeviceInterface(videoDevice, context);
79 	const VkDevice					device						= getSyncDevice(videoDevice, context);
80 	const VkQueue					queue						= getSyncQueue(videoDevice, context);
81 	const deUint32					queueFamilyIndex			= getSyncQueueFamilyIndex(videoDevice, context);
82 	const Unique<VkSemaphore>		semaphore					(createTestSemaphore(context, vk, device, config));
83 	const Unique<VkCommandPool>		cmdPool						(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
84 	const Unique<VkCommandBuffer>	cmdBuffer					(makeCommandBuffer(vk, device, *cmdPool));
85 	const VkCommandBufferBeginInfo	info						{
86 																	VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
87 																	DE_NULL,										// const void*                              pNext;
88 																	VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,	// VkCommandBufferUsageFlags                flags;
89 																	DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
90 																};
91 	const deUint64					timelineValue				= 1u;
92 	const Unique<VkFence>			fence						(createFence(vk, device));
93 	bool							usingTimelineSemaphores		= config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE;
94 	VkCommandBufferSubmitInfoKHR	commandBufferInfo			= makeCommonCommandBufferSubmitInfo(*cmdBuffer);
95 	SynchronizationWrapperPtr		synchronizationWrapper		= getSynchronizationWrapper(config.type, vk, usingTimelineSemaphores, 2u);
96 	VkSemaphoreSubmitInfoKHR		signalSemaphoreSubmitInfo	= makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValue, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR);
97 	VkSemaphoreSubmitInfoKHR		waitSemaphoreSubmitInfo		= makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValue, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
98 
99 	synchronizationWrapper->addSubmitInfo(
100 		0u,												// deUint32								waitSemaphoreInfoCount
101 		DE_NULL,										// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
102 		1u,												// deUint32								commandBufferInfoCount
103 		&commandBufferInfo,								// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
104 		1u,												// deUint32								signalSemaphoreInfoCount
105 		&signalSemaphoreSubmitInfo,						// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
106 		DE_FALSE,
107 		usingTimelineSemaphores
108 	);
109 	synchronizationWrapper->addSubmitInfo(
110 		1u,												// deUint32								waitSemaphoreInfoCount
111 		&waitSemaphoreSubmitInfo,						// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
112 		1u,												// deUint32								commandBufferInfoCount
113 		&commandBufferInfo,								// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
114 		0u,												// deUint32								signalSemaphoreInfoCount
115 		DE_NULL,										// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
116 		usingTimelineSemaphores,
117 		DE_FALSE
118 	);
119 
120 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &info));
121 	endCommandBuffer(vk, *cmdBuffer);
122 	VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
123 
124 	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, FENCE_WAIT))
125 		return tcu::TestStatus::fail("Basic semaphore tests with one queue failed");
126 
127 	return tcu::TestStatus::pass("Basic semaphore tests with one queue passed");
128 }
129 
noneWaitSubmitTest(Context & context,const TestConfig config)130 tcu::TestStatus noneWaitSubmitTest (Context& context, const TestConfig config)
131 {
132 	const DeviceInterface&			vk										= context.getDeviceInterface();
133 	const VkDevice							device								= context.getDevice();
134 	const VkQueue								queue									= context.getUniversalQueue();
135 	const deUint32							queueFamilyIndex			= context.getUniversalQueueFamilyIndex();
136 
137 	const Unique<VkSemaphore>			semaphore					(createTestSemaphore(context, vk, device, config));
138 	const Unique<VkCommandPool>		cmdPool						(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
139 
140 		const Unique<VkCommandBuffer>	firstbuffer					(makeCommandBuffer(vk, device, *cmdPool));
141 	const Unique<VkCommandBuffer>	secondBuffer				(makeCommandBuffer(vk, device, *cmdPool));
142 
143 	const VkCommandBufferBeginInfo	info						{
144 																	VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
145 																	DE_NULL,																			// const void*                              pNext;
146 																	VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,	// VkCommandBufferUsageFlags                flags;
147 																	DE_NULL,																			// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
148 																};
149 	const Unique<VkFence>			fence1					(createFence(vk, device));
150 	const Unique<VkFence>			fence2					(createFence(vk, device));
151 	const Unique<VkEvent>			event						(createEvent(vk, device));
152 
153 	VK_CHECK(vk.beginCommandBuffer(*firstbuffer, &info));
154 	endCommandBuffer(vk, *firstbuffer);
155 
156 	const VkSubmitInfo firstSubmitInfo {
157 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	//VkStructureType sType
158 		DE_NULL,												//const void* pNext
159 		0u,															//uint32_t waitSemaphoreCount
160 		DE_NULL,												//const VkSemaphore* pWaitSemaphores
161 		DE_NULL,												//const VkPipelineStageFlags* pWaitDstStageMask
162 		1u,															//uint32_t commandBufferCount
163 		&firstbuffer.get(),							//const VkCommandBuffer* pCommandBuffers
164 		1,															//uint32_t signalSemaphoreCount
165 		&semaphore.get()								//const VkSemaphore* pSignalSemaphores
166 	};
167 
168 	//check if waiting on an event in the none stage works as expected
169 	VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_NONE_KHR};
170 
171 	const VkSubmitInfo secondSubmitInfo {
172 		VK_STRUCTURE_TYPE_SUBMIT_INFO,  //VkStructureType sType
173 		DE_NULL,												//const void* pNext
174 		1u,															//uint32_t waitSemaphoreCount
175 		&semaphore.get(),								//const VkSemaphore* pWaitSemaphores
176 		waitStages,											//const VkPipelineStageFlags* pWaitDstStageMask
177 		1u,															//uint32_t commandBufferCount
178 		&secondBuffer.get(),							//const VkCommandBuffer* pCommandBuffers
179 		0,															//uint32_t signalSemaphoreCount
180 		DE_NULL													//const VkSemaphore* pSignalSemaphores
181 	};
182 
183 	VK_CHECK(vk.beginCommandBuffer(*secondBuffer, &info));
184 	vk.cmdSetEvent(*secondBuffer, event.get(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
185 	endCommandBuffer(vk, *secondBuffer);
186 
187 	VK_CHECK(vk.queueSubmit(queue, 1, &firstSubmitInfo,  fence1.get()));
188 	VK_CHECK(vk.queueSubmit(queue, 1, &secondSubmitInfo, fence2.get()));
189 	VK_CHECK(vk.queueWaitIdle(queue));
190 
191 	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence1.get(), DE_TRUE, FENCE_WAIT))
192 		return tcu::TestStatus::fail("None stage test failed, failed to wait for fence");
193 
194 	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence2.get(), DE_TRUE, FENCE_WAIT))
195 		return tcu::TestStatus::fail("None stage test failed, failed to wait for the second fence");
196 
197 	if (vk.getEventStatus(device, event.get()) != VK_EVENT_SET)
198 		return tcu::TestStatus::fail("None stage test failed, event isn't set");
199 
200 	return tcu::TestStatus::pass("Pass");
201 }
202 
basicChainCase(Context & context,TestConfig config)203 tcu::TestStatus basicChainCase(Context & context, TestConfig config)
204 {
205 	VkResult								err							= VK_SUCCESS;
206 	de::MovePtr<VideoDevice>				videoDevice					(config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
207 	const DeviceInterface&					vk							= getSyncDeviceInterface(videoDevice, context);
208 	const VkDevice							device						= getSyncDevice(videoDevice, context);
209 	const VkQueue							queue						= getSyncQueue(videoDevice, context);
210 	VkSemaphoreCreateInfo					sci							= { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, DE_NULL, 0 };
211 	VkFenceCreateInfo						fci							= { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
212 	VkFence									fence;
213 	std::vector<VkSemaphoreSubmitInfoKHR>	waitSemaphoreSubmitInfos	(basicChainLength, makeCommonSemaphoreSubmitInfo(0u, 0u, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR));
214 	std::vector<VkSemaphoreSubmitInfoKHR>	signalSemaphoreSubmitInfos	(basicChainLength, makeCommonSemaphoreSubmitInfo(0u, 0u, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR));
215 	VkSemaphoreSubmitInfoKHR*				pWaitSemaphoreInfo			= DE_NULL;
216 	VkSemaphoreSubmitInfoKHR*				pSignalSemaphoreInfo		= signalSemaphoreSubmitInfos.data();
217 
218 	for (int i = 0; err == VK_SUCCESS && i < basicChainLength; i++)
219 	{
220 		if (i % (basicChainLength/4) == 0) context.getTestContext().touchWatchdog();
221 
222 		err = vk.createSemaphore(device, &sci, DE_NULL, &pSignalSemaphoreInfo->semaphore);
223 		if (err != VK_SUCCESS)
224 			continue;
225 
226 		SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_FALSE);
227 		synchronizationWrapper->addSubmitInfo(
228 			!!pWaitSemaphoreInfo,						// deUint32								waitSemaphoreInfoCount
229 			pWaitSemaphoreInfo,							// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
230 			0u,											// deUint32								commandBufferInfoCount
231 			DE_NULL,									// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
232 			1u,											// deUint32								signalSemaphoreInfoCount
233 			pSignalSemaphoreInfo						// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
234 		);
235 
236 		err = synchronizationWrapper->queueSubmit(queue, 0);
237 		pWaitSemaphoreInfo				= &waitSemaphoreSubmitInfos[i];
238 		pWaitSemaphoreInfo->semaphore	= pSignalSemaphoreInfo->semaphore;
239 		pSignalSemaphoreInfo++;
240 	}
241 
242 
243 	VK_CHECK(vk.createFence(device, &fci, DE_NULL, &fence));
244 
245 	{
246 		SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_FALSE);
247 		synchronizationWrapper->addSubmitInfo(1, pWaitSemaphoreInfo, 0, DE_NULL, 0, DE_NULL);
248 		VK_CHECK(synchronizationWrapper->queueSubmit(queue, fence));
249 	}
250 
251 	vk.waitForFences(device, 1, &fence, VK_TRUE, ~(0ull));
252 	vk.destroyFence(device, fence, DE_NULL);
253 
254 	for (const auto& s : signalSemaphoreSubmitInfos)
255 		vk.destroySemaphore(device, s.semaphore, DE_NULL);
256 
257 	if (err == VK_SUCCESS)
258 		return tcu::TestStatus::pass("Basic semaphore chain test passed");
259 
260 	return tcu::TestStatus::fail("Basic semaphore chain test failed");
261 }
262 
basicChainTimelineCase(Context & context,TestConfig config)263 tcu::TestStatus basicChainTimelineCase (Context& context, TestConfig config)
264 {
265 	VkResult					err			= VK_SUCCESS;
266 	de::MovePtr<VideoDevice>	videoDevice	(config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
267 	const DeviceInterface&		vk			= getSyncDeviceInterface(videoDevice, context);
268 	const VkDevice				device		= getSyncDevice(videoDevice, context);
269 	const VkQueue				queue		= getSyncQueue(videoDevice, context);
270 	VkSemaphoreTypeCreateInfo	scti		= { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, DE_NULL, VK_SEMAPHORE_TYPE_TIMELINE, 0 };
271 	VkSemaphoreCreateInfo		sci			= { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &scti, 0 };
272 	VkFenceCreateInfo			fci			= { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
273 	VkSemaphore					semaphore;
274 	VkFence						fence;
275 
276 	VK_CHECK(vk.createSemaphore(device, &sci, DE_NULL, &semaphore));
277 
278 	std::vector<VkSemaphoreSubmitInfoKHR>	waitSemaphoreSubmitInfos	(basicChainLength, makeCommonSemaphoreSubmitInfo(semaphore, 0u, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR));
279 	std::vector<VkSemaphoreSubmitInfoKHR>	signalSemaphoreSubmitInfos	(basicChainLength, makeCommonSemaphoreSubmitInfo(semaphore, 0u, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR));
280 	VkSemaphoreSubmitInfoKHR*				pWaitSemaphoreInfo			= DE_NULL;
281 	VkSemaphoreSubmitInfoKHR*				pSignalSemaphoreInfo		= signalSemaphoreSubmitInfos.data();
282 
283 	for (int i = 0; err == VK_SUCCESS && i < basicChainLength; i++)
284 	{
285 		if (i % (basicChainLength/4) == 0) context.getTestContext().touchWatchdog();
286 
287 		pSignalSemaphoreInfo->value = static_cast<deUint64>(i+1);
288 
289 		SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_TRUE);
290 		synchronizationWrapper->addSubmitInfo(
291 			!!pWaitSemaphoreInfo,					// deUint32								waitSemaphoreInfoCount
292 			pWaitSemaphoreInfo,						// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
293 			0u,										// deUint32								commandBufferInfoCount
294 			DE_NULL,								// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
295 			1u,										// deUint32								signalSemaphoreInfoCount
296 			pSignalSemaphoreInfo,					// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
297 			!!pWaitSemaphoreInfo,
298 			DE_TRUE
299 		);
300 
301 		err = synchronizationWrapper->queueSubmit(queue, 0);
302 
303 		pWaitSemaphoreInfo			= &waitSemaphoreSubmitInfos[i];
304 		pWaitSemaphoreInfo->value	= static_cast<deUint64>(i);
305 		pSignalSemaphoreInfo++;
306 	}
307 
308 	pWaitSemaphoreInfo->value = basicChainLength;
309 	SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_TRUE);
310 	synchronizationWrapper->addSubmitInfo(
311 		1u,											// deUint32								waitSemaphoreInfoCount
312 		pWaitSemaphoreInfo,							// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
313 		0u,											// deUint32								commandBufferInfoCount
314 		DE_NULL,									// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
315 		0u,											// deUint32								signalSemaphoreInfoCount
316 		DE_NULL,									// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
317 		DE_TRUE
318 	);
319 
320 	VK_CHECK(vk.createFence(device, &fci, DE_NULL, &fence));
321 	VK_CHECK(synchronizationWrapper->queueSubmit(queue, fence));
322 	vk.waitForFences(device, 1, &fence, VK_TRUE, ~(0ull));
323 
324 	vk.destroyFence(device, fence, DE_NULL);
325 	vk.destroySemaphore(device, semaphore, DE_NULL);
326 
327 	if (err == VK_SUCCESS)
328 		return tcu::TestStatus::pass("Basic semaphore chain test passed");
329 
330 	return tcu::TestStatus::fail("Basic semaphore chain test failed");
331 }
332 
basicThreadTimelineCase(Context & context,TestConfig config)333 tcu::TestStatus basicThreadTimelineCase(Context& context, TestConfig config)
334 {
335 	const VkSemaphoreTypeCreateInfo		scti			= { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, DE_NULL, VK_SEMAPHORE_TYPE_TIMELINE, 0 };
336 	de::MovePtr<VideoDevice>			videoDevice		(config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
337 	const DeviceInterface&				vk				= getSyncDeviceInterface(videoDevice, context);
338 	const VkDevice						device			= getSyncDevice(videoDevice, context);
339 	const VkSemaphoreCreateInfo			sci				= { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &scti, 0 };
340 	const VkFenceCreateInfo				fci				= { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
341 	const vk::Unique<vk::VkSemaphore>	semaphore		(createSemaphore(vk, device, &sci));
342 	const Unique<VkFence>				fence			(createFence(vk, device, &fci));
343 	const deUint64						waitTimeout		= 50ull * 1000000ull;		// miliseconds
344 	VkResult							threadResult	= VK_SUCCESS;
345 
346 	// helper creating VkSemaphoreSignalInfo
347 	auto makeSemaphoreSignalInfo = [&semaphore](deUint64 value) -> VkSemaphoreSignalInfo
348 	{
349 		return
350 		{
351 			VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,		// VkStructureType				sType
352 			DE_NULL,										// const void*					pNext
353 			*semaphore,										// VkSemaphore					semaphore
354 			value											// deUint64						value
355 		};
356 	};
357 
358 	// helper creating VkSemaphoreWaitInfo
359 	auto makeSemaphoreWaitInfo = [&semaphore](deUint64* valuePtr) -> VkSemaphoreWaitInfo
360 	{
361 		return
362 		{
363 			VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,			// VkStructureType				sType
364 			DE_NULL,										// const void*					pNext
365 			VK_SEMAPHORE_WAIT_ANY_BIT,						// VkSemaphoreWaitFlags			flags;
366 			1u,												// deUint32						semaphoreCount;
367 			&*semaphore,									// const VkSemaphore*			pSemaphores;
368 			valuePtr										// const deUint64*				pValues;
369 		};
370 	};
371 
372 	// start thread - semaphore has value 0
373 	de::MovePtr<std::thread> thread(new std::thread([=, &vk, &threadResult]
374 	{
375 		// wait till semaphore has value 1
376 		deUint64 waitValue = 1;
377 		VkSemaphoreWaitInfo waitOne = makeSemaphoreWaitInfo(&waitValue);
378 		threadResult = vk.waitSemaphores(device, &waitOne, waitTimeout);
379 
380 		if (threadResult == VK_SUCCESS)
381 		{
382 			// signal semaphore with value 2
383 			VkSemaphoreSignalInfo signalTwo = makeSemaphoreSignalInfo(2);
384 			threadResult = vk.signalSemaphore(device, &signalTwo);
385 		}
386 	}));
387 
388 	// wait some time to give thread chance to start
389 	deSleep(1);		// milisecond
390 
391 	// signal semaphore with value 1
392 	VkSemaphoreSignalInfo signalOne = makeSemaphoreSignalInfo(1);
393 	vk.signalSemaphore(device, &signalOne);
394 
395 	// wait till semaphore has value 2
396 	deUint64				waitValue	= 2;
397 	VkSemaphoreWaitInfo		waitTwo		= makeSemaphoreWaitInfo(&waitValue);
398 	VkResult				mainResult	= vk.waitSemaphores(device, &waitTwo, waitTimeout);
399 
400 	thread->join();
401 
402 	if (mainResult == VK_SUCCESS)
403 		return tcu::TestStatus::pass("Pass");
404 
405 	if ((mainResult == VK_TIMEOUT) || (threadResult == VK_TIMEOUT))
406 		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Reached wait timeout");
407 
408 	return tcu::TestStatus::fail("Fail");
409 }
410 
basicMultiQueueCase(Context & context,TestConfig config)411 tcu::TestStatus basicMultiQueueCase (Context& context, TestConfig config)
412 {
413 	enum { NO_MATCH_FOUND = ~((deUint32)0) };
414 	enum QueuesIndexes { FIRST = 0, SECOND, COUNT };
415 
416 	struct Queues
417 	{
418 		VkQueue		queue;
419 		deUint32	queueFamilyIndex;
420 	};
421 
422 #ifndef CTS_USES_VULKANSC
423 	const VkInstance								instance						= context.getInstance();
424 	const InstanceInterface&						instanceInterface				= context.getInstanceInterface();
425 	const VkPhysicalDevice							physicalDevice					= context.getPhysicalDevice();
426 	de::MovePtr<VideoDevice>						videoDevice						(config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
427 	const DeviceInterface&							vk								= getSyncDeviceInterface(videoDevice, context);
428 	std::vector<VkQueueFamilyVideoPropertiesKHR>	videoQueueFamilyProperties2;
429 #else
430 	const CustomInstance							instance						(createCustomInstanceFromContext(context));
431 	const InstanceDriver&							instanceDriver					(instance.getDriver());
432 	const VkPhysicalDevice							physicalDevice					= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
433 	const InstanceInterface&						instanceInterface				= instanceDriver;
434 //	const DeviceInterface&							vk								= context.getDeviceInterface();
435 //	const InstanceInterface&						instance						= context.getInstanceInterface();
436 //	const VkPhysicalDevice							physicalDevice					= context.getPhysicalDevice();
437 #endif // CTS_USES_VULKANSC
438 	vk::Move<vk::VkDevice>							logicalDevice;
439 	std::vector<VkQueueFamilyProperties>			queueFamilyProperties;
440 	std::vector<VkQueueFamilyProperties2>			queueFamilyProperties2;
441 	VkDeviceCreateInfo								deviceInfo;
442 	VkPhysicalDeviceFeatures						deviceFeatures;
443 	const float										queuePriorities[COUNT]	= { 1.0f, 1.0f };
444 	VkDeviceQueueCreateInfo							queueInfos[COUNT];
445 	Queues											queues[COUNT] =
446 	{
447 		{DE_NULL, (deUint32)NO_MATCH_FOUND},
448 		{DE_NULL, (deUint32)NO_MATCH_FOUND}
449 	};
450 	const VkCommandBufferBeginInfo			info =
451 	{
452 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
453 		DE_NULL,										// const void*                              pNext;
454 		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,	// VkCommandBufferUsageFlags                flags;
455 		DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
456 	};
457 
458 	const bool								isTimelineSemaphore = config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE;
459 
460 	if (config.videoCodecOperationFlags != 0)
461 	{
462 #ifndef CTS_USES_VULKANSC
463 		uint32_t	queueFamilyPropertiesCount	= 0;
464 
465 		instanceInterface.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
466 
467 		if (queueFamilyPropertiesCount > 0)
468 		{
469 			queueFamilyProperties2.resize(queueFamilyPropertiesCount);
470 			videoQueueFamilyProperties2.resize(queueFamilyPropertiesCount);
471 
472 			for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
473 			{
474 				queueFamilyProperties2[ndx].sType						= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
475 				queueFamilyProperties2[ndx].pNext						= &videoQueueFamilyProperties2[ndx];
476 				videoQueueFamilyProperties2[ndx].sType					= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
477 				videoQueueFamilyProperties2[ndx].pNext					= DE_NULL;
478 				videoQueueFamilyProperties2[ndx].videoCodecOperations	= 0;
479 			}
480 
481 			instanceInterface.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties2.data());
482 
483 			if (queueFamilyPropertiesCount != queueFamilyProperties2.size())
484 				TCU_FAIL("Device returns less queue families than initially reported");
485 
486 			queueFamilyProperties.reserve(queueFamilyPropertiesCount);
487 
488 			for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
489 				queueFamilyProperties.push_back(queueFamilyProperties2[ndx].queueFamilyProperties);
490 		}
491 #endif // CTS_USES_VULKANSC
492 	}
493 	else
494 	{
495 		queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceInterface, physicalDevice);
496 	}
497 
498 	for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
499 	{
500 #ifndef CTS_USES_VULKANSC
501 		const bool usableQueue	=  videoQueueFamilyProperties2.empty()
502 								|| (videoQueueFamilyProperties2[queueNdx].videoCodecOperations & config.videoCodecOperationFlags) != 0;
503 
504 		if (!usableQueue)
505 			continue;
506 #endif // CTS_USES_VULKANSC
507 
508 		if (NO_MATCH_FOUND == queues[FIRST].queueFamilyIndex)
509 			queues[FIRST].queueFamilyIndex = queueNdx;
510 
511 		if (queues[FIRST].queueFamilyIndex != queueNdx || queueFamilyProperties[queueNdx].queueCount > 1u)
512 		{
513 			queues[SECOND].queueFamilyIndex = queueNdx;
514 			break;
515 		}
516 	}
517 
518 	if (queues[FIRST].queueFamilyIndex == NO_MATCH_FOUND || queues[SECOND].queueFamilyIndex == NO_MATCH_FOUND)
519 		TCU_THROW(NotSupportedError, "Queues couldn't be created");
520 
521 	for (int queueNdx = 0; queueNdx < COUNT; ++queueNdx)
522 	{
523 		VkDeviceQueueCreateInfo queueInfo;
524 		deMemset(&queueInfo, 0, sizeof(queueInfo));
525 
526 		queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
527 		queueInfo.pNext = DE_NULL;
528 		queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
529 		queueInfo.queueFamilyIndex = queues[queueNdx].queueFamilyIndex;
530 		queueInfo.queueCount = (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 2 : 1;
531 		queueInfo.pQueuePriorities = queuePriorities;
532 
533 		queueInfos[queueNdx] = queueInfo;
534 
535 		if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
536 			break;
537 	}
538 
539 	deMemset(&deviceInfo, 0, sizeof(deviceInfo));
540 	instanceInterface.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
541 
542 	VkPhysicalDeviceFeatures2					createPhysicalFeature		{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, DE_NULL, deviceFeatures };
543 	VkPhysicalDeviceTimelineSemaphoreFeatures	timelineSemaphoreFeatures	{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, DE_NULL, DE_TRUE };
544 	VkPhysicalDeviceSynchronization2FeaturesKHR	synchronization2Features	{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR, DE_NULL, DE_TRUE };
545 	void**										nextPtr						= &createPhysicalFeature.pNext;
546 
547 	std::vector<const char*> deviceExtensions;
548 
549 	if (config.videoCodecOperationFlags != 0)
550 		VideoDevice::addVideoDeviceExtensions(deviceExtensions, context.getUsedApiVersion(), VideoDevice::getQueueFlags(config.videoCodecOperationFlags), config.videoCodecOperationFlags);
551 
552 	if (isTimelineSemaphore)
553 	{
554 		if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_timeline_semaphore"))
555 			deviceExtensions.push_back("VK_KHR_timeline_semaphore");
556 		addToChainVulkanStructure(&nextPtr, timelineSemaphoreFeatures);
557 	}
558 	if (config.type == SynchronizationType::SYNCHRONIZATION2)
559 	{
560 		deviceExtensions.push_back("VK_KHR_synchronization2");
561 		addToChainVulkanStructure(&nextPtr, synchronization2Features);
562 	}
563 
564 	void* pNext												= &createPhysicalFeature;
565 #ifdef CTS_USES_VULKANSC
566 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
567 	memReservationInfo.pNext								= pNext;
568 	pNext													= &memReservationInfo;
569 
570 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
571 	sc10Features.pNext										= pNext;
572 	pNext													= &sc10Features;
573 
574 	VkPipelineCacheCreateInfo			pcCI;
575 	std::vector<VkPipelinePoolSize>		poolSizes;
576 	if (context.getTestContext().getCommandLine().isSubProcess())
577 	{
578 		if (context.getResourceInterface()->getCacheDataSize() > 0)
579 		{
580 			pcCI =
581 			{
582 				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,		// VkStructureType				sType;
583 				DE_NULL,											// const void*					pNext;
584 				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
585 					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
586 				context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
587 				context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
588 			};
589 			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
590 			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
591 		}
592 
593 		poolSizes							= context.getResourceInterface()->getPipelinePoolSizes();
594 		if (!poolSizes.empty())
595 		{
596 			memReservationInfo.pipelinePoolSizeCount			= deUint32(poolSizes.size());
597 			memReservationInfo.pPipelinePoolSizes				= poolSizes.data();
598 		}
599 	}
600 #endif // CTS_USES_VULKANSC
601 
602 	deviceInfo.sType					= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
603 	deviceInfo.pNext					= pNext;
604 	deviceInfo.enabledExtensionCount	= static_cast<deUint32>(deviceExtensions.size());
605 	deviceInfo.ppEnabledExtensionNames	= deviceExtensions.empty() ? DE_NULL : deviceExtensions.data();
606 	deviceInfo.enabledLayerCount		= 0u;
607 	deviceInfo.ppEnabledLayerNames		= DE_NULL;
608 	deviceInfo.pEnabledFeatures			= 0u;
609 	deviceInfo.queueCreateInfoCount		= (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 1 : COUNT;
610 	deviceInfo.pQueueCreateInfos		= queueInfos;
611 
612 	logicalDevice = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instance, instanceInterface, physicalDevice, &deviceInfo);
613 
614 #ifndef CTS_USES_VULKANSC
615 	de::MovePtr<vk::DeviceDriver>								deviceDriver	= de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), instance, *logicalDevice));
616 #else
617 	de::MovePtr<vk::DeviceDriverSC, vk::DeinitDeviceDeleter>	deviceDriver	= de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(context.getPlatformInterface(), instance, *logicalDevice, context.getTestContext().getCommandLine(), context.getResourceInterface(), context.getDeviceVulkanSC10Properties(), context.getDeviceProperties()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), *logicalDevice));
618 	const DeviceInterface&										vk				= *deviceDriver;
619 #endif // CTS_USES_VULKANSC
620 
621 	for (deUint32 queueReqNdx = 0; queueReqNdx < COUNT; ++queueReqNdx)
622 	{
623 		if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
624 			vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, queueReqNdx, &queues[queueReqNdx].queue);
625 		else
626 			vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, 0u, &queues[queueReqNdx].queue);
627 	}
628 
629 	Move<VkSemaphore>						semaphore;
630 	Move<VkCommandPool>						cmdPool[COUNT];
631 	Move<VkCommandBuffer>					cmdBuffer[COUNT];
632 	deUint64								timelineValues[COUNT] = { 1ull, 2ull };
633 	Move<VkFence>							fence[COUNT];
634 
635 	semaphore			= (createTestSemaphore(context, vk, *logicalDevice, config));
636 	cmdPool[FIRST]		= (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[FIRST].queueFamilyIndex));
637 	cmdPool[SECOND]		= (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[SECOND].queueFamilyIndex));
638 	cmdBuffer[FIRST]	= (makeCommandBuffer(vk, *logicalDevice, *cmdPool[FIRST]));
639 	cmdBuffer[SECOND]	= (makeCommandBuffer(vk, *logicalDevice, *cmdPool[SECOND]));
640 
641 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[FIRST], &info));
642 	endCommandBuffer(vk, *cmdBuffer[FIRST]);
643 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[SECOND], &info));
644 	endCommandBuffer(vk, *cmdBuffer[SECOND]);
645 
646 	fence[FIRST] = (createFence(vk, *logicalDevice));
647 	fence[SECOND] = (createFence(vk, *logicalDevice));
648 
649 	VkCommandBufferSubmitInfoKHR commandBufferInfo[]
650 	{
651 		makeCommonCommandBufferSubmitInfo(*cmdBuffer[FIRST]),
652 		makeCommonCommandBufferSubmitInfo(*cmdBuffer[SECOND])
653 	};
654 
655 	VkSemaphoreSubmitInfoKHR signalSemaphoreSubmitInfo[]
656 	{
657 		makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[FIRST], VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR),
658 		makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[SECOND], VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR)
659 	};
660 	VkSemaphoreSubmitInfoKHR waitSemaphoreSubmitInfo =
661 		makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[FIRST], VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
662 
663 	{
664 		SynchronizationWrapperPtr synchronizationWrapper[]
665 		{
666 			getSynchronizationWrapper(config.type, vk, isTimelineSemaphore),
667 			getSynchronizationWrapper(config.type, vk, isTimelineSemaphore)
668 		};
669 		synchronizationWrapper[FIRST]->addSubmitInfo(
670 			0u,													// deUint32								waitSemaphoreInfoCount
671 			DE_NULL,											// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
672 			1u,													// deUint32								commandBufferInfoCount
673 			&commandBufferInfo[FIRST],							// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
674 			1u,													// deUint32								signalSemaphoreInfoCount
675 			&signalSemaphoreSubmitInfo[FIRST],					// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
676 			DE_FALSE,
677 			isTimelineSemaphore
678 		);
679 		synchronizationWrapper[SECOND]->addSubmitInfo(
680 			1u,													// deUint32								waitSemaphoreInfoCount
681 			&waitSemaphoreSubmitInfo,							// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
682 			1u,													// deUint32								commandBufferInfoCount
683 			&commandBufferInfo[SECOND],							// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
684 			1u,													// deUint32								signalSemaphoreInfoCount
685 			&signalSemaphoreSubmitInfo[SECOND],					// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
686 			isTimelineSemaphore,
687 			isTimelineSemaphore
688 		);
689 		VK_CHECK(synchronizationWrapper[FIRST]->queueSubmit(queues[FIRST].queue, *fence[FIRST]));
690 		VK_CHECK(synchronizationWrapper[SECOND]->queueSubmit(queues[SECOND].queue, *fence[SECOND]));
691 	}
692 
693 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
694 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
695 
696 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
697 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
698 
699 	if (isTimelineSemaphore)
700 	{
701 		signalSemaphoreSubmitInfo[FIRST].value	= 3ull;
702 		signalSemaphoreSubmitInfo[SECOND].value	= 4ull;
703 		waitSemaphoreSubmitInfo.value			= 3ull;
704 	}
705 
706 	// swap semaphore info compared to above submits
707 	{
708 		SynchronizationWrapperPtr synchronizationWrapper[]
709 		{
710 			getSynchronizationWrapper(config.type, vk, isTimelineSemaphore),
711 			getSynchronizationWrapper(config.type, vk, isTimelineSemaphore)
712 		};
713 		synchronizationWrapper[FIRST]->addSubmitInfo(
714 			1u,													// deUint32								waitSemaphoreInfoCount
715 			&waitSemaphoreSubmitInfo,							// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
716 			1u,													// deUint32								commandBufferInfoCount
717 			&commandBufferInfo[FIRST],							// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
718 			1u,													// deUint32								signalSemaphoreInfoCount
719 			&signalSemaphoreSubmitInfo[SECOND],					// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
720 			isTimelineSemaphore,
721 			isTimelineSemaphore
722 		);
723 		synchronizationWrapper[SECOND]->addSubmitInfo(
724 			isTimelineSemaphore ? 0u : 1u,								// deUint32								waitSemaphoreInfoCount
725 			isTimelineSemaphore ? DE_NULL : &waitSemaphoreSubmitInfo,	// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
726 			1u,															// deUint32								commandBufferInfoCount
727 			&commandBufferInfo[SECOND],									// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
728 			1u,															// deUint32								signalSemaphoreInfoCount
729 			&signalSemaphoreSubmitInfo[FIRST],							// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
730 			DE_FALSE,
731 			isTimelineSemaphore
732 		);
733 
734 		VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[FIRST].get()));
735 		VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[SECOND].get()));
736 		VK_CHECK(synchronizationWrapper[SECOND]->queueSubmit(queues[SECOND].queue, *fence[SECOND]));
737 		VK_CHECK(synchronizationWrapper[FIRST]->queueSubmit(queues[FIRST].queue, *fence[FIRST]));
738 	}
739 
740 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
741 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
742 
743 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
744 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
745 
746 	return tcu::TestStatus::pass("Basic semaphore tests with multi queue passed");
747 }
748 
checkSupport(Context & context,TestConfig config)749 void checkSupport (Context& context, TestConfig config)
750 {
751 	if (config.videoCodecOperationFlags != 0)
752 		VideoDevice::checkSupport(context, config.videoCodecOperationFlags);
753 
754 	if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
755 		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
756 
757 	if (config.type == SynchronizationType::SYNCHRONIZATION2)
758 		context.requireDeviceFunctionality("VK_KHR_synchronization2");
759 }
760 
checkCommandBufferSimultaneousUseSupport(Context & context,TestConfig config)761 void checkCommandBufferSimultaneousUseSupport (Context& context, TestConfig config)
762 {
763 	checkSupport(context, config);
764 
765 #ifdef CTS_USES_VULKANSC
766 	if (context.getDeviceVulkanSC10Properties().commandBufferSimultaneousUse == VK_FALSE)
767 		TCU_THROW(NotSupportedError, "commandBufferSimultaneousUse is not supported");
768 #endif
769 }
770 
771 } // anonymous
772 
createBasicBinarySemaphoreTests(tcu::TestContext & testCtx,SynchronizationType type,VideoCodecOperationFlags videoCodecOperationFlags)773 tcu::TestCaseGroup* createBasicBinarySemaphoreTests (tcu::TestContext& testCtx, SynchronizationType type, VideoCodecOperationFlags videoCodecOperationFlags)
774 {
775 	de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "binary_semaphore", "Basic semaphore tests"));
776 
777 	TestConfig config =
778 	{
779 		0,
780 		VK_SEMAPHORE_TYPE_BINARY,
781 		type,
782 		videoCodecOperationFlags,
783 	};
784 	for (deUint32 typedCreate = 0; typedCreate < 2; typedCreate++)
785 	{
786 		config.useTypeCreate = (typedCreate != 0);
787 		const std::string createName = config.useTypeCreate ? "_typed" : "";
788 
789 		addFunctionCase(basicTests.get(), "one_queue" + createName,		"Basic binary semaphore tests with one queue",		checkCommandBufferSimultaneousUseSupport,	basicOneQueueCase, config);
790 		addFunctionCase(basicTests.get(), "multi_queue" + createName,	"Basic binary semaphore tests with multi queue",	checkCommandBufferSimultaneousUseSupport,	basicMultiQueueCase, config);
791 	}
792 
793 	if (type == SynchronizationType::SYNCHRONIZATION2)
794 		addFunctionCase(basicTests.get(), "none_wait_submit", "Test waiting on the none pipeline stage",	checkCommandBufferSimultaneousUseSupport, noneWaitSubmitTest, config);
795 
796 	addFunctionCase(basicTests.get(), "chain", "Binary semaphore chain test", checkSupport, basicChainCase, config);
797 
798 	return basicTests.release();
799 }
800 
createBasicTimelineSemaphoreTests(tcu::TestContext & testCtx,SynchronizationType type,VideoCodecOperationFlags videoCodecOperationFlags)801 tcu::TestCaseGroup* createBasicTimelineSemaphoreTests (tcu::TestContext& testCtx, SynchronizationType type, VideoCodecOperationFlags videoCodecOperationFlags)
802 {
803 	de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "timeline_semaphore", "Basic timeline semaphore tests"));
804 	const TestConfig				config =
805 	{
806 		true,
807 		VK_SEMAPHORE_TYPE_TIMELINE,
808 		type,
809 		videoCodecOperationFlags,
810 	};
811 
812 	addFunctionCase(basicTests.get(), "one_queue",		"Basic timeline semaphore tests with one queue",	checkCommandBufferSimultaneousUseSupport,	basicOneQueueCase, config);
813 	addFunctionCase(basicTests.get(), "multi_queue",	"Basic timeline semaphore tests with multi queue",	checkCommandBufferSimultaneousUseSupport,	basicMultiQueueCase, config);
814 	addFunctionCase(basicTests.get(), "chain",			"Timeline semaphore chain test",					checkSupport, basicChainTimelineCase, config);
815 
816 	// dont repeat this test for synchronization2
817 	if (type == SynchronizationType::LEGACY)
818 		addFunctionCase(basicTests.get(), "two_threads","Timeline semaphore used by two threads",			checkSupport, basicThreadTimelineCase, config);
819 
820 	return basicTests.release();
821 }
822 
823 } // synchronization
824 } // vkt
825