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 
hostResetSetEventCase(Context & context)44 tcu::TestStatus hostResetSetEventCase (Context& context)
45 {
46 	const DeviceInterface&		vk			= context.getDeviceInterface();
47 	const VkDevice				device		= context.getDevice();
48 	const VkEventCreateInfo		eventInfo	=
49 											{
50 												VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
51 												DE_NULL,
52 												0
53 											};
54 	VkEvent						event;
55 	Move<VkEvent>				ptrEvent;
56 
57 	if (VK_SUCCESS != vk.createEvent(device, &eventInfo, DE_NULL, &event))
58 		return tcu::TestStatus::fail("Couldn't create event");
59 
60 	ptrEvent = Move<VkEvent>(check<VkEvent>(event), Deleter<VkEvent>(vk, device, DE_NULL));
61 
62 	if (VK_EVENT_RESET != vk.getEventStatus(device, event))
63 		return tcu::TestStatus::fail("Created event should be in unsignaled state");
64 
65 	if (VK_SUCCESS != vk.setEvent(device, event))
66 		return tcu::TestStatus::fail("Couldn't set event");
67 
68 	if (VK_EVENT_SET != vk.getEventStatus(device, event))
69 		return tcu::TestStatus::fail("Event should be in signaled state after set");
70 
71 	if (VK_SUCCESS != vk.resetEvent(device, event))
72 		return tcu::TestStatus::fail("Couldn't reset event");
73 
74 	if (VK_EVENT_RESET != vk.getEventStatus(device, event))
75 		return tcu::TestStatus::fail("Event should be in unsignaled state after reset");
76 
77 	return tcu::TestStatus::pass("Tests set and reset event on host pass");
78 }
79 
deviceResetSetEventCase(Context & context)80 tcu::TestStatus deviceResetSetEventCase (Context& context)
81 {
82 	const DeviceInterface&			vk					= context.getDeviceInterface();
83 	const VkDevice					device				= context.getDevice();
84 	const VkQueue					queue				= context.getUniversalQueue();
85 	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
86 	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
87 	const Unique<VkCommandBuffer>	cmdBuffer			(makeCommandBuffer(vk, device, *cmdPool));
88 	const VkSubmitInfo				submitInfo			=
89 														{
90 															VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
91 															DE_NULL,						// const void*					pNext;
92 															0u,								// deUint32						waitSemaphoreCount;
93 															DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
94 															DE_NULL,						// const VkPipelineStageFlags*	pWaitDstStageMask;
95 															1u,								// deUint32						commandBufferCount;
96 															&cmdBuffer.get(),				// const VkCommandBuffer*		pCommandBuffers;
97 															0u,								// deUint32						signalSemaphoreCount;
98 															DE_NULL,						// const VkSemaphore*			pSignalSemaphores;
99 														};
100 	const Unique<VkEvent>			event				(createEvent(vk, device));
101 
102 	beginCommandBuffer(vk, *cmdBuffer);
103 	vk.cmdSetEvent(*cmdBuffer, *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
104 	endCommandBuffer(vk, *cmdBuffer);
105 
106 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
107 	VK_CHECK(vk.queueWaitIdle(queue));
108 
109 	if (VK_EVENT_SET != vk.getEventStatus(device, *event))
110 		return tcu::TestStatus::fail("Event should be in signaled state after set");
111 
112 	beginCommandBuffer(vk, *cmdBuffer);
113 	vk.cmdResetEvent(*cmdBuffer, *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
114 	endCommandBuffer(vk, *cmdBuffer);
115 
116 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
117 	VK_CHECK(vk.queueWaitIdle(queue));
118 
119 	if (VK_EVENT_RESET != vk.getEventStatus(device, *event))
120 		return tcu::TestStatus::fail("Event should be in unsignaled state after set");
121 
122 	return tcu::TestStatus::pass("Device set and reset event tests pass");
123 }
124 
singleSubmissionCase(Context & context)125 tcu::TestStatus singleSubmissionCase (Context& context)
126 {
127 	enum {SET=0, WAIT, COUNT};
128 	const DeviceInterface&			vk					= context.getDeviceInterface();
129 	const VkDevice					device				= context.getDevice();
130 	const VkQueue					queue				= context.getUniversalQueue();
131 	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
132 	const Unique<VkFence>			fence				(createFence(vk, device));
133 	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
134 	const Move<VkCommandBuffer>		ptrCmdBuffer[COUNT]	= {makeCommandBuffer(vk, device, *cmdPool), makeCommandBuffer(vk, device, *cmdPool)};
135 	VkCommandBuffer					cmdBuffers[COUNT]	= {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]};
136 	const VkSubmitInfo				submitInfo			=
137 														{
138 															VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
139 															DE_NULL,						// const void*					pNext;
140 															0u,								// deUint32						waitSemaphoreCount;
141 															DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
142 															DE_NULL,						// const VkPipelineStageFlags*	pWaitDstStageMask;
143 															2u,								// deUint32						commandBufferCount;
144 															cmdBuffers,						// const VkCommandBuffer*		pCommandBuffers;
145 															0u,								// deUint32						signalSemaphoreCount;
146 															DE_NULL,						// const VkSemaphore*			pSignalSemaphores;
147 														};
148 	const Unique<VkEvent>			event				(createEvent(vk, device));
149 
150 	beginCommandBuffer(vk, cmdBuffers[SET]);
151 	vk.cmdSetEvent(cmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
152 	endCommandBuffer(vk, cmdBuffers[SET]);
153 
154 	beginCommandBuffer(vk, cmdBuffers[WAIT]);
155 	vk.cmdWaitEvents(cmdBuffers[WAIT], 1u, &event.get(),VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
156 	endCommandBuffer(vk, cmdBuffers[WAIT]);
157 
158 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
159 	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
160 		return tcu::TestStatus::fail("Queue should end execution");
161 
162 	return tcu::TestStatus::pass("Wait and set even on device single submission tests pass");
163 }
164 
multiSubmissionCase(Context & context)165 tcu::TestStatus multiSubmissionCase (Context& context)
166 {
167 	enum {SET=0, WAIT, COUNT};
168 	const DeviceInterface&			vk					= context.getDeviceInterface();
169 	const VkDevice					device				= context.getDevice();
170 	const VkQueue					queue				= context.getUniversalQueue();
171 	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
172 	const Move<VkFence>				ptrFence[COUNT]		=
173 	{
174 		createFence(vk, device),
175 		createFence(vk, device)
176 	};
177 	VkFence							fence[COUNT]		= {*ptrFence[SET], *ptrFence[WAIT]};
178 	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
179 	const Move<VkCommandBuffer>		ptrCmdBuffer[COUNT]	= {makeCommandBuffer(vk, device, *cmdPool), makeCommandBuffer(vk, device, *cmdPool)};
180 	VkCommandBuffer					cmdBuffers[COUNT]	= {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]};
181 	const VkSubmitInfo				submitInfo[COUNT]	=
182 														{
183 															{
184 																VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
185 																DE_NULL,						// const void*					pNext;
186 																0u,								// deUint32						waitSemaphoreCount;
187 																DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
188 																DE_NULL,						// const VkPipelineStageFlags*	pWaitDstStageMask;
189 																1u,								// deUint32						commandBufferCount;
190 																&cmdBuffers[SET],				// const VkCommandBuffer*		pCommandBuffers;
191 																0u,								// deUint32						signalSemaphoreCount;
192 																DE_NULL,						// const VkSemaphore*			pSignalSemaphores;
193 															},
194 															{
195 																VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
196 																DE_NULL,						// const void*					pNext;
197 																0u,								// deUint32						waitSemaphoreCount;
198 																DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
199 																DE_NULL,						// const VkPipelineStageFlags*	pWaitDstStageMask;
200 																1u,								// deUint32						commandBufferCount;
201 																&cmdBuffers[WAIT],				// const VkCommandBuffer*		pCommandBuffers;
202 																0u,								// deUint32						signalSemaphoreCount;
203 																DE_NULL,						// const VkSemaphore*			pSignalSemaphores;
204 															}
205 														};
206 	const Unique<VkEvent>			event				(createEvent(vk, device));
207 
208 	beginCommandBuffer(vk, cmdBuffers[SET]);
209 	vk.cmdSetEvent(cmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
210 	endCommandBuffer(vk, cmdBuffers[SET]);
211 
212 	beginCommandBuffer(vk, cmdBuffers[WAIT]);
213 	vk.cmdWaitEvents(cmdBuffers[WAIT], 1u, &event.get(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
214 	endCommandBuffer(vk, cmdBuffers[WAIT]);
215 
216 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo[SET], fence[SET]));
217 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo[WAIT], fence[WAIT]));
218 
219 	if (VK_SUCCESS != vk.waitForFences(device, 2u, fence, DE_TRUE, LONG_FENCE_WAIT))
220 		return tcu::TestStatus::fail("Queue should end execution");
221 
222 	return tcu::TestStatus::pass("Wait and set even on device multi submission tests pass");
223 }
224 
secondaryCommandBufferCase(Context & context)225 tcu::TestStatus secondaryCommandBufferCase (Context& context)
226 {
227 	enum {SET=0, WAIT, COUNT};
228 	const DeviceInterface&					vk						= context.getDeviceInterface();
229 	const VkDevice							device					= context.getDevice();
230 	const VkQueue							queue					= context.getUniversalQueue();
231 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
232 	const Unique<VkFence>					fence					(createFence(vk, device));
233 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
234 	const Move<VkCommandBuffer>				primaryCmdBuffer		(makeCommandBuffer(vk, device, *cmdPool));
235 	const VkCommandBufferAllocateInfo		cmdBufferInfo			=
236 																	{
237 																		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
238 																		DE_NULL,											// const void*			pNext;
239 																		*cmdPool,											// VkCommandPool		commandPool;
240 																		VK_COMMAND_BUFFER_LEVEL_SECONDARY,					// VkCommandBufferLevel	level;
241 																		1u,													// deUint32				commandBufferCount;
242 																	};
243 	const Move<VkCommandBuffer>				prtCmdBuffers[COUNT]	= {allocateCommandBuffer (vk, device, &cmdBufferInfo), allocateCommandBuffer (vk, device, &cmdBufferInfo)};
244 	VkCommandBuffer							secondaryCmdBuffers[]	= {*prtCmdBuffers[SET], *prtCmdBuffers[WAIT]};
245 	const VkSubmitInfo						submitInfo				=
246 																	{
247 																		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
248 																		DE_NULL,						// const void*					pNext;
249 																		0u,								// deUint32						waitSemaphoreCount;
250 																		DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
251 																		DE_NULL,						// const VkPipelineStageFlags*	pWaitDstStageMask;
252 																		1u,								// deUint32						commandBufferCount;
253 																		&primaryCmdBuffer.get(),		// const VkCommandBuffer*		pCommandBuffers;
254 																		0u,								// deUint32						signalSemaphoreCount;
255 																		DE_NULL,						// const VkSemaphore*			pSignalSemaphores;
256 																	};
257 	const Unique<VkEvent>					event					(createEvent(vk, device));
258 
259 	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
260 																	{
261 																		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,	//VkStructureType					sType;
262 																		DE_NULL,											//const void*						pNext;
263 																		DE_NULL,											//VkRenderPass					renderPass;
264 																		0u,													//deUint32						subpass;
265 																		DE_NULL,											//VkFramebuffer					framebuffer;
266 																		VK_FALSE,											//VkBool32						occlusionQueryEnable;
267 																		(VkQueryControlFlags)0u,							//VkQueryControlFlags				queryFlags;
268 																		(VkQueryPipelineStatisticFlags)0u,					//VkQueryPipelineStatisticFlags	pipelineStatistics;
269 																	};
270 	const VkCommandBufferBeginInfo			cmdBufferBeginInfo		=
271 																	{
272 																		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
273 																		DE_NULL,										// const void*                              pNext;
274 																		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
275 																		&secCmdBufInheritInfo,							// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
276 																	};
277 
278 	VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[SET], &cmdBufferBeginInfo));
279 	vk.cmdSetEvent(secondaryCmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
280 	endCommandBuffer(vk, secondaryCmdBuffers[SET]);
281 
282 	VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[WAIT], &cmdBufferBeginInfo));
283 	vk.cmdWaitEvents(secondaryCmdBuffers[WAIT], 1u, &event.get(),VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
284 	endCommandBuffer(vk, secondaryCmdBuffers[WAIT]);
285 
286 	beginCommandBuffer(vk, *primaryCmdBuffer);
287 	vk.cmdExecuteCommands(*primaryCmdBuffer, 2u, secondaryCmdBuffers);
288 	endCommandBuffer(vk, *primaryCmdBuffer);
289 
290 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
291 	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
292 		return tcu::TestStatus::fail("Queue should end execution");
293 
294 	return tcu::TestStatus::pass("Wait and set even on device using secondary command buffers tests pass");
295 }
296 
297 } // anonymous
298 
createBasicEventTests(tcu::TestContext & testCtx)299 tcu::TestCaseGroup* createBasicEventTests (tcu::TestContext& testCtx)
300 {
301 	de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "event", "Basic event tests"));
302 	addFunctionCase(basicTests.get(), "host_set_reset",   "Basic event tests set and reset on host", hostResetSetEventCase);
303 	addFunctionCase(basicTests.get(), "device_set_reset", "Basic event tests set and reset on device", deviceResetSetEventCase);
304 	addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer", "Wait and set event single submission on device", singleSubmissionCase);
305 	addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer", "Wait and set event mutli submission on device", multiSubmissionCase);
306 	addFunctionCase(basicTests.get(), "multi_secondary_command_buffer", "Event used on secondary command buffer ", secondaryCommandBufferCase);
307 
308 	return basicTests.release();
309 }
310 
311 } // synchronization
312 } // vkt
313