• 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 
basicWaitForTimelineValueHelper(Context & context,TestConfig config,VkSemaphoreWaitFlags wait_flags,deUint64 signal_value,deUint64 wait_value)411 VkResult basicWaitForTimelineValueHelper(Context& context, TestConfig config, VkSemaphoreWaitFlags wait_flags, deUint64 signal_value, deUint64 wait_value) {
412 	const VkSemaphoreTypeCreateInfo		scti			= { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, DE_NULL, VK_SEMAPHORE_TYPE_TIMELINE, 0 };
413 	de::MovePtr<VideoDevice>			videoDevice		(config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
414 	const DeviceInterface&				vk				= getSyncDeviceInterface(videoDevice, context);
415 	const VkDevice						device			= getSyncDevice(videoDevice, context);
416 	const VkSemaphoreCreateInfo			sci				= { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &scti, 0 };
417 	const VkFenceCreateInfo				fci				= { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
418 	const vk::Unique<vk::VkSemaphore>	semaphore		(createSemaphore(vk, device, &sci));
419 	const Unique<VkFence>				fence			(createFence(vk, device, &fci));
420 	const deUint64						waitTimeout		= 0;		// return immediately
421 
422 	// helper creating VkSemaphoreSignalInfo
423 	auto makeSemaphoreSignalInfo = [&semaphore](deUint64 value) -> VkSemaphoreSignalInfo
424 	{
425 		return
426 		{
427 			VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,		// VkStructureType				sType
428 			DE_NULL,										// const void*					pNext
429 			*semaphore,										// VkSemaphore					semaphore
430 			value											// deUint64						value
431 		};
432 	};
433 
434 	// helper creating VkSemaphoreWaitInfo
435 	auto makeSemaphoreWaitInfo = [&semaphore](VkSemaphoreWaitFlags flags, deUint64* valuePtr) -> VkSemaphoreWaitInfo
436 	{
437 		return
438 		{
439 			VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,			// VkStructureType				sType
440 			DE_NULL,										// const void*					pNext
441 			flags,											// VkSemaphoreWaitFlags			flags;
442 			1u,												// deUint32						semaphoreCount;
443 			&*semaphore,									// const VkSemaphore*			pSemaphores;
444 			valuePtr										// const deUint64*				pValues;
445 		};
446 	};
447 
448 	VkSemaphoreSignalInfo signalTheValue = makeSemaphoreSignalInfo(signal_value);
449 	vk.signalSemaphore(device, &signalTheValue);
450 
451     VkSemaphoreWaitInfo waitForTheValue = makeSemaphoreWaitInfo(wait_flags, &wait_value);
452     return vk.waitSemaphores(device, &waitForTheValue, waitTimeout);
453 }
454 
basicWaitForAnyCurrentTimelineValueCase(Context & context,TestConfig config)455 tcu::TestStatus basicWaitForAnyCurrentTimelineValueCase(Context& context, TestConfig config)
456 {
457   VkResult mainResult = basicWaitForTimelineValueHelper(context, config, VK_SEMAPHORE_WAIT_ANY_BIT, 1, 1);
458   if (mainResult == VK_SUCCESS)
459     return tcu::TestStatus::pass("Pass");
460 
461   return tcu::TestStatus::fail("Fail");
462 }
463 
basicWaitForAnyLesserTimelineValueCase(Context & context,TestConfig config)464 tcu::TestStatus basicWaitForAnyLesserTimelineValueCase(Context& context, TestConfig config)
465 {
466   VkResult mainResult = basicWaitForTimelineValueHelper(context, config, VK_SEMAPHORE_WAIT_ANY_BIT, 4, 1);
467   if (mainResult == VK_SUCCESS)
468     return tcu::TestStatus::pass("Pass");
469 
470   return tcu::TestStatus::fail("Fail");
471 }
472 
basicWaitForAllCurrentTimelineValueCase(Context & context,TestConfig config)473 tcu::TestStatus basicWaitForAllCurrentTimelineValueCase(Context& context, TestConfig config)
474 {
475   VkResult mainResult = basicWaitForTimelineValueHelper(context, config, 0, 1, 1);
476   if (mainResult == VK_SUCCESS)
477     return tcu::TestStatus::pass("Pass");
478 
479   return tcu::TestStatus::fail("Fail");
480 }
481 
basicWaitForAllLesserTimelineValueCase(Context & context,TestConfig config)482 tcu::TestStatus basicWaitForAllLesserTimelineValueCase(Context& context, TestConfig config)
483 {
484   VkResult mainResult = basicWaitForTimelineValueHelper(context, config, 0, 4, 1);
485   if (mainResult == VK_SUCCESS)
486     return tcu::TestStatus::pass("Pass");
487 
488   return tcu::TestStatus::fail("Fail");
489 }
490 
basicMultiQueueCase(Context & context,TestConfig config)491 tcu::TestStatus basicMultiQueueCase (Context& context, TestConfig config)
492 {
493 	enum { NO_MATCH_FOUND = ~((deUint32)0) };
494 	enum QueuesIndexes { FIRST = 0, SECOND, COUNT };
495 
496 	struct Queues
497 	{
498 		VkQueue		queue;
499 		deUint32	queueFamilyIndex;
500 	};
501 
502 #ifndef CTS_USES_VULKANSC
503 	const VkInstance								instance						= context.getInstance();
504 	const InstanceInterface&						instanceInterface				= context.getInstanceInterface();
505 	const VkPhysicalDevice							physicalDevice					= context.getPhysicalDevice();
506 	de::MovePtr<VideoDevice>						videoDevice						(config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
507 	const DeviceInterface&							vk								= getSyncDeviceInterface(videoDevice, context);
508 	std::vector<VkQueueFamilyVideoPropertiesKHR>	videoQueueFamilyProperties2;
509 #else
510 	const CustomInstance							instance						(createCustomInstanceFromContext(context));
511 	const InstanceDriver&							instanceDriver					(instance.getDriver());
512 	const VkPhysicalDevice							physicalDevice					= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
513 	const InstanceInterface&						instanceInterface				= instanceDriver;
514 //	const DeviceInterface&							vk								= context.getDeviceInterface();
515 //	const InstanceInterface&						instance						= context.getInstanceInterface();
516 //	const VkPhysicalDevice							physicalDevice					= context.getPhysicalDevice();
517 #endif // CTS_USES_VULKANSC
518 	vk::Move<vk::VkDevice>							logicalDevice;
519 	std::vector<VkQueueFamilyProperties>			queueFamilyProperties;
520 	std::vector<VkQueueFamilyProperties2>			queueFamilyProperties2;
521 	VkDeviceCreateInfo								deviceInfo;
522 	VkPhysicalDeviceFeatures						deviceFeatures;
523 	const float										queuePriorities[COUNT]	= { 1.0f, 1.0f };
524 	VkDeviceQueueCreateInfo							queueInfos[COUNT];
525 	Queues											queues[COUNT] =
526 	{
527 		{DE_NULL, (deUint32)NO_MATCH_FOUND},
528 		{DE_NULL, (deUint32)NO_MATCH_FOUND}
529 	};
530 	const VkCommandBufferBeginInfo			info =
531 	{
532 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
533 		DE_NULL,										// const void*                              pNext;
534 		VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,	// VkCommandBufferUsageFlags                flags;
535 		DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
536 	};
537 
538 	const bool								isTimelineSemaphore = config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE;
539 
540 	if (config.videoCodecOperationFlags != 0)
541 	{
542 #ifndef CTS_USES_VULKANSC
543 		uint32_t	queueFamilyPropertiesCount	= 0;
544 
545 		instanceInterface.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
546 
547 		if (queueFamilyPropertiesCount > 0)
548 		{
549 			queueFamilyProperties2.resize(queueFamilyPropertiesCount);
550 			videoQueueFamilyProperties2.resize(queueFamilyPropertiesCount);
551 
552 			for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
553 			{
554 				queueFamilyProperties2[ndx].sType						= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
555 				queueFamilyProperties2[ndx].pNext						= &videoQueueFamilyProperties2[ndx];
556 				videoQueueFamilyProperties2[ndx].sType					= vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
557 				videoQueueFamilyProperties2[ndx].pNext					= DE_NULL;
558 				videoQueueFamilyProperties2[ndx].videoCodecOperations	= 0;
559 			}
560 
561 			instanceInterface.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties2.data());
562 
563 			if (queueFamilyPropertiesCount != queueFamilyProperties2.size())
564 				TCU_FAIL("Device returns less queue families than initially reported");
565 
566 			queueFamilyProperties.reserve(queueFamilyPropertiesCount);
567 
568 			for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
569 				queueFamilyProperties.push_back(queueFamilyProperties2[ndx].queueFamilyProperties);
570 		}
571 #endif // CTS_USES_VULKANSC
572 	}
573 	else
574 	{
575 		queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceInterface, physicalDevice);
576 	}
577 
578 	for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
579 	{
580 #ifndef CTS_USES_VULKANSC
581 		const bool usableQueue	=  videoQueueFamilyProperties2.empty()
582 								|| (videoQueueFamilyProperties2[queueNdx].videoCodecOperations & config.videoCodecOperationFlags) != 0;
583 
584 		if (!usableQueue)
585 			continue;
586 #endif // CTS_USES_VULKANSC
587 
588 		if (NO_MATCH_FOUND == queues[FIRST].queueFamilyIndex)
589 			queues[FIRST].queueFamilyIndex = queueNdx;
590 
591 		if (queues[FIRST].queueFamilyIndex != queueNdx || queueFamilyProperties[queueNdx].queueCount > 1u)
592 		{
593 			queues[SECOND].queueFamilyIndex = queueNdx;
594 			break;
595 		}
596 	}
597 
598 	if (queues[FIRST].queueFamilyIndex == NO_MATCH_FOUND || queues[SECOND].queueFamilyIndex == NO_MATCH_FOUND)
599 		TCU_THROW(NotSupportedError, "Queues couldn't be created");
600 
601 	for (int queueNdx = 0; queueNdx < COUNT; ++queueNdx)
602 	{
603 		VkDeviceQueueCreateInfo queueInfo;
604 		deMemset(&queueInfo, 0, sizeof(queueInfo));
605 
606 		queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
607 		queueInfo.pNext = DE_NULL;
608 		queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
609 		queueInfo.queueFamilyIndex = queues[queueNdx].queueFamilyIndex;
610 		queueInfo.queueCount = (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 2 : 1;
611 		queueInfo.pQueuePriorities = queuePriorities;
612 
613 		queueInfos[queueNdx] = queueInfo;
614 
615 		if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
616 			break;
617 	}
618 
619 	deMemset(&deviceInfo, 0, sizeof(deviceInfo));
620 	instanceInterface.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
621 
622 	VkPhysicalDeviceFeatures2					createPhysicalFeature		{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, DE_NULL, deviceFeatures };
623 	VkPhysicalDeviceTimelineSemaphoreFeatures	timelineSemaphoreFeatures	{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, DE_NULL, DE_TRUE };
624 	VkPhysicalDeviceSynchronization2FeaturesKHR	synchronization2Features	{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR, DE_NULL, DE_TRUE };
625 	void**										nextPtr						= &createPhysicalFeature.pNext;
626 
627 	std::vector<const char*> deviceExtensions;
628 
629 	if (config.videoCodecOperationFlags != 0)
630 		VideoDevice::addVideoDeviceExtensions(deviceExtensions, context.getUsedApiVersion(), VideoDevice::getQueueFlags(config.videoCodecOperationFlags), config.videoCodecOperationFlags);
631 
632 	if (isTimelineSemaphore)
633 	{
634 		if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_timeline_semaphore"))
635 			deviceExtensions.push_back("VK_KHR_timeline_semaphore");
636 		addToChainVulkanStructure(&nextPtr, timelineSemaphoreFeatures);
637 	}
638 	if (config.type == SynchronizationType::SYNCHRONIZATION2)
639 	{
640 		deviceExtensions.push_back("VK_KHR_synchronization2");
641 		addToChainVulkanStructure(&nextPtr, synchronization2Features);
642 	}
643 
644 	void* pNext												= &createPhysicalFeature;
645 #ifdef CTS_USES_VULKANSC
646 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
647 	memReservationInfo.pNext								= pNext;
648 	pNext													= &memReservationInfo;
649 
650 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
651 	sc10Features.pNext										= pNext;
652 	pNext													= &sc10Features;
653 
654 	VkPipelineCacheCreateInfo			pcCI;
655 	std::vector<VkPipelinePoolSize>		poolSizes;
656 	if (context.getTestContext().getCommandLine().isSubProcess())
657 	{
658 		if (context.getResourceInterface()->getCacheDataSize() > 0)
659 		{
660 			pcCI =
661 			{
662 				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,		// VkStructureType				sType;
663 				DE_NULL,											// const void*					pNext;
664 				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
665 					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
666 				context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
667 				context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
668 			};
669 			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
670 			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
671 		}
672 
673 		poolSizes							= context.getResourceInterface()->getPipelinePoolSizes();
674 		if (!poolSizes.empty())
675 		{
676 			memReservationInfo.pipelinePoolSizeCount			= deUint32(poolSizes.size());
677 			memReservationInfo.pPipelinePoolSizes				= poolSizes.data();
678 		}
679 	}
680 #endif // CTS_USES_VULKANSC
681 
682 	deviceInfo.sType					= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
683 	deviceInfo.pNext					= pNext;
684 	deviceInfo.enabledExtensionCount	= static_cast<deUint32>(deviceExtensions.size());
685 	deviceInfo.ppEnabledExtensionNames	= deviceExtensions.empty() ? DE_NULL : deviceExtensions.data();
686 	deviceInfo.enabledLayerCount		= 0u;
687 	deviceInfo.ppEnabledLayerNames		= DE_NULL;
688 	deviceInfo.pEnabledFeatures			= 0u;
689 	deviceInfo.queueCreateInfoCount		= (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 1 : COUNT;
690 	deviceInfo.pQueueCreateInfos		= queueInfos;
691 
692 	logicalDevice = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instance, instanceInterface, physicalDevice, &deviceInfo);
693 
694 #ifndef CTS_USES_VULKANSC
695 	de::MovePtr<vk::DeviceDriver>								deviceDriver	= de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), instance, *logicalDevice, context.getUsedApiVersion()));
696 #else
697 	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(), context.getUsedApiVersion()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), *logicalDevice));
698 	const DeviceInterface&										vk				= *deviceDriver;
699 #endif // CTS_USES_VULKANSC
700 
701 	for (deUint32 queueReqNdx = 0; queueReqNdx < COUNT; ++queueReqNdx)
702 	{
703 		if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
704 			vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, queueReqNdx, &queues[queueReqNdx].queue);
705 		else
706 			vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, 0u, &queues[queueReqNdx].queue);
707 	}
708 
709 	Move<VkSemaphore>						semaphore;
710 	Move<VkCommandPool>						cmdPool[COUNT];
711 	Move<VkCommandBuffer>					cmdBuffer[COUNT];
712 	deUint64								timelineValues[COUNT] = { 1ull, 2ull };
713 	Move<VkFence>							fence[COUNT];
714 
715 	semaphore			= (createTestSemaphore(context, vk, *logicalDevice, config));
716 	cmdPool[FIRST]		= (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[FIRST].queueFamilyIndex));
717 	cmdPool[SECOND]		= (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[SECOND].queueFamilyIndex));
718 	cmdBuffer[FIRST]	= (makeCommandBuffer(vk, *logicalDevice, *cmdPool[FIRST]));
719 	cmdBuffer[SECOND]	= (makeCommandBuffer(vk, *logicalDevice, *cmdPool[SECOND]));
720 
721 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[FIRST], &info));
722 	endCommandBuffer(vk, *cmdBuffer[FIRST]);
723 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[SECOND], &info));
724 	endCommandBuffer(vk, *cmdBuffer[SECOND]);
725 
726 	fence[FIRST] = (createFence(vk, *logicalDevice));
727 	fence[SECOND] = (createFence(vk, *logicalDevice));
728 
729 	VkCommandBufferSubmitInfoKHR commandBufferInfo[]
730 	{
731 		makeCommonCommandBufferSubmitInfo(*cmdBuffer[FIRST]),
732 		makeCommonCommandBufferSubmitInfo(*cmdBuffer[SECOND])
733 	};
734 
735 	VkSemaphoreSubmitInfoKHR signalSemaphoreSubmitInfo[]
736 	{
737 		makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[FIRST], VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR),
738 		makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[SECOND], VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR)
739 	};
740 	VkSemaphoreSubmitInfoKHR waitSemaphoreSubmitInfo =
741 		makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[FIRST], VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
742 
743 	{
744 		SynchronizationWrapperPtr synchronizationWrapper[]
745 		{
746 			getSynchronizationWrapper(config.type, vk, isTimelineSemaphore),
747 			getSynchronizationWrapper(config.type, vk, isTimelineSemaphore)
748 		};
749 		synchronizationWrapper[FIRST]->addSubmitInfo(
750 			0u,													// deUint32								waitSemaphoreInfoCount
751 			DE_NULL,											// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
752 			1u,													// deUint32								commandBufferInfoCount
753 			&commandBufferInfo[FIRST],							// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
754 			1u,													// deUint32								signalSemaphoreInfoCount
755 			&signalSemaphoreSubmitInfo[FIRST],					// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
756 			DE_FALSE,
757 			isTimelineSemaphore
758 		);
759 		synchronizationWrapper[SECOND]->addSubmitInfo(
760 			1u,													// deUint32								waitSemaphoreInfoCount
761 			&waitSemaphoreSubmitInfo,							// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
762 			1u,													// deUint32								commandBufferInfoCount
763 			&commandBufferInfo[SECOND],							// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
764 			1u,													// deUint32								signalSemaphoreInfoCount
765 			&signalSemaphoreSubmitInfo[SECOND],					// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
766 			isTimelineSemaphore,
767 			isTimelineSemaphore
768 		);
769 		VK_CHECK(synchronizationWrapper[FIRST]->queueSubmit(queues[FIRST].queue, *fence[FIRST]));
770 		VK_CHECK(synchronizationWrapper[SECOND]->queueSubmit(queues[SECOND].queue, *fence[SECOND]));
771 	}
772 
773 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
774 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
775 
776 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
777 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
778 
779 	if (isTimelineSemaphore)
780 	{
781 		signalSemaphoreSubmitInfo[FIRST].value	= 3ull;
782 		signalSemaphoreSubmitInfo[SECOND].value	= 4ull;
783 		waitSemaphoreSubmitInfo.value			= 3ull;
784 	}
785 
786 	// swap semaphore info compared to above submits
787 	{
788 		SynchronizationWrapperPtr synchronizationWrapper[]
789 		{
790 			getSynchronizationWrapper(config.type, vk, isTimelineSemaphore),
791 			getSynchronizationWrapper(config.type, vk, isTimelineSemaphore)
792 		};
793 		synchronizationWrapper[FIRST]->addSubmitInfo(
794 			1u,													// deUint32								waitSemaphoreInfoCount
795 			&waitSemaphoreSubmitInfo,							// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
796 			1u,													// deUint32								commandBufferInfoCount
797 			&commandBufferInfo[FIRST],							// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
798 			1u,													// deUint32								signalSemaphoreInfoCount
799 			&signalSemaphoreSubmitInfo[SECOND],					// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
800 			isTimelineSemaphore,
801 			isTimelineSemaphore
802 		);
803 		synchronizationWrapper[SECOND]->addSubmitInfo(
804 			isTimelineSemaphore ? 0u : 1u,								// deUint32								waitSemaphoreInfoCount
805 			isTimelineSemaphore ? DE_NULL : &waitSemaphoreSubmitInfo,	// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
806 			1u,															// deUint32								commandBufferInfoCount
807 			&commandBufferInfo[SECOND],									// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
808 			1u,															// deUint32								signalSemaphoreInfoCount
809 			&signalSemaphoreSubmitInfo[FIRST],							// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
810 			DE_FALSE,
811 			isTimelineSemaphore
812 		);
813 
814 		VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[FIRST].get()));
815 		VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[SECOND].get()));
816 		VK_CHECK(synchronizationWrapper[SECOND]->queueSubmit(queues[SECOND].queue, *fence[SECOND]));
817 		VK_CHECK(synchronizationWrapper[FIRST]->queueSubmit(queues[FIRST].queue, *fence[FIRST]));
818 	}
819 
820 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
821 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
822 
823 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
824 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
825 
826 	return tcu::TestStatus::pass("Basic semaphore tests with multi queue passed");
827 }
828 
checkSupport(Context & context,TestConfig config)829 void checkSupport (Context& context, TestConfig config)
830 {
831 	if (config.videoCodecOperationFlags != 0)
832 		VideoDevice::checkSupport(context, config.videoCodecOperationFlags);
833 
834 	if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
835 		context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
836 
837 	if (config.type == SynchronizationType::SYNCHRONIZATION2)
838 		context.requireDeviceFunctionality("VK_KHR_synchronization2");
839 }
840 
checkCommandBufferSimultaneousUseSupport(Context & context,TestConfig config)841 void checkCommandBufferSimultaneousUseSupport (Context& context, TestConfig config)
842 {
843 	checkSupport(context, config);
844 
845 #ifdef CTS_USES_VULKANSC
846 	if (context.getDeviceVulkanSC10Properties().commandBufferSimultaneousUse == VK_FALSE)
847 		TCU_THROW(NotSupportedError, "commandBufferSimultaneousUse is not supported");
848 #endif
849 }
850 
851 } // anonymous
852 
createBasicBinarySemaphoreTests(tcu::TestContext & testCtx,SynchronizationType type,VideoCodecOperationFlags videoCodecOperationFlags)853 tcu::TestCaseGroup* createBasicBinarySemaphoreTests (tcu::TestContext& testCtx, SynchronizationType type, VideoCodecOperationFlags videoCodecOperationFlags)
854 {
855 	de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "binary_semaphore"));
856 
857 	TestConfig config =
858 	{
859 		0,
860 		VK_SEMAPHORE_TYPE_BINARY,
861 		type,
862 		videoCodecOperationFlags,
863 	};
864 	for (deUint32 typedCreate = 0; typedCreate < 2; typedCreate++)
865 	{
866 		config.useTypeCreate = (typedCreate != 0);
867 		const std::string createName = config.useTypeCreate ? "_typed" : "";
868 
869 		// Basic binary semaphore tests with one queue
870 		addFunctionCase(basicTests.get(), "one_queue" + createName, checkCommandBufferSimultaneousUseSupport,	basicOneQueueCase, config);
871 		// Basic binary semaphore tests with multi queue
872 		addFunctionCase(basicTests.get(), "multi_queue" + createName, checkCommandBufferSimultaneousUseSupport,	basicMultiQueueCase, config);
873 	}
874 
875 	if (type == SynchronizationType::SYNCHRONIZATION2)
876 		// Test waiting on the none pipeline stage
877 		addFunctionCase(basicTests.get(), "none_wait_submit", checkCommandBufferSimultaneousUseSupport, noneWaitSubmitTest, config);
878 
879 	// Binary semaphore chain test
880 	addFunctionCase(basicTests.get(), "chain", checkSupport, basicChainCase, config);
881 
882 	return basicTests.release();
883 }
884 
createBasicTimelineSemaphoreTests(tcu::TestContext & testCtx,SynchronizationType type,VideoCodecOperationFlags videoCodecOperationFlags)885 tcu::TestCaseGroup* createBasicTimelineSemaphoreTests (tcu::TestContext& testCtx, SynchronizationType type, VideoCodecOperationFlags videoCodecOperationFlags)
886 {
887 	// Basic timeline semaphore tests
888 	de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "timeline_semaphore"));
889 	const TestConfig				config =
890 	{
891 		true,
892 		VK_SEMAPHORE_TYPE_TIMELINE,
893 		type,
894 		videoCodecOperationFlags,
895 	};
896 
897 	// Basic timeline semaphore tests with one queue
898 	addFunctionCase(basicTests.get(), "one_queue", checkCommandBufferSimultaneousUseSupport,	basicOneQueueCase, config);
899 	// Basic timeline semaphore tests with multi queue
900 	addFunctionCase(basicTests.get(), "multi_queue", checkCommandBufferSimultaneousUseSupport,	basicMultiQueueCase, config);
901 	// Timeline semaphore chain test
902 	addFunctionCase(basicTests.get(), "chain", checkSupport, basicChainTimelineCase, config);
903 
904 	// dont repeat this test for synchronization2
905 	if (type == SynchronizationType::LEGACY) {
906 		// Timeline semaphore used by two threads
907 		addFunctionCase(basicTests.get(), "two_threads", checkSupport, basicThreadTimelineCase, config);
908 		// Wait for the currently signalled timeline semaphore value (wait for any)
909 		addFunctionCase(basicTests.get(), "wait_for_any_current_value", checkSupport, basicWaitForAnyCurrentTimelineValueCase, config);
910 		// Wait for a value less than the currently signalled timeline semaphore value (wait for any)
911 		addFunctionCase(basicTests.get(), "wait_for_any_lesser_value", checkSupport, basicWaitForAnyLesserTimelineValueCase, config);
912 		// Wait for the currently signalled timeline semaphore value (wait for all)
913 		addFunctionCase(basicTests.get(), "wait_for_all_current_value", checkSupport, basicWaitForAllCurrentTimelineValueCase, config);
914 		// Wait for a value less than the currently signalled timeline semaphore value (wait for all)
915 		addFunctionCase(basicTests.get(), "wait_for_all_lesser_value", checkSupport, basicWaitForAllLesserTimelineValueCase, config);
916     }
917 
918 	return basicTests.release();
919 }
920 
921 } // synchronization
922 } // vkt
923