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
deviceWaitForEventCase(Context & context)125 tcu::TestStatus deviceWaitForEventCase (Context& context)
126 {
127 const DeviceInterface& vk = context.getDeviceInterface();
128 const VkDevice device = context.getDevice();
129 const VkQueue queue = context.getUniversalQueue();
130 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
131 const Unique<VkFence> fence (createFence(vk, device));
132 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
133 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
134 const VkSubmitInfo submitInfo =
135 {
136 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
137 DE_NULL, // const void* pNext;
138 0u, // deUint32 waitSemaphoreCount;
139 DE_NULL, // const VkSemaphore* pWaitSemaphores;
140 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
141 1u, // deUint32 commandBufferCount;
142 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
143 0u, // deUint32 signalSemaphoreCount;
144 DE_NULL, // const VkSemaphore* pSignalSemaphores;
145 };
146 const VkEventCreateInfo eventInfo =
147 {
148 VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
149 DE_NULL,
150 0
151 };
152 const Unique<VkEvent> event (createEvent(vk, device, &eventInfo, DE_NULL));
153
154 beginCommandBuffer(vk, *cmdBuffer);
155 vk.cmdWaitEvents(*cmdBuffer, 1u, &event.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
156 endCommandBuffer(vk, *cmdBuffer);
157
158 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
159 if (VK_TIMEOUT != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, SHORT_FENCE_WAIT))
160 return tcu::TestStatus::fail("Queue should not end execution");
161
162 if (VK_SUCCESS != vk.setEvent(device, *event))
163 return tcu::TestStatus::fail("Couldn't set event");
164
165 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
166 return tcu::TestStatus::fail("Queue should end execution");
167
168 return tcu::TestStatus::pass("Device wait for event tests pass");
169 }
170
singleSubmissionCase(Context & context)171 tcu::TestStatus singleSubmissionCase (Context& context)
172 {
173 enum {SET=0, WAIT, COUNT};
174 const DeviceInterface& vk = context.getDeviceInterface();
175 const VkDevice device = context.getDevice();
176 const VkQueue queue = context.getUniversalQueue();
177 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
178 const Unique<VkFence> fence (createFence(vk, device));
179 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
180 const Move<VkCommandBuffer> ptrCmdBuffer[COUNT] = {makeCommandBuffer(vk, device, *cmdPool), makeCommandBuffer(vk, device, *cmdPool)};
181 VkCommandBuffer cmdBuffers[COUNT] = {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]};
182 const VkSubmitInfo submitInfo =
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 2u, // deUint32 commandBufferCount;
190 cmdBuffers, // const VkCommandBuffer* pCommandBuffers;
191 0u, // deUint32 signalSemaphoreCount;
192 DE_NULL, // const VkSemaphore* pSignalSemaphores;
193 };
194 const Unique<VkEvent> event (createEvent(vk, device));
195
196 beginCommandBuffer(vk, cmdBuffers[SET]);
197 vk.cmdSetEvent(cmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
198 endCommandBuffer(vk, cmdBuffers[SET]);
199
200 beginCommandBuffer(vk, cmdBuffers[WAIT]);
201 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);
202 endCommandBuffer(vk, cmdBuffers[WAIT]);
203
204 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
205 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
206 return tcu::TestStatus::fail("Queue should end execution");
207
208 return tcu::TestStatus::pass("Wait and set even on device single submission tests pass");
209 }
210
multiSubmissionCase(Context & context)211 tcu::TestStatus multiSubmissionCase (Context& context)
212 {
213 enum {SET=0, WAIT, COUNT};
214 const DeviceInterface& vk = context.getDeviceInterface();
215 const VkDevice device = context.getDevice();
216 const VkQueue queue = context.getUniversalQueue();
217 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
218 const Move<VkFence> ptrFence[COUNT] =
219 {
220 createFence(vk, device),
221 createFence(vk, device)
222 };
223 VkFence fence[COUNT] = {*ptrFence[SET], *ptrFence[WAIT]};
224 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
225 const Move<VkCommandBuffer> ptrCmdBuffer[COUNT] = {makeCommandBuffer(vk, device, *cmdPool), makeCommandBuffer(vk, device, *cmdPool)};
226 VkCommandBuffer cmdBuffers[COUNT] = {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]};
227 const VkSubmitInfo submitInfo[COUNT] =
228 {
229 {
230 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
231 DE_NULL, // const void* pNext;
232 0u, // deUint32 waitSemaphoreCount;
233 DE_NULL, // const VkSemaphore* pWaitSemaphores;
234 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
235 1u, // deUint32 commandBufferCount;
236 &cmdBuffers[SET], // const VkCommandBuffer* pCommandBuffers;
237 0u, // deUint32 signalSemaphoreCount;
238 DE_NULL, // const VkSemaphore* pSignalSemaphores;
239 },
240 {
241 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
242 DE_NULL, // const void* pNext;
243 0u, // deUint32 waitSemaphoreCount;
244 DE_NULL, // const VkSemaphore* pWaitSemaphores;
245 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
246 1u, // deUint32 commandBufferCount;
247 &cmdBuffers[WAIT], // const VkCommandBuffer* pCommandBuffers;
248 0u, // deUint32 signalSemaphoreCount;
249 DE_NULL, // const VkSemaphore* pSignalSemaphores;
250 }
251 };
252 const Unique<VkEvent> event (createEvent(vk, device));
253
254 beginCommandBuffer(vk, cmdBuffers[SET]);
255 vk.cmdSetEvent(cmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
256 endCommandBuffer(vk, cmdBuffers[SET]);
257
258 beginCommandBuffer(vk, cmdBuffers[WAIT]);
259 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);
260 endCommandBuffer(vk, cmdBuffers[WAIT]);
261
262 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo[SET], fence[SET]));
263 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo[WAIT], fence[WAIT]));
264
265 if (VK_SUCCESS != vk.waitForFences(device, 2u, fence, DE_TRUE, LONG_FENCE_WAIT))
266 return tcu::TestStatus::fail("Queue should end execution");
267
268 return tcu::TestStatus::pass("Wait and set even on device multi submission tests pass");
269 }
270
secondaryCommandBufferCase(Context & context)271 tcu::TestStatus secondaryCommandBufferCase (Context& context)
272 {
273 enum {SET=0, WAIT, COUNT};
274 const DeviceInterface& vk = context.getDeviceInterface();
275 const VkDevice device = context.getDevice();
276 const VkQueue queue = context.getUniversalQueue();
277 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
278 const Unique<VkFence> fence (createFence(vk, device));
279 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
280 const Move<VkCommandBuffer> primaryCmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
281 const VkCommandBufferAllocateInfo cmdBufferInfo =
282 {
283 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
284 DE_NULL, // const void* pNext;
285 *cmdPool, // VkCommandPool commandPool;
286 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level;
287 1u, // deUint32 commandBufferCount;
288 };
289 const Move<VkCommandBuffer> prtCmdBuffers[COUNT] = {allocateCommandBuffer (vk, device, &cmdBufferInfo), allocateCommandBuffer (vk, device, &cmdBufferInfo)};
290 VkCommandBuffer secondaryCmdBuffers[] = {*prtCmdBuffers[SET], *prtCmdBuffers[WAIT]};
291 const VkSubmitInfo submitInfo =
292 {
293 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
294 DE_NULL, // const void* pNext;
295 0u, // deUint32 waitSemaphoreCount;
296 DE_NULL, // const VkSemaphore* pWaitSemaphores;
297 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
298 1u, // deUint32 commandBufferCount;
299 &primaryCmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
300 0u, // deUint32 signalSemaphoreCount;
301 DE_NULL, // const VkSemaphore* pSignalSemaphores;
302 };
303 const Unique<VkEvent> event (createEvent(vk, device));
304
305 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
306 {
307 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, //VkStructureType sType;
308 DE_NULL, //const void* pNext;
309 DE_NULL, //VkRenderPass renderPass;
310 0u, //deUint32 subpass;
311 DE_NULL, //VkFramebuffer framebuffer;
312 VK_FALSE, //VkBool32 occlusionQueryEnable;
313 (VkQueryControlFlags)0u, //VkQueryControlFlags queryFlags;
314 (VkQueryPipelineStatisticFlags)0u, //VkQueryPipelineStatisticFlags pipelineStatistics;
315 };
316 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
317 {
318 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
319 DE_NULL, // const void* pNext;
320 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
321 &secCmdBufInheritInfo, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
322 };
323
324 VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[SET], &cmdBufferBeginInfo));
325 vk.cmdSetEvent(secondaryCmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
326 endCommandBuffer(vk, secondaryCmdBuffers[SET]);
327
328 VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[WAIT], &cmdBufferBeginInfo));
329 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);
330 endCommandBuffer(vk, secondaryCmdBuffers[WAIT]);
331
332 beginCommandBuffer(vk, *primaryCmdBuffer);
333 vk.cmdExecuteCommands(*primaryCmdBuffer, 2u, secondaryCmdBuffers);
334 endCommandBuffer(vk, *primaryCmdBuffer);
335
336 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
337 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
338 return tcu::TestStatus::fail("Queue should end execution");
339
340 return tcu::TestStatus::pass("Wait and set even on device using secondary command buffers tests pass");
341 }
342
343 } // anonymous
344
createBasicEventTests(tcu::TestContext & testCtx)345 tcu::TestCaseGroup* createBasicEventTests (tcu::TestContext& testCtx)
346 {
347 de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "event", "Basic event tests"));
348 addFunctionCase(basicTests.get(), "host_set_reset", "Basic event tests set and reset on host", hostResetSetEventCase);
349 addFunctionCase(basicTests.get(), "device_set_reset", "Basic event tests set and reset on device", deviceResetSetEventCase);
350 addFunctionCase(basicTests.get(), "host_set_device_wait", "Wait for event on device test", deviceWaitForEventCase);
351 addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer", "Wait and set event single submission on device", singleSubmissionCase);
352 addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer", "Wait and set event mutli submission on device", multiSubmissionCase);
353 addFunctionCase(basicTests.get(), "multi_secondary_command_buffer", "Event used on secondary command buffer ", secondaryCommandBufferCase);
354
355 return basicTests.release();
356 }
357
358 } // synchronization
359 } // vkt
360