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 #include "vktCustomInstancesDevices.hpp"
28 
29 #include "vkDefs.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkRef.hpp"
32 #include "vkCmdUtil.hpp"
33 
34 namespace vkt
35 {
36 namespace synchronization
37 {
38 namespace
39 {
40 
41 using namespace vk;
42 #define SHORT_FENCE_WAIT 1000ull
43 #define LONG_FENCE_WAIT ~0ull
44 
45 using vkt::synchronization::VideoCodecOperationFlags;
46 
47 struct TestConfig
48 {
49     SynchronizationType type;
50     VkEventCreateFlags flags;
51     VideoCodecOperationFlags videoCodecOperationFlags;
52 };
53 
hostResetSetEventCase(Context & context,TestConfig config)54 tcu::TestStatus hostResetSetEventCase(Context &context, TestConfig config)
55 {
56     de::MovePtr<VideoDevice> videoDevice(
57         config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
58     const VkDevice device             = getSyncDevice(videoDevice, context);
59     const DeviceInterface &vk         = getSyncDeviceInterface(videoDevice, context);
60     const VkEventCreateInfo eventInfo = {VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, DE_NULL, 0};
61     VkEvent event;
62     Move<VkEvent> ptrEvent;
63 
64     DE_UNREF(config);
65 
66     if (VK_SUCCESS != vk.createEvent(device, &eventInfo, DE_NULL, &event))
67         return tcu::TestStatus::fail("Couldn't create event");
68 
69     ptrEvent = Move<VkEvent>(check<VkEvent>(event), Deleter<VkEvent>(vk, device, DE_NULL));
70 
71     if (VK_EVENT_RESET != vk.getEventStatus(device, event))
72         return tcu::TestStatus::fail("Created event should be in unsignaled state");
73 
74     if (VK_SUCCESS != vk.setEvent(device, event))
75         return tcu::TestStatus::fail("Couldn't set event");
76 
77     if (VK_EVENT_SET != vk.getEventStatus(device, event))
78         return tcu::TestStatus::fail("Event should be in signaled state after set");
79 
80     if (VK_SUCCESS != vk.resetEvent(device, event))
81         return tcu::TestStatus::fail("Couldn't reset event");
82 
83     if (VK_EVENT_RESET != vk.getEventStatus(device, event))
84         return tcu::TestStatus::fail("Event should be in unsignaled state after reset");
85 
86     return tcu::TestStatus::pass("Tests set and reset event on host pass");
87 }
88 
deviceResetSetEventCase(Context & context,TestConfig config)89 tcu::TestStatus deviceResetSetEventCase(Context &context, TestConfig config)
90 {
91     de::MovePtr<VideoDevice> videoDevice(
92         config.videoCodecOperationFlags != 0 ?
93             new VideoDevice(context, config.videoCodecOperationFlags,
94                             config.type == SynchronizationType::SYNCHRONIZATION2 ?
95                                 VideoDevice::VIDEO_DEVICE_FLAG_REQUIRE_SYNC2_OR_NOT_SUPPORTED :
96                                 0) :
97             DE_NULL);
98     const VkDevice device           = getSyncDevice(videoDevice, context);
99     const DeviceInterface &vk       = getSyncDeviceInterface(videoDevice, context);
100     const VkQueue queue             = getSyncQueue(videoDevice, context);
101     const uint32_t queueFamilyIndex = getSyncQueueFamilyIndex(videoDevice, context);
102     const Unique<VkCommandPool> cmdPool(
103         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
104     const Unique<VkCommandBuffer> cmdBuffer(makeCommandBuffer(vk, device, *cmdPool));
105     const Unique<VkEvent> event(createEvent(vk, device));
106     const VkCommandBufferSubmitInfoKHR commandBufferSubmitInfo = makeCommonCommandBufferSubmitInfo(cmdBuffer.get());
107     const VkMemoryBarrier2KHR memoryBarrier2                   = {
108         VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR,  // VkStructureType                    sType
109         DE_NULL,                                 // const void*                        pNext
110         VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR            srcStageMask
111         VK_ACCESS_2_NONE_KHR,                    // VkAccessFlags2KHR                srcAccessMask
112         VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR            dstStageMask
113         VK_ACCESS_2_NONE_KHR                        // VkAccessFlags2KHR                dstAccessMask
114     };
115     VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(&memoryBarrier2, DE_NULL, DE_NULL, true);
116 
117     {
118         SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, false);
119 
120         beginCommandBuffer(vk, *cmdBuffer);
121         synchronizationWrapper->cmdSetEvent(*cmdBuffer, *event, &dependencyInfo);
122         endCommandBuffer(vk, *cmdBuffer);
123 
124         synchronizationWrapper->addSubmitInfo(
125             0u,                       // uint32_t                                waitSemaphoreInfoCount
126             DE_NULL,                  // const VkSemaphoreSubmitInfoKHR*        pWaitSemaphoreInfos
127             1u,                       // uint32_t                                commandBufferInfoCount
128             &commandBufferSubmitInfo, // const VkCommandBufferSubmitInfoKHR*    pCommandBufferInfos
129             0u,                       // uint32_t                                signalSemaphoreInfoCount
130             DE_NULL                   // const VkSemaphoreSubmitInfoKHR*        pSignalSemaphoreInfos
131         );
132 
133         VK_CHECK(synchronizationWrapper->queueSubmit(queue, DE_NULL));
134     }
135 
136     VK_CHECK(vk.queueWaitIdle(queue));
137     context.resetCommandPoolForVKSC(device, *cmdPool);
138 
139     if (VK_EVENT_SET != vk.getEventStatus(device, *event))
140         return tcu::TestStatus::fail("Event should be in signaled state after set");
141 
142     {
143         SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, false);
144 
145         beginCommandBuffer(vk, *cmdBuffer);
146         synchronizationWrapper->cmdResetEvent(*cmdBuffer, *event, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
147         endCommandBuffer(vk, *cmdBuffer);
148 
149         synchronizationWrapper->addSubmitInfo(
150             0u,                       // uint32_t                                waitSemaphoreInfoCount
151             DE_NULL,                  // const VkSemaphoreSubmitInfoKHR*        pWaitSemaphoreInfos
152             1u,                       // uint32_t                                commandBufferInfoCount
153             &commandBufferSubmitInfo, // const VkCommandBufferSubmitInfoKHR*    pCommandBufferInfos
154             0u,                       // uint32_t                                signalSemaphoreInfoCount
155             DE_NULL                   // const VkSemaphoreSubmitInfoKHR*        pSignalSemaphoreInfos
156         );
157 
158         VK_CHECK(synchronizationWrapper->queueSubmit(queue, DE_NULL));
159     }
160 
161     VK_CHECK(vk.queueWaitIdle(queue));
162 
163     if (VK_EVENT_RESET != vk.getEventStatus(device, *event))
164         return tcu::TestStatus::fail("Event should be in unsignaled state after set");
165 
166     return tcu::TestStatus::pass("Device set and reset event tests pass");
167 }
168 
eventSetResetNoneStage(Context & context,TestConfig)169 tcu::TestStatus eventSetResetNoneStage(Context &context, TestConfig)
170 {
171     const DeviceInterface &vk       = context.getDeviceInterface();
172     const VkDevice device           = context.getDevice();
173     const VkQueue queue             = context.getUniversalQueue();
174     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
175     const Unique<VkCommandPool> cmdPool(makeCommandPool(vk, device, queueFamilyIndex));
176     const Unique<VkCommandBuffer> cmdBuffer(makeCommandBuffer(vk, device, *cmdPool));
177     const Unique<VkEvent> event(createEvent(vk, device));
178     const VkCommandBufferSubmitInfoKHR commandBufferSubmitInfo = makeCommonCommandBufferSubmitInfo(cmdBuffer.get());
179     const VkMemoryBarrier2KHR memoryBarrier2                   = {
180         VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR, // VkStructureType                    sType
181         DE_NULL,                                // const void*                            pNext
182         VK_PIPELINE_STAGE_NONE_KHR,             // VkPipelineStageFlags2KHR    srcStageMask
183         VK_ACCESS_2_NONE_KHR,                   // VkAccessFlags2KHR                srcAccessMask
184         VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT, // VkPipelineStageFlags2KHR    dstStageMask
185         VK_ACCESS_2_MEMORY_WRITE_BIT            // VkAccessFlags2KHR                dstAccessMask
186     };
187     const VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(&memoryBarrier2, DE_NULL, DE_NULL, true);
188 
189     SynchronizationWrapperPtr synchronizationWrapper =
190         getSynchronizationWrapper(SynchronizationType::SYNCHRONIZATION2, vk, false);
191 
192     beginCommandBuffer(vk, *cmdBuffer, VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT);
193     synchronizationWrapper->cmdSetEvent(*cmdBuffer, *event, &dependencyInfo);
194     endCommandBuffer(vk, *cmdBuffer);
195 
196     synchronizationWrapper->addSubmitInfo(
197         0u,                       // uint32_t                                waitSemaphoreInfoCount
198         DE_NULL,                  // const VkSemaphoreSubmitInfoKHR*        pWaitSemaphoreInfos
199         1u,                       // uint32_t                                commandBufferInfoCount
200         &commandBufferSubmitInfo, // const VkCommandBufferSubmitInfoKHR*    pCommandBufferInfos
201         0u,                       // uint32_t                                signalSemaphoreInfoCount
202         DE_NULL                   // const VkSemaphoreSubmitInfoKHR*        pSignalSemaphoreInfos
203     );
204 
205     VK_CHECK(synchronizationWrapper->queueSubmit(queue, DE_NULL));
206     VK_CHECK(vk.queueWaitIdle(queue));
207     context.resetCommandPoolForVKSC(device, *cmdPool);
208 
209     if (VK_EVENT_SET != vk.getEventStatus(device, *event))
210         return tcu::TestStatus::fail("Event should be in signaled state after set");
211     {
212         // SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(SynchronizationType::SYNCHRONIZATION2, vk, false);
213         beginCommandBuffer(vk, *cmdBuffer, VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT);
214         synchronizationWrapper->cmdResetEvent(*cmdBuffer, *event, VK_PIPELINE_STAGE_NONE_KHR);
215         endCommandBuffer(vk, *cmdBuffer);
216 
217         synchronizationWrapper->addSubmitInfo(
218             0u,                       // uint32_t                                waitSemaphoreInfoCount
219             DE_NULL,                  // const VkSemaphoreSubmitInfoKHR*        pWaitSemaphoreInfos
220             1u,                       // uint32_t                                commandBufferInfoCount
221             &commandBufferSubmitInfo, // const VkCommandBufferSubmitInfoKHR*    pCommandBufferInfos
222             0u,                       // uint32_t                                signalSemaphoreInfoCount
223             DE_NULL                   // const VkSemaphoreSubmitInfoKHR*        pSignalSemaphoreInfos
224         );
225 
226         VK_CHECK(synchronizationWrapper->queueSubmit(queue, DE_NULL));
227     }
228 
229     VK_CHECK(vk.queueWaitIdle(queue));
230 
231     if (VK_EVENT_RESET != vk.getEventStatus(device, *event))
232         return tcu::TestStatus::fail("Event should be in unsignaled state after reset");
233 
234     return tcu::TestStatus::pass("Pass");
235 }
236 
singleSubmissionCase(Context & context,TestConfig config)237 tcu::TestStatus singleSubmissionCase(Context &context, TestConfig config)
238 {
239     enum
240     {
241         SET = 0,
242         WAIT,
243         COUNT
244     };
245     de::MovePtr<VideoDevice> videoDevice(
246         config.videoCodecOperationFlags != 0 ?
247             new VideoDevice(context, config.videoCodecOperationFlags,
248                             config.type == SynchronizationType::SYNCHRONIZATION2 ?
249                                 VideoDevice::VIDEO_DEVICE_FLAG_REQUIRE_SYNC2_OR_NOT_SUPPORTED :
250                                 0) :
251             DE_NULL);
252     const DeviceInterface &vk       = getSyncDeviceInterface(videoDevice, context);
253     const VkDevice device           = getSyncDevice(videoDevice, context);
254     const VkQueue queue             = getSyncQueue(videoDevice, context);
255     const uint32_t queueFamilyIndex = getSyncQueueFamilyIndex(videoDevice, context);
256     const Unique<VkFence> fence(createFence(vk, device));
257     const Unique<VkCommandPool> cmdPool(
258         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
259     const Move<VkCommandBuffer> ptrCmdBuffer[COUNT] = {makeCommandBuffer(vk, device, *cmdPool),
260                                                        makeCommandBuffer(vk, device, *cmdPool)};
261     VkCommandBuffer cmdBuffers[COUNT]               = {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]};
262     const Unique<VkEvent> event(createEvent(vk, device, config.flags));
263     VkCommandBufferSubmitInfoKHR commandBufferSubmitInfo[]{makeCommonCommandBufferSubmitInfo(cmdBuffers[SET]),
264                                                            makeCommonCommandBufferSubmitInfo(cmdBuffers[WAIT])};
265     VkDependencyInfoKHR dependencyInfo               = makeCommonDependencyInfo(DE_NULL, DE_NULL, DE_NULL, true);
266     SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, false);
267 
268     synchronizationWrapper->addSubmitInfo(
269         0u,                      // uint32_t                                waitSemaphoreInfoCount
270         DE_NULL,                 // const VkSemaphoreSubmitInfoKHR*        pWaitSemaphoreInfos
271         2u,                      // uint32_t                                commandBufferInfoCount
272         commandBufferSubmitInfo, // const VkCommandBufferSubmitInfoKHR*    pCommandBufferInfos
273         0u,                      // uint32_t                                signalSemaphoreInfoCount
274         DE_NULL                  // const VkSemaphoreSubmitInfoKHR*        pSignalSemaphoreInfos
275     );
276 
277     beginCommandBuffer(vk, cmdBuffers[SET]);
278     synchronizationWrapper->cmdSetEvent(cmdBuffers[SET], *event, &dependencyInfo);
279     endCommandBuffer(vk, cmdBuffers[SET]);
280 
281     beginCommandBuffer(vk, cmdBuffers[WAIT]);
282     synchronizationWrapper->cmdWaitEvents(cmdBuffers[WAIT], 1u, &event.get(), &dependencyInfo);
283     endCommandBuffer(vk, cmdBuffers[WAIT]);
284 
285     VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
286 
287     if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), true, LONG_FENCE_WAIT))
288         return tcu::TestStatus::fail("Queue should end execution");
289 
290     return tcu::TestStatus::pass("Wait and set even on device single submission tests pass");
291 }
292 
multiSubmissionCase(Context & context,TestConfig config)293 tcu::TestStatus multiSubmissionCase(Context &context, TestConfig config)
294 {
295     enum
296     {
297         SET = 0,
298         WAIT,
299         COUNT
300     };
301     de::MovePtr<VideoDevice> videoDevice(
302         config.videoCodecOperationFlags != 0 ?
303             new VideoDevice(context, config.videoCodecOperationFlags,
304                             config.type == SynchronizationType::SYNCHRONIZATION2 ?
305                                 VideoDevice::VIDEO_DEVICE_FLAG_REQUIRE_SYNC2_OR_NOT_SUPPORTED :
306                                 0) :
307             DE_NULL);
308     const DeviceInterface &vk           = getSyncDeviceInterface(videoDevice, context);
309     const VkDevice device               = getSyncDevice(videoDevice, context);
310     const VkQueue queue                 = getSyncQueue(videoDevice, context);
311     const uint32_t queueFamilyIndex     = getSyncQueueFamilyIndex(videoDevice, context);
312     const Move<VkFence> ptrFence[COUNT] = {createFence(vk, device), createFence(vk, device)};
313     VkFence fence[COUNT]                = {*ptrFence[SET], *ptrFence[WAIT]};
314     const Unique<VkCommandPool> cmdPool(
315         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
316     const Move<VkCommandBuffer> ptrCmdBuffer[COUNT] = {makeCommandBuffer(vk, device, *cmdPool),
317                                                        makeCommandBuffer(vk, device, *cmdPool)};
318     VkCommandBuffer cmdBuffers[COUNT]               = {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]};
319     const Unique<VkEvent> event(createEvent(vk, device, config.flags));
320     VkCommandBufferSubmitInfoKHR commandBufferSubmitInfo[] = {makeCommonCommandBufferSubmitInfo(cmdBuffers[SET]),
321                                                               makeCommonCommandBufferSubmitInfo(cmdBuffers[WAIT])};
322     SynchronizationWrapperPtr synchronizationWrapper[]     = {getSynchronizationWrapper(config.type, vk, false),
323                                                               getSynchronizationWrapper(config.type, vk, false)};
324     VkDependencyInfoKHR dependencyInfos[]                  = {makeCommonDependencyInfo(DE_NULL, DE_NULL, DE_NULL, true),
325                                                               makeCommonDependencyInfo(DE_NULL, DE_NULL, DE_NULL, true)};
326 
327     synchronizationWrapper[SET]->addSubmitInfo(
328         0u,                            // uint32_t                                waitSemaphoreInfoCount
329         DE_NULL,                       // const VkSemaphoreSubmitInfoKHR*        pWaitSemaphoreInfos
330         1u,                            // uint32_t                                commandBufferInfoCount
331         &commandBufferSubmitInfo[SET], // const VkCommandBufferSubmitInfoKHR*    pCommandBufferInfos
332         0u,                            // uint32_t                                signalSemaphoreInfoCount
333         DE_NULL                        // const VkSemaphoreSubmitInfoKHR*        pSignalSemaphoreInfos
334     );
335 
336     synchronizationWrapper[WAIT]->addSubmitInfo(
337         0u,                             // uint32_t                                waitSemaphoreInfoCount
338         DE_NULL,                        // const VkSemaphoreSubmitInfoKHR*        pWaitSemaphoreInfos
339         1u,                             // uint32_t                                commandBufferInfoCount
340         &commandBufferSubmitInfo[WAIT], // const VkCommandBufferSubmitInfoKHR*    pCommandBufferInfos
341         0u,                             // uint32_t                                signalSemaphoreInfoCount
342         DE_NULL                         // const VkSemaphoreSubmitInfoKHR*        pSignalSemaphoreInfos
343     );
344 
345     beginCommandBuffer(vk, cmdBuffers[SET]);
346     synchronizationWrapper[SET]->cmdSetEvent(cmdBuffers[SET], *event, &dependencyInfos[SET]);
347     endCommandBuffer(vk, cmdBuffers[SET]);
348 
349     beginCommandBuffer(vk, cmdBuffers[WAIT]);
350     synchronizationWrapper[WAIT]->cmdWaitEvents(cmdBuffers[WAIT], 1u, &event.get(), &dependencyInfos[WAIT]);
351     endCommandBuffer(vk, cmdBuffers[WAIT]);
352 
353     VK_CHECK(synchronizationWrapper[SET]->queueSubmit(queue, fence[SET]));
354     VK_CHECK(synchronizationWrapper[WAIT]->queueSubmit(queue, fence[WAIT]));
355 
356     if (VK_SUCCESS != vk.waitForFences(device, 2u, fence, true, LONG_FENCE_WAIT))
357         return tcu::TestStatus::fail("Queue should end execution");
358 
359     return tcu::TestStatus::pass("Wait and set even on device multi submission tests pass");
360 }
361 
secondaryCommandBufferCase(Context & context,TestConfig config)362 tcu::TestStatus secondaryCommandBufferCase(Context &context, TestConfig config)
363 {
364     enum
365     {
366         SET = 0,
367         WAIT,
368         COUNT
369     };
370     de::MovePtr<VideoDevice> videoDevice(
371         config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
372     const DeviceInterface &vk       = getSyncDeviceInterface(videoDevice, context);
373     const VkDevice device           = getSyncDevice(videoDevice, context);
374     const VkQueue queue             = getSyncQueue(videoDevice, context);
375     const uint32_t queueFamilyIndex = getSyncQueueFamilyIndex(videoDevice, context);
376     const Unique<VkFence> fence(createFence(vk, device));
377     const Unique<VkCommandPool> cmdPool(
378         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
379     const Move<VkCommandBuffer> primaryCmdBuffer(makeCommandBuffer(vk, device, *cmdPool));
380     const VkCommandBufferAllocateInfo cmdBufferInfo = {
381         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
382         DE_NULL,                                        // const void* pNext;
383         *cmdPool,                                       // VkCommandPool commandPool;
384         VK_COMMAND_BUFFER_LEVEL_SECONDARY,              // VkCommandBufferLevel level;
385         1u,                                             // uint32_t commandBufferCount;
386     };
387     const Move<VkCommandBuffer> prtCmdBuffers[COUNT] = {allocateCommandBuffer(vk, device, &cmdBufferInfo),
388                                                         allocateCommandBuffer(vk, device, &cmdBufferInfo)};
389     VkCommandBuffer secondaryCmdBuffers[]            = {*prtCmdBuffers[SET], *prtCmdBuffers[WAIT]};
390     const Unique<VkEvent> event(createEvent(vk, device, config.flags));
391 
392     const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = {
393         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, //VkStructureType sType;
394         DE_NULL,                                           //const void* pNext;
395         DE_NULL,                                           //VkRenderPass renderPass;
396         0u,                                                //uint32_t subpass;
397         DE_NULL,                                           //VkFramebuffer framebuffer;
398         VK_FALSE,                                          //VkBool32 occlusionQueryEnable;
399         (VkQueryControlFlags)0u,                           //VkQueryControlFlags queryFlags;
400         (VkQueryPipelineStatisticFlags)0u,                 //VkQueryPipelineStatisticFlags pipelineStatistics;
401     };
402     const VkCommandBufferBeginInfo cmdBufferBeginInfo = {
403         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType                          sType;
404         DE_NULL,                                     // const void*                              pNext;
405         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags                flags;
406         &secCmdBufInheritInfo,                       // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
407     };
408     VkCommandBufferSubmitInfoKHR commandBufferSubmitInfo = makeCommonCommandBufferSubmitInfo(*primaryCmdBuffer);
409     VkDependencyInfoKHR dependencyInfos[]                = {makeCommonDependencyInfo(DE_NULL, DE_NULL, DE_NULL, true),
410                                                             makeCommonDependencyInfo(DE_NULL, DE_NULL, DE_NULL, true)};
411     SynchronizationWrapperPtr synchronizationWrapper     = getSynchronizationWrapper(config.type, vk, false);
412 
413     synchronizationWrapper->addSubmitInfo(
414         0u,                       // uint32_t                                waitSemaphoreInfoCount
415         DE_NULL,                  // const VkSemaphoreSubmitInfoKHR*        pWaitSemaphoreInfos
416         1u,                       // uint32_t                                commandBufferInfoCount
417         &commandBufferSubmitInfo, // const VkCommandBufferSubmitInfoKHR*    pCommandBufferInfos
418         0u,                       // uint32_t                                signalSemaphoreInfoCount
419         DE_NULL                   // const VkSemaphoreSubmitInfoKHR*        pSignalSemaphoreInfos
420     );
421 
422     VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[SET], &cmdBufferBeginInfo));
423     synchronizationWrapper->cmdSetEvent(secondaryCmdBuffers[SET], *event, &dependencyInfos[SET]);
424     endCommandBuffer(vk, secondaryCmdBuffers[SET]);
425 
426     VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[WAIT], &cmdBufferBeginInfo));
427     synchronizationWrapper->cmdWaitEvents(secondaryCmdBuffers[WAIT], 1u, &event.get(), &dependencyInfos[WAIT]);
428     endCommandBuffer(vk, secondaryCmdBuffers[WAIT]);
429 
430     beginCommandBuffer(vk, *primaryCmdBuffer);
431     vk.cmdExecuteCommands(*primaryCmdBuffer, 2u, secondaryCmdBuffers);
432     endCommandBuffer(vk, *primaryCmdBuffer);
433 
434     VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
435 
436     if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), true, LONG_FENCE_WAIT))
437         return tcu::TestStatus::fail("Queue should end execution");
438 
439     return tcu::TestStatus::pass("Wait and set even on device using secondary command buffers tests pass");
440 }
441 
checkSupport(Context & context,TestConfig config)442 void checkSupport(Context &context, TestConfig config)
443 {
444     if (config.videoCodecOperationFlags != 0)
445         VideoDevice::checkSupport(context, config.videoCodecOperationFlags);
446 
447     if (config.type == SynchronizationType::SYNCHRONIZATION2)
448         context.requireDeviceFunctionality("VK_KHR_synchronization2");
449 
450 #ifndef CTS_USES_VULKANSC
451     if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
452         !context.getPortabilitySubsetFeatures().events)
453         TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Events are not supported by this implementation");
454 #endif // CTS_USES_VULKANSC
455 }
456 
checkSecondaryBufferSupport(Context & context,TestConfig config)457 void checkSecondaryBufferSupport(Context &context, TestConfig config)
458 {
459     checkSupport(context, config);
460 
461 #ifdef CTS_USES_VULKANSC
462     if (context.getDeviceVulkanSC10Properties().secondaryCommandBufferNullOrImagelessFramebuffer == VK_FALSE)
463         TCU_THROW(NotSupportedError, "secondaryCommandBufferNullFramebuffer is not supported");
464 #endif // CTS_USES_VULKANSC
465 }
466 
467 } // namespace
468 
createBasicEventTests(tcu::TestContext & testCtx,VideoCodecOperationFlags videoCodecOperationFlags)469 tcu::TestCaseGroup *createBasicEventTests(tcu::TestContext &testCtx, VideoCodecOperationFlags videoCodecOperationFlags)
470 {
471     TestConfig config{SynchronizationType::LEGACY, 0U, videoCodecOperationFlags};
472 
473     // Basic event tests
474     de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "event"));
475 
476     // Basic event tests set and reset on host
477     addFunctionCase(basicTests.get(), "host_set_reset", checkSupport, hostResetSetEventCase, config);
478     // Basic event tests set and reset on device
479     addFunctionCase(basicTests.get(), "device_set_reset", checkSupport, deviceResetSetEventCase, config);
480     // Wait and set event single submission on device
481     addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer", checkSupport, singleSubmissionCase, config);
482     // Wait and set event mutli submission on device
483     addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer", checkSupport, multiSubmissionCase, config);
484     // Secondary command buffer does not apply to video queues and should not be a part of test plan
485     if (!videoCodecOperationFlags)
486         // Event used on secondary command buffer
487         addFunctionCase(basicTests.get(), "multi_secondary_command_buffer", checkSecondaryBufferSupport,
488                         secondaryCommandBufferCase, config);
489 
490     return basicTests.release();
491 }
492 
createSynchronization2BasicEventTests(tcu::TestContext & testCtx,VideoCodecOperationFlags videoCodecOperationFlags)493 tcu::TestCaseGroup *createSynchronization2BasicEventTests(tcu::TestContext &testCtx,
494                                                           VideoCodecOperationFlags videoCodecOperationFlags)
495 {
496     TestConfig config{SynchronizationType::SYNCHRONIZATION2, 0U, videoCodecOperationFlags};
497 
498     // Basic event tests
499     de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "event"));
500 
501     // Basic event tests set and reset on device
502     addFunctionCase(basicTests.get(), "device_set_reset", checkSupport, deviceResetSetEventCase, config);
503     // Wait and set event single submission on device
504     addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer", checkSupport, singleSubmissionCase, config);
505     // Wait and set event mutli submission on device
506     addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer", checkSupport, multiSubmissionCase, config);
507     // Event used on secondary command buffer
508     addFunctionCase(basicTests.get(), "multi_secondary_command_buffer", checkSecondaryBufferSupport,
509                     secondaryCommandBufferCase, config);
510     // Event set and reset using the none pipeline stage
511     addFunctionCase(basicTests.get(), "none_set_reset", checkSupport, eventSetResetNoneStage, config);
512 
513     config.flags = VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR;
514     // Wait and set GPU-only event single submission
515     addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer_device_only", checkSupport,
516                     singleSubmissionCase, config);
517     // Wait and set GPU-only event mutli submission
518     addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer_device_only", checkSupport,
519                     multiSubmissionCase, config);
520     // GPU-only event used on secondary command buffer
521     addFunctionCase(basicTests.get(), "multi_secondary_command_buffer_device_only", checkSecondaryBufferSupport,
522                     secondaryCommandBufferCase, config);
523 
524     return basicTests.release();
525 }
526 
527 } // namespace synchronization
528 } // namespace vkt
529