• 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 event basic tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSynchronizationBasicEventTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktSynchronizationUtil.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkRef.hpp"
31 #include "vkCmdUtil.hpp"
32 
33 namespace vkt
34 {
35 namespace synchronization
36 {
37 namespace
38 {
39 
40 using namespace vk;
41 #define SHORT_FENCE_WAIT	1000ull
42 #define LONG_FENCE_WAIT		~0ull
43 
44 struct TestConfig
45 {
46 	SynchronizationType		type;
47 	VkEventCreateFlags		flags;
48 };
49 
hostResetSetEventCase(Context & context,TestConfig config)50 tcu::TestStatus hostResetSetEventCase (Context& context, TestConfig config)
51 {
52 	const DeviceInterface&		vk			= context.getDeviceInterface();
53 	const VkDevice				device		= context.getDevice();
54 	const VkEventCreateInfo		eventInfo	=
55 											{
56 												VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
57 												DE_NULL,
58 												0
59 											};
60 	VkEvent						event;
61 	Move<VkEvent>				ptrEvent;
62 
63 	DE_UNREF(config);
64 
65 	if (VK_SUCCESS != vk.createEvent(device, &eventInfo, DE_NULL, &event))
66 		return tcu::TestStatus::fail("Couldn't create event");
67 
68 	ptrEvent = Move<VkEvent>(check<VkEvent>(event), Deleter<VkEvent>(vk, device, DE_NULL));
69 
70 	if (VK_EVENT_RESET != vk.getEventStatus(device, event))
71 		return tcu::TestStatus::fail("Created event should be in unsignaled state");
72 
73 	if (VK_SUCCESS != vk.setEvent(device, event))
74 		return tcu::TestStatus::fail("Couldn't set event");
75 
76 	if (VK_EVENT_SET != vk.getEventStatus(device, event))
77 		return tcu::TestStatus::fail("Event should be in signaled state after set");
78 
79 	if (VK_SUCCESS != vk.resetEvent(device, event))
80 		return tcu::TestStatus::fail("Couldn't reset event");
81 
82 	if (VK_EVENT_RESET != vk.getEventStatus(device, event))
83 		return tcu::TestStatus::fail("Event should be in unsignaled state after reset");
84 
85 	return tcu::TestStatus::pass("Tests set and reset event on host pass");
86 }
87 
deviceResetSetEventCase(Context & context,TestConfig config)88 tcu::TestStatus deviceResetSetEventCase (Context& context, TestConfig config)
89 {
90 	const DeviceInterface&				vk						= context.getDeviceInterface();
91 	const VkDevice						device					= context.getDevice();
92 	const VkQueue						queue					= context.getUniversalQueue();
93 	const deUint32						queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
94 	const Unique<VkCommandPool>			cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
95 	const Unique<VkCommandBuffer>		cmdBuffer				(makeCommandBuffer(vk, device, *cmdPool));
96 	const Unique<VkEvent>				event					(createEvent(vk, device));
97 	const VkCommandBufferSubmitInfoKHR	commandBufferSubmitInfo = makeCommonCommandBufferSubmitInfo(cmdBuffer.get());
98 	const VkMemoryBarrier2KHR			memoryBarrier2			=
99 	{
100 		VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR,				// VkStructureType					sType
101 		DE_NULL,											// const void*						pNext
102 		VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR,			// VkPipelineStageFlags2KHR			srcStageMask
103 		VK_ACCESS_2_NONE_KHR,								// VkAccessFlags2KHR				srcAccessMask
104 		VK_PIPELINE_STAGE_2_HOST_BIT_KHR,					// VkPipelineStageFlags2KHR			dstStageMask
105 		VK_ACCESS_2_HOST_READ_BIT_KHR						// VkAccessFlags2KHR				dstAccessMask
106 	};
107 	VkDependencyInfoKHR					dependencyInfo			= makeCommonDependencyInfo(&memoryBarrier2);
108 
109 	{
110 		SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_FALSE);
111 
112 		beginCommandBuffer(vk, *cmdBuffer);
113 		synchronizationWrapper->cmdSetEvent(*cmdBuffer, *event, &dependencyInfo);
114 		endCommandBuffer(vk, *cmdBuffer);
115 
116 		synchronizationWrapper->addSubmitInfo(
117 			0u,										// deUint32								waitSemaphoreInfoCount
118 			DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
119 			1u,										// deUint32								commandBufferInfoCount
120 			&commandBufferSubmitInfo,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
121 			0u,										// deUint32								signalSemaphoreInfoCount
122 			DE_NULL									// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
123 		);
124 
125 		VK_CHECK(synchronizationWrapper->queueSubmit(queue, DE_NULL));
126 	}
127 
128 	VK_CHECK(vk.queueWaitIdle(queue));
129 
130 	if (VK_EVENT_SET != vk.getEventStatus(device, *event))
131 		return tcu::TestStatus::fail("Event should be in signaled state after set");
132 
133 	{
134 		SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_FALSE);
135 
136 		beginCommandBuffer(vk, *cmdBuffer);
137 		synchronizationWrapper->cmdResetEvent(*cmdBuffer, *event, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
138 		endCommandBuffer(vk, *cmdBuffer);
139 
140 		synchronizationWrapper->addSubmitInfo(
141 			0u,										// deUint32								waitSemaphoreInfoCount
142 			DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
143 			1u,										// deUint32								commandBufferInfoCount
144 			&commandBufferSubmitInfo,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
145 			0u,										// deUint32								signalSemaphoreInfoCount
146 			DE_NULL									// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
147 		);
148 
149 		VK_CHECK(synchronizationWrapper->queueSubmit(queue, DE_NULL));
150 	}
151 
152 	VK_CHECK(vk.queueWaitIdle(queue));
153 
154 	if (VK_EVENT_RESET != vk.getEventStatus(device, *event))
155 		return tcu::TestStatus::fail("Event should be in unsignaled state after set");
156 
157 	return tcu::TestStatus::pass("Device set and reset event tests pass");
158 }
159 
singleSubmissionCase(Context & context,TestConfig config)160 tcu::TestStatus singleSubmissionCase (Context& context, TestConfig config)
161 {
162 	enum {SET=0, WAIT, COUNT};
163 	const DeviceInterface&			vk							= context.getDeviceInterface();
164 	const VkDevice					device						= context.getDevice();
165 	const VkQueue					queue						= context.getUniversalQueue();
166 	const deUint32					queueFamilyIndex			= context.getUniversalQueueFamilyIndex();
167 	const Unique<VkFence>			fence						(createFence(vk, device));
168 	const Unique<VkCommandPool>		cmdPool						(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
169 	const Move<VkCommandBuffer>		ptrCmdBuffer[COUNT]			= { makeCommandBuffer(vk, device, *cmdPool), makeCommandBuffer(vk, device, *cmdPool) };
170 	VkCommandBuffer					cmdBuffers[COUNT]			= {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]};
171 	const Unique<VkEvent>			event						(createEvent(vk, device, config.flags));
172 	VkCommandBufferSubmitInfoKHR	commandBufferSubmitInfo[]	{
173 																	makeCommonCommandBufferSubmitInfo(cmdBuffers[SET]),
174 																	makeCommonCommandBufferSubmitInfo(cmdBuffers[WAIT])
175 																};
176 	VkDependencyInfoKHR				dependencyInfo				= makeCommonDependencyInfo();
177 	SynchronizationWrapperPtr		synchronizationWrapper		= getSynchronizationWrapper(config.type, vk, DE_FALSE);
178 
179 	synchronizationWrapper->addSubmitInfo(
180 		0u,										// deUint32								waitSemaphoreInfoCount
181 		DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
182 		2u,										// deUint32								commandBufferInfoCount
183 		commandBufferSubmitInfo,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
184 		0u,										// deUint32								signalSemaphoreInfoCount
185 		DE_NULL									// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
186 	);
187 
188 	beginCommandBuffer(vk, cmdBuffers[SET]);
189 	synchronizationWrapper->cmdSetEvent(cmdBuffers[SET], *event, &dependencyInfo);
190 	endCommandBuffer(vk, cmdBuffers[SET]);
191 
192 	beginCommandBuffer(vk, cmdBuffers[WAIT]);
193 	synchronizationWrapper->cmdWaitEvents(cmdBuffers[WAIT], 1u, &event.get(), &dependencyInfo);
194 	endCommandBuffer(vk, cmdBuffers[WAIT]);
195 
196 	VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
197 
198 	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
199 		return tcu::TestStatus::fail("Queue should end execution");
200 
201 	return tcu::TestStatus::pass("Wait and set even on device single submission tests pass");
202 }
203 
multiSubmissionCase(Context & context,TestConfig config)204 tcu::TestStatus multiSubmissionCase(Context& context, TestConfig config)
205 {
206 	enum { SET = 0, WAIT, COUNT };
207 	const DeviceInterface&			vk					= context.getDeviceInterface();
208 	const VkDevice					device				= context.getDevice();
209 	const VkQueue					queue				= context.getUniversalQueue();
210 	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
211 	const Move<VkFence>				ptrFence[COUNT]		= { createFence(vk, device), createFence(vk, device) };
212 	VkFence							fence[COUNT]		= { *ptrFence[SET], *ptrFence[WAIT] };
213 	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
214 	const Move<VkCommandBuffer>		ptrCmdBuffer[COUNT] = { makeCommandBuffer(vk, device, *cmdPool), makeCommandBuffer(vk, device, *cmdPool) };
215 	VkCommandBuffer					cmdBuffers[COUNT]	= { *ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT] };
216 	const Unique<VkEvent>			event				(createEvent(vk, device, config.flags));
217 	VkCommandBufferSubmitInfoKHR	commandBufferSubmitInfo[] =
218 	{
219 		makeCommonCommandBufferSubmitInfo(cmdBuffers[SET]),
220 		makeCommonCommandBufferSubmitInfo(cmdBuffers[WAIT])
221 	};
222 	SynchronizationWrapperPtr		synchronizationWrapper[] =
223 	{
224 		getSynchronizationWrapper(config.type, vk, DE_FALSE),
225 		getSynchronizationWrapper(config.type, vk, DE_FALSE)
226 	};
227 	VkDependencyInfoKHR				dependencyInfos[] =
228 	{
229 		makeCommonDependencyInfo(),
230 		makeCommonDependencyInfo()
231 	};
232 
233 	synchronizationWrapper[SET]->addSubmitInfo(
234 		0u,										// deUint32								waitSemaphoreInfoCount
235 		DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
236 		1u,										// deUint32								commandBufferInfoCount
237 		&commandBufferSubmitInfo[SET],			// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
238 		0u,										// deUint32								signalSemaphoreInfoCount
239 		DE_NULL									// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
240 	);
241 
242 	synchronizationWrapper[WAIT]->addSubmitInfo(
243 		0u,										// deUint32								waitSemaphoreInfoCount
244 		DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
245 		1u,										// deUint32								commandBufferInfoCount
246 		&commandBufferSubmitInfo[WAIT],			// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
247 		0u,										// deUint32								signalSemaphoreInfoCount
248 		DE_NULL									// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
249 	);
250 
251 	beginCommandBuffer(vk, cmdBuffers[SET]);
252 	synchronizationWrapper[SET]->cmdSetEvent(cmdBuffers[SET], *event, &dependencyInfos[SET]);
253 	endCommandBuffer(vk, cmdBuffers[SET]);
254 
255 	beginCommandBuffer(vk, cmdBuffers[WAIT]);
256 	synchronizationWrapper[WAIT]->cmdWaitEvents(cmdBuffers[WAIT], 1u, &event.get(), &dependencyInfos[WAIT]);
257 	endCommandBuffer(vk, cmdBuffers[WAIT]);
258 
259 	VK_CHECK(synchronizationWrapper[SET]->queueSubmit(queue, fence[SET]));
260 	VK_CHECK(synchronizationWrapper[WAIT]->queueSubmit(queue, fence[WAIT]));
261 
262 	if (VK_SUCCESS != vk.waitForFences(device, 2u, fence, DE_TRUE, LONG_FENCE_WAIT))
263 		return tcu::TestStatus::fail("Queue should end execution");
264 
265 	return tcu::TestStatus::pass("Wait and set even on device multi submission tests pass");
266 }
267 
secondaryCommandBufferCase(Context & context,TestConfig config)268 tcu::TestStatus secondaryCommandBufferCase (Context& context, TestConfig config)
269 {
270 	enum {SET=0, WAIT, COUNT};
271 	const DeviceInterface&					vk						= context.getDeviceInterface();
272 	const VkDevice							device					= context.getDevice();
273 	const VkQueue							queue					= context.getUniversalQueue();
274 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
275 	const Unique<VkFence>					fence					(createFence(vk, device));
276 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
277 	const Move<VkCommandBuffer>				primaryCmdBuffer		(makeCommandBuffer(vk, device, *cmdPool));
278 	const VkCommandBufferAllocateInfo		cmdBufferInfo			=
279 																	{
280 																		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
281 																		DE_NULL,											// const void*			pNext;
282 																		*cmdPool,											// VkCommandPool		commandPool;
283 																		VK_COMMAND_BUFFER_LEVEL_SECONDARY,					// VkCommandBufferLevel	level;
284 																		1u,													// deUint32				commandBufferCount;
285 																	};
286 	const Move<VkCommandBuffer>				prtCmdBuffers[COUNT]	= {allocateCommandBuffer (vk, device, &cmdBufferInfo), allocateCommandBuffer (vk, device, &cmdBufferInfo)};
287 	VkCommandBuffer							secondaryCmdBuffers[]	= {*prtCmdBuffers[SET], *prtCmdBuffers[WAIT]};
288 	const Unique<VkEvent>					event					(createEvent(vk, device, config.flags));
289 
290 	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
291 																	{
292 																		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,	//VkStructureType					sType;
293 																		DE_NULL,											//const void*						pNext;
294 																		DE_NULL,											//VkRenderPass					renderPass;
295 																		0u,													//deUint32						subpass;
296 																		DE_NULL,											//VkFramebuffer					framebuffer;
297 																		VK_FALSE,											//VkBool32						occlusionQueryEnable;
298 																		(VkQueryControlFlags)0u,							//VkQueryControlFlags				queryFlags;
299 																		(VkQueryPipelineStatisticFlags)0u,					//VkQueryPipelineStatisticFlags	pipelineStatistics;
300 																	};
301 	const VkCommandBufferBeginInfo			cmdBufferBeginInfo		=
302 																	{
303 																		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
304 																		DE_NULL,										// const void*                              pNext;
305 																		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
306 																		&secCmdBufInheritInfo,							// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
307 																	};
308 	VkCommandBufferSubmitInfoKHR			commandBufferSubmitInfo	= makeCommonCommandBufferSubmitInfo(*primaryCmdBuffer);
309 	VkDependencyInfoKHR						dependencyInfos[]		=
310 																	{
311 																		makeCommonDependencyInfo(),
312 																		makeCommonDependencyInfo()
313 																	};
314 	SynchronizationWrapperPtr				synchronizationWrapper	= getSynchronizationWrapper(config.type, vk, DE_FALSE);
315 
316 	synchronizationWrapper->addSubmitInfo(
317 		0u,										// deUint32								waitSemaphoreInfoCount
318 		DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
319 		1u,										// deUint32								commandBufferInfoCount
320 		&commandBufferSubmitInfo,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
321 		0u,										// deUint32								signalSemaphoreInfoCount
322 		DE_NULL									// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
323 	);
324 
325 	VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[SET], &cmdBufferBeginInfo));
326 	synchronizationWrapper->cmdSetEvent(secondaryCmdBuffers[SET], *event, &dependencyInfos[SET]);
327 	endCommandBuffer(vk, secondaryCmdBuffers[SET]);
328 
329 	VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[WAIT], &cmdBufferBeginInfo));
330 	synchronizationWrapper->cmdWaitEvents(secondaryCmdBuffers[WAIT], 1u, &event.get(), &dependencyInfos[WAIT]);
331 	endCommandBuffer(vk, secondaryCmdBuffers[WAIT]);
332 
333 	beginCommandBuffer(vk, *primaryCmdBuffer);
334 	vk.cmdExecuteCommands(*primaryCmdBuffer, 2u, secondaryCmdBuffers);
335 	endCommandBuffer(vk, *primaryCmdBuffer);
336 
337 	VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
338 
339 	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
340 		return tcu::TestStatus::fail("Queue should end execution");
341 
342 	return tcu::TestStatus::pass("Wait and set even on device using secondary command buffers tests pass");
343 }
344 
checkSupport(Context & context,TestConfig config)345 void checkSupport(Context& context, TestConfig config)
346 {
347 	if (config.type == SynchronizationType::SYNCHRONIZATION2)
348 		context.requireDeviceFunctionality("VK_KHR_synchronization2");
349 
350 	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && !context.getPortabilitySubsetFeatures().events)
351 		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Events are not supported by this implementation");
352 }
353 
354 } // anonymous
355 
createBasicEventTests(tcu::TestContext & testCtx)356 tcu::TestCaseGroup* createBasicEventTests (tcu::TestContext& testCtx)
357 {
358 	TestConfig config
359 	{
360 		SynchronizationType::LEGACY,
361 		0U
362 	};
363 
364 	de::MovePtr<tcu::TestCaseGroup> basicTests (new tcu::TestCaseGroup(testCtx, "event", "Basic event tests"));
365 
366 	addFunctionCase(basicTests.get(), "host_set_reset", "Basic event tests set and reset on host", checkSupport, hostResetSetEventCase, config);
367 	addFunctionCase(basicTests.get(), "device_set_reset", "Basic event tests set and reset on device", checkSupport, deviceResetSetEventCase, config);
368 	addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer", "Wait and set event single submission on device", checkSupport, singleSubmissionCase, config);
369 	addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer", "Wait and set event mutli submission on device", checkSupport, multiSubmissionCase, config);
370 	addFunctionCase(basicTests.get(), "multi_secondary_command_buffer", "Event used on secondary command buffer ", checkSupport, secondaryCommandBufferCase, config);
371 
372 	return basicTests.release();
373 }
374 
createSynchronization2BasicEventTests(tcu::TestContext & testCtx)375 tcu::TestCaseGroup* createSynchronization2BasicEventTests (tcu::TestContext& testCtx)
376 {
377 	TestConfig config
378 	{
379 		SynchronizationType::SYNCHRONIZATION2,
380 		0U
381 	};
382 
383 	de::MovePtr<tcu::TestCaseGroup> basicTests (new tcu::TestCaseGroup(testCtx, "event", "Basic event tests"));
384 
385 	addFunctionCase(basicTests.get(), "device_set_reset", "Basic event tests set and reset on device", checkSupport, deviceResetSetEventCase, config);
386 	addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer", "Wait and set event single submission on device", checkSupport, singleSubmissionCase, config);
387 	addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer", "Wait and set event mutli submission on device", checkSupport, multiSubmissionCase, config);
388 	addFunctionCase(basicTests.get(), "multi_secondary_command_buffer", "Event used on secondary command buffer ", checkSupport, secondaryCommandBufferCase, config);
389 
390 	config.flags = VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR;
391 	addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer_device_only", "Wait and set GPU-only event single submission", checkSupport, singleSubmissionCase, config);
392 	addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer_device_only", "Wait and set GPU-only event mutli submission", checkSupport, multiSubmissionCase, config);
393 	addFunctionCase(basicTests.get(), "multi_secondary_command_buffer_device_only", "GPU-only event used on secondary command buffer ", checkSupport, secondaryCommandBufferCase, config);
394 
395 	return basicTests.release();
396 
397 }
398 
399 } // synchronization
400 } // vkt
401