Test waiting for fences without waitAll
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / synchronization / vktSynchronizationBasicFenceTests.cpp
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 fence basic tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSynchronizationBasicFenceTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktSynchronizationUtil.hpp"
27
28 #include "vkDefs.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkRef.hpp"
31
32 namespace vkt
33 {
34 namespace synchronization
35 {
36 namespace
37 {
38 using namespace vk;
39
40 static const deUint64   SHORT_FENCE_WAIT        = 1000ull;
41 static const deUint64   LONG_FENCE_WAIT         = ~0ull;
42
43 tcu::TestStatus basicOneFenceCase (Context& context)
44 {
45         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
46         const VkDevice                                  device                          = context.getDevice();
47         const VkQueue                                   queue                           = context.getUniversalQueue();
48         const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
49         const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
50         const Unique<VkCommandBuffer>   cmdBuffer                       (makeCommandBuffer(vk, device, *cmdPool));
51
52         const VkFenceCreateInfo                 fenceInfo                       =
53         {
54                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType      sType;
55                 DE_NULL,                                                                // const void*          pNext;
56                 0u,                                                                             // VkFenceCreateFlags   flags;
57         };
58
59         const Unique<VkFence>                   fence                           (createFence(vk, device, &fenceInfo));
60
61         const VkSubmitInfo                              submitInfo                      =
62         {
63                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                sType;
64                 DE_NULL,                                                                // const void*                    pNext;
65                 0u,                                                                             // deUint32                       waitSemaphoreCount;
66                 DE_NULL,                                                                // const VkSemaphore*             pWaitSemaphores;
67                 (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*    pWaitDstStageMask;
68                 1u,                                                                             // deUint32                       commandBufferCount;
69                 &cmdBuffer.get(),                                               // const VkCommandBuffer*         pCommandBuffers;
70                 0u,                                                                             // deUint32                       signalSemaphoreCount;
71                 DE_NULL,                                                                // const VkSemaphore*             pSignalSemaphores;
72         };
73
74         if (VK_NOT_READY != vk.getFenceStatus(device, *fence))
75                 return tcu::TestStatus::fail("Created fence should be in unsignaled state");
76
77         if (VK_TIMEOUT != vk.waitForFences(device, 1u, &fence.get(), VK_TRUE, SHORT_FENCE_WAIT))
78                 return tcu::TestStatus::fail("vkWaitForFences should return VK_TIMEOUT");
79
80         if (VK_NOT_READY != vk.getFenceStatus(device, *fence))
81                 return tcu::TestStatus::fail("Created fence should be in unsignaled state");
82
83         beginCommandBuffer(vk, *cmdBuffer);
84         endCommandBuffer(vk, *cmdBuffer);
85
86         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
87
88         if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
89                 return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS");
90
91         if (VK_SUCCESS != vk.getFenceStatus(device, *fence))
92                 return tcu::TestStatus::fail("Fence should be in signaled state");
93
94         if (VK_SUCCESS != vk.resetFences(device, 1u, &fence.get()))
95                 return tcu::TestStatus::fail("Couldn't reset the fence");
96
97         if (VK_NOT_READY != vk.getFenceStatus(device, *fence))
98                 return tcu::TestStatus::fail("Fence after reset should be in unsignaled state");
99
100         return tcu::TestStatus::pass("Basic one fence tests passed");
101 }
102
103 tcu::TestStatus basicMultiFenceCase (Context& context)
104 {
105         enum
106         {
107                 FIRST_FENCE = 0,
108                 SECOND_FENCE
109         };
110
111         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
112         const VkDevice                                  device                          = context.getDevice();
113         const VkQueue                                   queue                           = context.getUniversalQueue();
114         const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
115         const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,  queueFamilyIndex));
116         const Unique<VkCommandBuffer>   cmdBuffer                       (makeCommandBuffer(vk, device, *cmdPool));
117
118         const VkFenceCreateInfo                 fenceInfo                       =
119         {
120                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType      sType;
121                 DE_NULL,                                                                // const void*          pNext;
122                 0u,                                                                             // VkFenceCreateFlags   flags;
123         };
124
125         const Move<VkFence>                             ptrFence[2]                     =
126         {
127                 createFence(vk, device, &fenceInfo),
128                 createFence(vk, device, &fenceInfo)
129         };
130
131         const VkFence                                   fence[2]                        =
132         {
133                 *ptrFence[FIRST_FENCE],
134                 *ptrFence[SECOND_FENCE]
135         };
136
137         const VkCommandBufferBeginInfo  info                            =
138         {
139                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                          sType;
140                 DE_NULL,                                                                                // const void*                              pNext;
141                 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,   // VkCommandBufferUsageFlags                flags;
142                 DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
143         };
144
145         const VkSubmitInfo                              submitInfo                      =
146         {
147                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                sType;
148                 DE_NULL,                                                                // const void*                    pNext;
149                 0u,                                                                             // deUint32                       waitSemaphoreCount;
150                 DE_NULL,                                                                // const VkSemaphore*             pWaitSemaphores;
151                 (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*    pWaitDstStageMask;
152                 1u,                                                                             // deUint32                       commandBufferCount;
153                 &cmdBuffer.get(),                                               // const VkCommandBuffer*         pCommandBuffers;
154                 0u,                                                                             // deUint32                       signalSemaphoreCount;
155                 DE_NULL,                                                                // const VkSemaphore*             pSignalSemaphores;
156         };
157
158         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &info));
159         endCommandBuffer(vk, *cmdBuffer);
160
161         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[FIRST_FENCE]));
162
163         if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence[FIRST_FENCE], DE_FALSE, LONG_FENCE_WAIT))
164                 return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS");
165
166         if (VK_SUCCESS != vk.resetFences(device, 1u, &fence[FIRST_FENCE]))
167                 return tcu::TestStatus::fail("Couldn't reset the fence");
168
169         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[FIRST_FENCE]));
170
171         if (VK_TIMEOUT != vk.waitForFences(device, 2u, &fence[FIRST_FENCE], DE_TRUE, SHORT_FENCE_WAIT))
172                 return tcu::TestStatus::fail("vkWaitForFences should return VK_TIMEOUT");
173
174         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[SECOND_FENCE]));
175
176         if (VK_SUCCESS != vk.waitForFences(device, 2u, &fence[FIRST_FENCE], DE_TRUE, LONG_FENCE_WAIT))
177                 return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS");
178
179         return tcu::TestStatus::pass("Basic multi fence tests passed");
180 }
181
182 tcu::TestStatus emptySubmitCase (Context& context)
183 {
184         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
185         const VkDevice                                  device                          = context.getDevice();
186         const VkQueue                                   queue                           = context.getUniversalQueue();
187
188         const VkFenceCreateInfo                 fenceCreateInfo         =
189         {
190                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType       sType;
191                 DE_NULL,                                                                // const void*           pNext;
192                 (VkFenceCreateFlags)0,                                  // VkFenceCreateFlags    flags;
193         };
194
195         const Unique<VkFence>                   fence                           (createFence(vk, device, &fenceCreateInfo));
196
197         VK_CHECK(vk.queueSubmit(queue, 0u, DE_NULL, *fence));
198
199         if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT))
200                 return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS");
201
202         return tcu::TestStatus::pass("OK");
203 }
204
205 tcu::TestStatus basicMultiFenceWaitAllFalseCase (Context& context)
206 {
207         enum
208         {
209                 FIRST_FENCE = 0,
210                 SECOND_FENCE
211         };
212
213         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
214         const VkDevice                                  device                          = context.getDevice();
215         const VkQueue                                   queue                           = context.getUniversalQueue();
216         const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
217         const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
218         const Unique<VkCommandBuffer>   cmdBuffer                       (makeCommandBuffer(vk, device, *cmdPool));
219
220         const VkFenceCreateInfo                 fenceInfo                       =
221         {
222                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType     sType;
223                 DE_NULL,                                                                // const void*         pNext;
224                 0u,                                                                             // VkFenceCreateFlags  flags;
225         };
226
227         const Move<VkFence>                             ptrFence[2]                     =
228         {
229                 createFence(vk, device, &fenceInfo),
230                 createFence(vk, device, &fenceInfo)
231         };
232
233         const VkFence                                   fence[2]                        =
234         {
235                 *ptrFence[FIRST_FENCE],
236                 *ptrFence[SECOND_FENCE]
237         };
238
239         const VkCommandBufferBeginInfo  info                            =
240         {
241                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                          sType;
242                 DE_NULL,                                                                                // const void*                              pNext;
243                 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,   // VkCommandBufferUsageFlags                flags;
244                 DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
245         };
246
247         const VkSubmitInfo                              submitInfo                      =
248         {
249                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                sType;
250                 DE_NULL,                                                                // const void*                    pNext;
251                 0u,                                                                             // deUint32                       waitSemaphoreCount;
252                 DE_NULL,                                                                // const VkSemaphore*             pWaitSemaphores;
253                 (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*    pWaitDstStageMask;
254                 1u,                                                                             // deUint32                       commandBufferCount;
255                 &cmdBuffer.get(),                                               // const VkCommandBuffer*         pCommandBuffers;
256                 0u,                                                                             // deUint32                       signalSemaphoreCount;
257                 DE_NULL,                                                                // const VkSemaphore*             pSignalSemaphores;
258         };
259
260         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &info));
261         endCommandBuffer(vk, *cmdBuffer);
262
263         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[FIRST_FENCE]));
264         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[SECOND_FENCE]));
265
266         // Wait for any fence
267         if (VK_SUCCESS != vk.waitForFences(device, 2u, &fence[FIRST_FENCE], DE_FALSE, LONG_FENCE_WAIT))
268                 return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS");
269
270         // Wait for all fences
271         if (VK_SUCCESS != vk.waitForFences(device, 2u, &fence[FIRST_FENCE], DE_TRUE, LONG_FENCE_WAIT))
272                 return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS");
273
274         return tcu::TestStatus::pass("Basic multi fence test without waitAll passed");
275 }
276
277 } // anonymous
278
279 tcu::TestCaseGroup* createBasicFenceTests (tcu::TestContext& testCtx)
280 {
281         de::MovePtr<tcu::TestCaseGroup> basicFenceTests(new tcu::TestCaseGroup(testCtx, "fence", "Basic fence tests"));
282         addFunctionCase(basicFenceTests.get(),  "one",                                  "Basic one fence tests",                                                        basicOneFenceCase);
283         addFunctionCase(basicFenceTests.get(),  "multi",                                "Basic multi fence tests",                                                      basicMultiFenceCase);
284         addFunctionCase(basicFenceTests.get(),  "empty_submit",                 "Signal a fence after an empty queue submission",       emptySubmitCase);
285         addFunctionCase(basicFenceTests.get(),  "multi_waitall_false",  "Basic multi fence test without waitAll",                       basicMultiFenceWaitAllFalseCase);
286
287         return basicFenceTests.release();
288 }
289
290 } // synchronization
291 } // vkt