Added test to stress semaphore chains
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / synchronization / vktSynchronizationBasicSemaphoreTests.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 semaphore basic tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSynchronizationBasicSemaphoreTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktSynchronizationUtil.hpp"
27
28 #include "vkDefs.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkQueryUtil.hpp"
31
32
33 #include "vkRef.hpp"
34
35 namespace vkt
36 {
37 namespace synchronization
38 {
39 namespace
40 {
41
42 using namespace vk;
43
44 #define FENCE_WAIT      ~0ull
45
46 tcu::TestStatus basicOneQueueCase (Context& context)
47 {
48         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
49         const VkDevice                                  device                          = context.getDevice();
50         const VkQueue                                   queue                           = context.getUniversalQueue();
51         const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
52         const Unique<VkSemaphore>               semaphore                       (createSemaphore (vk, device));
53         const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
54         const Unique<VkCommandBuffer>   cmdBuffer                       (makeCommandBuffer(vk, device, *cmdPool));
55         const VkCommandBufferBeginInfo  info                            =
56                                                                                                                 {
57                                                                                                                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                          sType;
58                                                                                                                         DE_NULL,                                                                                // const void*                              pNext;
59                                                                                                                         VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,   // VkCommandBufferUsageFlags                flags;
60                                                                                                                         DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
61                                                                                                                 };
62         const VkPipelineStageFlags              stageBits[]                     = { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
63         const VkSubmitInfo                              submitInfo[2]           =
64                                                                                                                 {
65                                                                                                                         {
66                                                                                                                                 VK_STRUCTURE_TYPE_SUBMIT_INFO,          // VkStructureType                      sType;
67                                                                                                                                 DE_NULL,                                                        // const void*                          pNext;
68                                                                                                                                 0u,                                                                     // deUint32                                     waitSemaphoreCount;
69                                                                                                                                 DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
70                                                                                                                                 (const VkPipelineStageFlags*)DE_NULL,
71                                                                                                                                 1u,                                                                     // deUint32                                     commandBufferCount;
72                                                                                                                                 &cmdBuffer.get(),                                       // const VkCommandBuffer*       pCommandBuffers;
73                                                                                                                                 1u,                                                                     // deUint32                                     signalSemaphoreCount;
74                                                                                                                                 &semaphore.get(),                                       // const VkSemaphore*           pSignalSemaphores;
75                                                                                                                         },
76                                                                                                                         {
77                                                                                                                                 VK_STRUCTURE_TYPE_SUBMIT_INFO,          // VkStructureType                              sType;
78                                                                                                                                 DE_NULL,                                                        // const void*                                  pNext;
79                                                                                                                                 1u,                                                                     // deUint32                                             waitSemaphoreCount;
80                                                                                                                                 &semaphore.get(),                                       // const VkSemaphore*                   pWaitSemaphores;
81                                                                                                                                 stageBits,                                                      // const VkPipelineStageFlags*  pWaitDstStageMask;
82                                                                                                                                 1u,                                                                     // deUint32                                             commandBufferCount;
83                                                                                                                                 &cmdBuffer.get(),                                       // const VkCommandBuffer*               pCommandBuffers;
84                                                                                                                                 0u,                                                                     // deUint32                                             signalSemaphoreCount;
85                                                                                                                                 DE_NULL,                                                        // const VkSemaphore*                   pSignalSemaphores;
86                                                                                                                         }
87                                                                                                                 };
88         const Unique<VkFence>                   fence                           (createFence(vk, device));
89
90         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &info));
91         endCommandBuffer(vk, *cmdBuffer);
92         VK_CHECK(vk.queueSubmit(queue, 2u, submitInfo, *fence));
93
94         if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, FENCE_WAIT))
95                 return tcu::TestStatus::fail("Basic semaphore tests with one queue failed");
96
97         return tcu::TestStatus::pass("Basic semaphore tests with one queue passed");
98 }
99
100 tcu::TestStatus basicChainCase (Context& context)
101 {
102         VkResult                                        err                     = VK_SUCCESS;
103         const DeviceInterface&          vk                      = context.getDeviceInterface();
104         const VkDevice&                         device          = context.getDevice();
105         const VkQueue                           queue           = context.getUniversalQueue();
106         const int                                       chainLength = 32768;
107         VkPipelineStageFlags            flags           = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
108         VkSemaphoreCreateInfo           sci                     = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, DE_NULL, 0 };
109         VkFenceCreateInfo                       fci                     = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
110         std::vector<VkSemaphore>        semaphores;
111         VkFence                                         fence;
112
113         for (int i = 0; err == VK_SUCCESS && i < chainLength; i++)
114         {
115                 VkSemaphore                             semaphore;
116                 err = vk.createSemaphore(device, &sci, DE_NULL, &semaphore);
117                 if (err == VK_SUCCESS)
118                 {
119                         semaphores.push_back(semaphore);
120
121                         VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO,
122                                 DE_NULL,
123                                 semaphores.size() > 1 ? 1u : 0u,
124                                 semaphores.size() > 1 ? &semaphores[semaphores.size() - 2] : DE_NULL,
125                                 &flags,
126                                 0,
127                                 DE_NULL,
128                                 1,
129                                 &semaphores[semaphores.size() - 1] };
130                         err = vk.queueSubmit(queue, 1, &si, 0);
131                 }
132         }
133
134         VK_CHECK(vk.createFence(device, &fci, DE_NULL, &fence));
135
136         VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, DE_NULL, 1, &semaphores.back(), &flags, 0, DE_NULL, 0, DE_NULL };
137         VK_CHECK(vk.queueSubmit(queue, 1, &si, fence));
138
139         vk.waitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
140
141         vk.destroyFence(device, fence, DE_NULL);
142
143         for (unsigned int i = 0; i < semaphores.size(); i++)
144                 vk.destroySemaphore(device, semaphores[i], DE_NULL);
145
146         if (err == VK_SUCCESS)
147                 return tcu::TestStatus::pass("Basic semaphore chain test passed");
148
149         return tcu::TestStatus::fail("Basic semaphore chain test failed");
150 }
151
152 tcu::TestStatus basicMultiQueueCase (Context& context)
153 {
154         enum {NO_MATCH_FOUND = ~((deUint32)0)};
155         enum QueuesIndexes {FIRST = 0, SECOND, COUNT};
156
157         struct Queues
158         {
159                 VkQueue         queue;
160                 deUint32        queueFamilyIndex;
161         };
162
163
164         const DeviceInterface&                                  vk                                                      = context.getDeviceInterface();
165         const InstanceInterface&                                instance                                        = context.getInstanceInterface();
166         const VkPhysicalDevice                                  physicalDevice                          = context.getPhysicalDevice();
167         vk::Move<vk::VkDevice>                                  logicalDevice;
168         std::vector<VkQueueFamilyProperties>    queueFamilyProperties;
169         VkDeviceCreateInfo                                              deviceInfo;
170         VkPhysicalDeviceFeatures                                deviceFeatures;
171         const float                                                             queuePriorities[COUNT]          = {1.0f, 1.0f};
172         VkDeviceQueueCreateInfo                                 queueInfos[COUNT];
173         Queues                                                                  queues[COUNT]                           =
174                                                                                                                                                 {
175                                                                                                                                                         {DE_NULL, (deUint32)NO_MATCH_FOUND},
176                                                                                                                                                         {DE_NULL, (deUint32)NO_MATCH_FOUND}
177                                                                                                                                                 };
178         const VkCommandBufferBeginInfo                  info                                            =
179                                                                                                                                                 {
180                                                                                                                                                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                          sType;
181                                                                                                                                                         DE_NULL,                                                                                // const void*                              pNext;
182                                                                                                                                                         VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,   // VkCommandBufferUsageFlags                flags;
183                                                                                                                                                         DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
184                                                                                                                                                 };
185         Move<VkSemaphore>                                               semaphore;
186         Move<VkCommandPool>                                             cmdPool[COUNT];
187         Move<VkCommandBuffer>                                   cmdBuffer[COUNT];
188         const VkPipelineStageFlags                              stageBits[]                                     = { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
189         VkSubmitInfo                                                    submitInfo[COUNT];
190         Move<VkFence>                                                   fence[COUNT];
191
192         queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
193
194         for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
195         {
196                 if (NO_MATCH_FOUND == queues[FIRST].queueFamilyIndex)
197                         queues[FIRST].queueFamilyIndex = queueNdx;
198
199                 if (queues[FIRST].queueFamilyIndex != queueNdx || queueFamilyProperties[queueNdx].queueCount > 1u)
200                 {
201                         queues[SECOND].queueFamilyIndex = queueNdx;
202                         break;
203                 }
204         }
205
206         if (queues[FIRST].queueFamilyIndex == NO_MATCH_FOUND || queues[SECOND].queueFamilyIndex == NO_MATCH_FOUND)
207                 TCU_THROW(NotSupportedError, "Queues couldn't be created");
208
209         for (int queueNdx = 0; queueNdx < COUNT; ++queueNdx)
210         {
211                 VkDeviceQueueCreateInfo queueInfo;
212                 deMemset(&queueInfo, 0, sizeof(queueInfo));
213
214                 queueInfo.sType                         = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
215                 queueInfo.pNext                         = DE_NULL;
216                 queueInfo.flags                         = (VkDeviceQueueCreateFlags)0u;
217                 queueInfo.queueFamilyIndex      = queues[queueNdx].queueFamilyIndex;
218                 queueInfo.queueCount            = (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 2 : 1;
219                 queueInfo.pQueuePriorities      = queuePriorities;
220
221                 queueInfos[queueNdx]            = queueInfo;
222
223                 if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
224                         break;
225         }
226
227         deMemset(&deviceInfo, 0, sizeof(deviceInfo));
228         instance.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
229
230         deviceInfo.sType                                        = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
231         deviceInfo.pNext                                        = DE_NULL;
232         deviceInfo.enabledExtensionCount        = 0u;
233         deviceInfo.ppEnabledExtensionNames      = DE_NULL;
234         deviceInfo.enabledLayerCount            = 0u;
235         deviceInfo.ppEnabledLayerNames          = DE_NULL;
236         deviceInfo.pEnabledFeatures                     = &deviceFeatures;
237         deviceInfo.queueCreateInfoCount         = (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 1 : COUNT;
238         deviceInfo.pQueueCreateInfos            = queueInfos;
239
240         logicalDevice = vk::createDevice(instance, physicalDevice, &deviceInfo);
241
242         for (deUint32 queueReqNdx = 0; queueReqNdx < COUNT; ++queueReqNdx)
243         {
244                 if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
245                         vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, queueReqNdx, &queues[queueReqNdx].queue);
246                 else
247                         vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, 0u, &queues[queueReqNdx].queue);
248         }
249
250         semaphore                       = (createSemaphore (vk, *logicalDevice));
251         cmdPool[FIRST]          = (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[FIRST].queueFamilyIndex));
252         cmdPool[SECOND]         = (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[SECOND].queueFamilyIndex));
253         cmdBuffer[FIRST]        = (makeCommandBuffer(vk, *logicalDevice, *cmdPool[FIRST]));
254         cmdBuffer[SECOND]       = (makeCommandBuffer(vk, *logicalDevice, *cmdPool[SECOND]));
255
256         submitInfo[FIRST].sType                                 = VK_STRUCTURE_TYPE_SUBMIT_INFO;
257         submitInfo[FIRST].pNext                                 = DE_NULL;
258         submitInfo[FIRST].waitSemaphoreCount    = 0u;
259         submitInfo[FIRST].pWaitSemaphores               = DE_NULL;
260         submitInfo[FIRST].pWaitDstStageMask             = (const VkPipelineStageFlags*)DE_NULL;
261         submitInfo[FIRST].commandBufferCount    = 1u;
262         submitInfo[FIRST].pCommandBuffers               = &cmdBuffer[FIRST].get();
263         submitInfo[FIRST].signalSemaphoreCount  = 1u;
264         submitInfo[FIRST].pSignalSemaphores             = &semaphore.get();
265
266         submitInfo[SECOND].sType                                        = VK_STRUCTURE_TYPE_SUBMIT_INFO;
267         submitInfo[SECOND].pNext                                        = DE_NULL;
268         submitInfo[SECOND].waitSemaphoreCount           = 1u;
269         submitInfo[SECOND].pWaitSemaphores                      = &semaphore.get();
270         submitInfo[SECOND].pWaitDstStageMask            = stageBits;
271         submitInfo[SECOND].commandBufferCount           = 1u;
272         submitInfo[SECOND].pCommandBuffers                      = &cmdBuffer[SECOND].get();
273         submitInfo[SECOND].signalSemaphoreCount         = 0u;
274         submitInfo[SECOND].pSignalSemaphores            = DE_NULL;
275
276         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[FIRST], &info));
277         endCommandBuffer(vk, *cmdBuffer[FIRST]);
278         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[SECOND], &info));
279         endCommandBuffer(vk, *cmdBuffer[SECOND]);
280
281         fence[FIRST]  = (createFence(vk, *logicalDevice));
282         fence[SECOND] = (createFence(vk, *logicalDevice));
283
284         VK_CHECK(vk.queueSubmit(queues[FIRST].queue, 1u, &submitInfo[FIRST], *fence[FIRST]));
285         VK_CHECK(vk.queueSubmit(queues[SECOND].queue, 1u, &submitInfo[SECOND], *fence[SECOND]));
286
287         if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
288                 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
289
290         if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
291                 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
292
293         {
294                 VkSubmitInfo swapInfo                           = submitInfo[SECOND];
295                 submitInfo[SECOND]                                      = submitInfo[FIRST];
296                 submitInfo[FIRST]                                       = swapInfo;
297                 submitInfo[SECOND].pCommandBuffers      = &cmdBuffer[SECOND].get();
298                 submitInfo[FIRST].pCommandBuffers       = &cmdBuffer[FIRST].get();
299         }
300
301         VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[FIRST].get()));
302         VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[SECOND].get()));
303
304         VK_CHECK(vk.queueSubmit(queues[SECOND].queue, 1u, &submitInfo[SECOND], *fence[SECOND]));
305         VK_CHECK(vk.queueSubmit(queues[FIRST].queue, 1u, &submitInfo[FIRST], *fence[FIRST]));
306
307         if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
308                 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
309
310         if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
311                 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
312
313         return tcu::TestStatus::pass("Basic semaphore tests with multi queue passed");
314 }
315
316 } // anonymous
317
318 tcu::TestCaseGroup* createBasicSemaphoreTests (tcu::TestContext& testCtx)
319 {
320         de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "semaphore", "Basic semaphore tests"));
321         addFunctionCase(basicTests.get(), "one_queue",   "Basic semaphore tests with one queue",   basicOneQueueCase);
322         addFunctionCase(basicTests.get(), "multi_queue", "Basic semaphore tests with multi queue", basicMultiQueueCase);
323         addFunctionCase(basicTests.get(), "chain", "Semaphore chain test", basicChainCase);
324
325         return basicTests.release();
326 }
327
328 } // synchronization
329 } // vkt