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 #include "vktCustomInstancesDevices.hpp"
28
29 #include "vkDefs.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkDeviceUtil.hpp"
34 #include "vkRef.hpp"
35 #include "vkSafetyCriticalUtil.hpp"
36
37 #include <thread>
38
39 #include "tcuCommandLine.hpp"
40
41 namespace vkt
42 {
43 namespace synchronization
44 {
45 namespace
46 {
47
48 using namespace vk;
49 using vkt::synchronization::VideoCodecOperationFlags;
50
51 struct TestConfig
52 {
53 bool useTypeCreate;
54 VkSemaphoreType semaphoreType;
55 SynchronizationType type;
56 VideoCodecOperationFlags videoCodecOperationFlags;
57 };
58
59 #ifdef CTS_USES_VULKANSC
60 static const int basicChainLength = 1024;
61 #else
62 static const int basicChainLength = 32768;
63 #endif
64
createTestSemaphore(Context & context,const DeviceInterface & vk,const VkDevice device,const TestConfig & config)65 Move<VkSemaphore> createTestSemaphore(Context& context, const DeviceInterface& vk, const VkDevice device, const TestConfig& config)
66 {
67 if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE && !context.getTimelineSemaphoreFeatures().timelineSemaphore)
68 TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
69
70 return Move<VkSemaphore>(config.useTypeCreate ? createSemaphoreType(vk, device, config.semaphoreType) : createSemaphore(vk, device));
71 }
72
73 #define FENCE_WAIT ~0ull
74
basicOneQueueCase(Context & context,const TestConfig config)75 tcu::TestStatus basicOneQueueCase (Context& context, const TestConfig config)
76 {
77 de::MovePtr<VideoDevice> videoDevice (config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
78 const DeviceInterface& vk = getSyncDeviceInterface(videoDevice, context);
79 const VkDevice device = getSyncDevice(videoDevice, context);
80 const VkQueue queue = getSyncQueue(videoDevice, context);
81 const deUint32 queueFamilyIndex = getSyncQueueFamilyIndex(videoDevice, context);
82 const Unique<VkSemaphore> semaphore (createTestSemaphore(context, vk, device, config));
83 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
84 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
85 const VkCommandBufferBeginInfo info {
86 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
87 DE_NULL, // const void* pNext;
88 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // VkCommandBufferUsageFlags flags;
89 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
90 };
91 const deUint64 timelineValue = 1u;
92 const Unique<VkFence> fence (createFence(vk, device));
93 bool usingTimelineSemaphores = config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE;
94 VkCommandBufferSubmitInfoKHR commandBufferInfo = makeCommonCommandBufferSubmitInfo(*cmdBuffer);
95 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, usingTimelineSemaphores, 2u);
96 VkSemaphoreSubmitInfoKHR signalSemaphoreSubmitInfo = makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValue, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR);
97 VkSemaphoreSubmitInfoKHR waitSemaphoreSubmitInfo = makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValue, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
98
99 synchronizationWrapper->addSubmitInfo(
100 0u, // deUint32 waitSemaphoreInfoCount
101 DE_NULL, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
102 1u, // deUint32 commandBufferInfoCount
103 &commandBufferInfo, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
104 1u, // deUint32 signalSemaphoreInfoCount
105 &signalSemaphoreSubmitInfo, // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
106 DE_FALSE,
107 usingTimelineSemaphores
108 );
109 synchronizationWrapper->addSubmitInfo(
110 1u, // deUint32 waitSemaphoreInfoCount
111 &waitSemaphoreSubmitInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
112 1u, // deUint32 commandBufferInfoCount
113 &commandBufferInfo, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
114 0u, // deUint32 signalSemaphoreInfoCount
115 DE_NULL, // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
116 usingTimelineSemaphores,
117 DE_FALSE
118 );
119
120 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &info));
121 endCommandBuffer(vk, *cmdBuffer);
122 VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
123
124 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, FENCE_WAIT))
125 return tcu::TestStatus::fail("Basic semaphore tests with one queue failed");
126
127 return tcu::TestStatus::pass("Basic semaphore tests with one queue passed");
128 }
129
noneWaitSubmitTest(Context & context,const TestConfig config)130 tcu::TestStatus noneWaitSubmitTest (Context& context, const TestConfig config)
131 {
132 const DeviceInterface& vk = context.getDeviceInterface();
133 const VkDevice device = context.getDevice();
134 const VkQueue queue = context.getUniversalQueue();
135 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
136
137 const Unique<VkSemaphore> semaphore (createTestSemaphore(context, vk, device, config));
138 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
139
140 const Unique<VkCommandBuffer> firstbuffer (makeCommandBuffer(vk, device, *cmdPool));
141 const Unique<VkCommandBuffer> secondBuffer (makeCommandBuffer(vk, device, *cmdPool));
142
143 const VkCommandBufferBeginInfo info {
144 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
145 DE_NULL, // const void* pNext;
146 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // VkCommandBufferUsageFlags flags;
147 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
148 };
149 const Unique<VkFence> fence1 (createFence(vk, device));
150 const Unique<VkFence> fence2 (createFence(vk, device));
151 const Unique<VkEvent> event (createEvent(vk, device));
152
153 VK_CHECK(vk.beginCommandBuffer(*firstbuffer, &info));
154 endCommandBuffer(vk, *firstbuffer);
155
156 const VkSubmitInfo firstSubmitInfo {
157 VK_STRUCTURE_TYPE_SUBMIT_INFO, //VkStructureType sType
158 DE_NULL, //const void* pNext
159 0u, //uint32_t waitSemaphoreCount
160 DE_NULL, //const VkSemaphore* pWaitSemaphores
161 DE_NULL, //const VkPipelineStageFlags* pWaitDstStageMask
162 1u, //uint32_t commandBufferCount
163 &firstbuffer.get(), //const VkCommandBuffer* pCommandBuffers
164 1, //uint32_t signalSemaphoreCount
165 &semaphore.get() //const VkSemaphore* pSignalSemaphores
166 };
167
168 //check if waiting on an event in the none stage works as expected
169 VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_NONE_KHR};
170
171 const VkSubmitInfo secondSubmitInfo {
172 VK_STRUCTURE_TYPE_SUBMIT_INFO, //VkStructureType sType
173 DE_NULL, //const void* pNext
174 1u, //uint32_t waitSemaphoreCount
175 &semaphore.get(), //const VkSemaphore* pWaitSemaphores
176 waitStages, //const VkPipelineStageFlags* pWaitDstStageMask
177 1u, //uint32_t commandBufferCount
178 &secondBuffer.get(), //const VkCommandBuffer* pCommandBuffers
179 0, //uint32_t signalSemaphoreCount
180 DE_NULL //const VkSemaphore* pSignalSemaphores
181 };
182
183 VK_CHECK(vk.beginCommandBuffer(*secondBuffer, &info));
184 vk.cmdSetEvent(*secondBuffer, event.get(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
185 endCommandBuffer(vk, *secondBuffer);
186
187 VK_CHECK(vk.queueSubmit(queue, 1, &firstSubmitInfo, fence1.get()));
188 VK_CHECK(vk.queueSubmit(queue, 1, &secondSubmitInfo, fence2.get()));
189 VK_CHECK(vk.queueWaitIdle(queue));
190
191 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence1.get(), DE_TRUE, FENCE_WAIT))
192 return tcu::TestStatus::fail("None stage test failed, failed to wait for fence");
193
194 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence2.get(), DE_TRUE, FENCE_WAIT))
195 return tcu::TestStatus::fail("None stage test failed, failed to wait for the second fence");
196
197 if (vk.getEventStatus(device, event.get()) != VK_EVENT_SET)
198 return tcu::TestStatus::fail("None stage test failed, event isn't set");
199
200 return tcu::TestStatus::pass("Pass");
201 }
202
basicChainCase(Context & context,TestConfig config)203 tcu::TestStatus basicChainCase(Context & context, TestConfig config)
204 {
205 VkResult err = VK_SUCCESS;
206 de::MovePtr<VideoDevice> videoDevice (config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
207 const DeviceInterface& vk = getSyncDeviceInterface(videoDevice, context);
208 const VkDevice device = getSyncDevice(videoDevice, context);
209 const VkQueue queue = getSyncQueue(videoDevice, context);
210 VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, DE_NULL, 0 };
211 VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
212 VkFence fence;
213 std::vector<VkSemaphoreSubmitInfoKHR> waitSemaphoreSubmitInfos (basicChainLength, makeCommonSemaphoreSubmitInfo(0u, 0u, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR));
214 std::vector<VkSemaphoreSubmitInfoKHR> signalSemaphoreSubmitInfos (basicChainLength, makeCommonSemaphoreSubmitInfo(0u, 0u, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR));
215 VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfo = DE_NULL;
216 VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfo = signalSemaphoreSubmitInfos.data();
217
218 for (int i = 0; err == VK_SUCCESS && i < basicChainLength; i++)
219 {
220 if (i % (basicChainLength/4) == 0) context.getTestContext().touchWatchdog();
221
222 err = vk.createSemaphore(device, &sci, DE_NULL, &pSignalSemaphoreInfo->semaphore);
223 if (err != VK_SUCCESS)
224 continue;
225
226 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_FALSE);
227 synchronizationWrapper->addSubmitInfo(
228 !!pWaitSemaphoreInfo, // deUint32 waitSemaphoreInfoCount
229 pWaitSemaphoreInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
230 0u, // deUint32 commandBufferInfoCount
231 DE_NULL, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
232 1u, // deUint32 signalSemaphoreInfoCount
233 pSignalSemaphoreInfo // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
234 );
235
236 err = synchronizationWrapper->queueSubmit(queue, 0);
237 pWaitSemaphoreInfo = &waitSemaphoreSubmitInfos[i];
238 pWaitSemaphoreInfo->semaphore = pSignalSemaphoreInfo->semaphore;
239 pSignalSemaphoreInfo++;
240 }
241
242
243 VK_CHECK(vk.createFence(device, &fci, DE_NULL, &fence));
244
245 {
246 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_FALSE);
247 synchronizationWrapper->addSubmitInfo(1, pWaitSemaphoreInfo, 0, DE_NULL, 0, DE_NULL);
248 VK_CHECK(synchronizationWrapper->queueSubmit(queue, fence));
249 }
250
251 vk.waitForFences(device, 1, &fence, VK_TRUE, ~(0ull));
252 vk.destroyFence(device, fence, DE_NULL);
253
254 for (const auto& s : signalSemaphoreSubmitInfos)
255 vk.destroySemaphore(device, s.semaphore, DE_NULL);
256
257 if (err == VK_SUCCESS)
258 return tcu::TestStatus::pass("Basic semaphore chain test passed");
259
260 return tcu::TestStatus::fail("Basic semaphore chain test failed");
261 }
262
basicChainTimelineCase(Context & context,TestConfig config)263 tcu::TestStatus basicChainTimelineCase (Context& context, TestConfig config)
264 {
265 VkResult err = VK_SUCCESS;
266 de::MovePtr<VideoDevice> videoDevice (config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
267 const DeviceInterface& vk = getSyncDeviceInterface(videoDevice, context);
268 const VkDevice device = getSyncDevice(videoDevice, context);
269 const VkQueue queue = getSyncQueue(videoDevice, context);
270 VkSemaphoreTypeCreateInfo scti = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, DE_NULL, VK_SEMAPHORE_TYPE_TIMELINE, 0 };
271 VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &scti, 0 };
272 VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
273 VkSemaphore semaphore;
274 VkFence fence;
275
276 VK_CHECK(vk.createSemaphore(device, &sci, DE_NULL, &semaphore));
277
278 std::vector<VkSemaphoreSubmitInfoKHR> waitSemaphoreSubmitInfos (basicChainLength, makeCommonSemaphoreSubmitInfo(semaphore, 0u, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR));
279 std::vector<VkSemaphoreSubmitInfoKHR> signalSemaphoreSubmitInfos (basicChainLength, makeCommonSemaphoreSubmitInfo(semaphore, 0u, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR));
280 VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfo = DE_NULL;
281 VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfo = signalSemaphoreSubmitInfos.data();
282
283 for (int i = 0; err == VK_SUCCESS && i < basicChainLength; i++)
284 {
285 if (i % (basicChainLength/4) == 0) context.getTestContext().touchWatchdog();
286
287 pSignalSemaphoreInfo->value = static_cast<deUint64>(i+1);
288
289 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_TRUE);
290 synchronizationWrapper->addSubmitInfo(
291 !!pWaitSemaphoreInfo, // deUint32 waitSemaphoreInfoCount
292 pWaitSemaphoreInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
293 0u, // deUint32 commandBufferInfoCount
294 DE_NULL, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
295 1u, // deUint32 signalSemaphoreInfoCount
296 pSignalSemaphoreInfo, // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
297 !!pWaitSemaphoreInfo,
298 DE_TRUE
299 );
300
301 err = synchronizationWrapper->queueSubmit(queue, 0);
302
303 pWaitSemaphoreInfo = &waitSemaphoreSubmitInfos[i];
304 pWaitSemaphoreInfo->value = static_cast<deUint64>(i);
305 pSignalSemaphoreInfo++;
306 }
307
308 pWaitSemaphoreInfo->value = basicChainLength;
309 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(config.type, vk, DE_TRUE);
310 synchronizationWrapper->addSubmitInfo(
311 1u, // deUint32 waitSemaphoreInfoCount
312 pWaitSemaphoreInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
313 0u, // deUint32 commandBufferInfoCount
314 DE_NULL, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
315 0u, // deUint32 signalSemaphoreInfoCount
316 DE_NULL, // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
317 DE_TRUE
318 );
319
320 VK_CHECK(vk.createFence(device, &fci, DE_NULL, &fence));
321 VK_CHECK(synchronizationWrapper->queueSubmit(queue, fence));
322 vk.waitForFences(device, 1, &fence, VK_TRUE, ~(0ull));
323
324 vk.destroyFence(device, fence, DE_NULL);
325 vk.destroySemaphore(device, semaphore, DE_NULL);
326
327 if (err == VK_SUCCESS)
328 return tcu::TestStatus::pass("Basic semaphore chain test passed");
329
330 return tcu::TestStatus::fail("Basic semaphore chain test failed");
331 }
332
basicThreadTimelineCase(Context & context,TestConfig config)333 tcu::TestStatus basicThreadTimelineCase(Context& context, TestConfig config)
334 {
335 const VkSemaphoreTypeCreateInfo scti = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, DE_NULL, VK_SEMAPHORE_TYPE_TIMELINE, 0 };
336 de::MovePtr<VideoDevice> videoDevice (config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
337 const DeviceInterface& vk = getSyncDeviceInterface(videoDevice, context);
338 const VkDevice device = getSyncDevice(videoDevice, context);
339 const VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &scti, 0 };
340 const VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
341 const vk::Unique<vk::VkSemaphore> semaphore (createSemaphore(vk, device, &sci));
342 const Unique<VkFence> fence (createFence(vk, device, &fci));
343 const deUint64 waitTimeout = 50ull * 1000000ull; // miliseconds
344 VkResult threadResult = VK_SUCCESS;
345
346 // helper creating VkSemaphoreSignalInfo
347 auto makeSemaphoreSignalInfo = [&semaphore](deUint64 value) -> VkSemaphoreSignalInfo
348 {
349 return
350 {
351 VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, // VkStructureType sType
352 DE_NULL, // const void* pNext
353 *semaphore, // VkSemaphore semaphore
354 value // deUint64 value
355 };
356 };
357
358 // helper creating VkSemaphoreWaitInfo
359 auto makeSemaphoreWaitInfo = [&semaphore](deUint64* valuePtr) -> VkSemaphoreWaitInfo
360 {
361 return
362 {
363 VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, // VkStructureType sType
364 DE_NULL, // const void* pNext
365 VK_SEMAPHORE_WAIT_ANY_BIT, // VkSemaphoreWaitFlags flags;
366 1u, // deUint32 semaphoreCount;
367 &*semaphore, // const VkSemaphore* pSemaphores;
368 valuePtr // const deUint64* pValues;
369 };
370 };
371
372 // start thread - semaphore has value 0
373 de::MovePtr<std::thread> thread(new std::thread([=, &vk, &threadResult]
374 {
375 // wait till semaphore has value 1
376 deUint64 waitValue = 1;
377 VkSemaphoreWaitInfo waitOne = makeSemaphoreWaitInfo(&waitValue);
378 threadResult = vk.waitSemaphores(device, &waitOne, waitTimeout);
379
380 if (threadResult == VK_SUCCESS)
381 {
382 // signal semaphore with value 2
383 VkSemaphoreSignalInfo signalTwo = makeSemaphoreSignalInfo(2);
384 threadResult = vk.signalSemaphore(device, &signalTwo);
385 }
386 }));
387
388 // wait some time to give thread chance to start
389 deSleep(1); // milisecond
390
391 // signal semaphore with value 1
392 VkSemaphoreSignalInfo signalOne = makeSemaphoreSignalInfo(1);
393 vk.signalSemaphore(device, &signalOne);
394
395 // wait till semaphore has value 2
396 deUint64 waitValue = 2;
397 VkSemaphoreWaitInfo waitTwo = makeSemaphoreWaitInfo(&waitValue);
398 VkResult mainResult = vk.waitSemaphores(device, &waitTwo, waitTimeout);
399
400 thread->join();
401
402 if (mainResult == VK_SUCCESS)
403 return tcu::TestStatus::pass("Pass");
404
405 if ((mainResult == VK_TIMEOUT) || (threadResult == VK_TIMEOUT))
406 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Reached wait timeout");
407
408 return tcu::TestStatus::fail("Fail");
409 }
410
basicWaitForTimelineValueHelper(Context & context,TestConfig config,VkSemaphoreWaitFlags wait_flags,deUint64 signal_value,deUint64 wait_value)411 VkResult basicWaitForTimelineValueHelper(Context& context, TestConfig config, VkSemaphoreWaitFlags wait_flags, deUint64 signal_value, deUint64 wait_value) {
412 const VkSemaphoreTypeCreateInfo scti = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, DE_NULL, VK_SEMAPHORE_TYPE_TIMELINE, 0 };
413 de::MovePtr<VideoDevice> videoDevice (config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
414 const DeviceInterface& vk = getSyncDeviceInterface(videoDevice, context);
415 const VkDevice device = getSyncDevice(videoDevice, context);
416 const VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &scti, 0 };
417 const VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, 0 };
418 const vk::Unique<vk::VkSemaphore> semaphore (createSemaphore(vk, device, &sci));
419 const Unique<VkFence> fence (createFence(vk, device, &fci));
420 const deUint64 waitTimeout = 0; // return immediately
421
422 // helper creating VkSemaphoreSignalInfo
423 auto makeSemaphoreSignalInfo = [&semaphore](deUint64 value) -> VkSemaphoreSignalInfo
424 {
425 return
426 {
427 VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, // VkStructureType sType
428 DE_NULL, // const void* pNext
429 *semaphore, // VkSemaphore semaphore
430 value // deUint64 value
431 };
432 };
433
434 // helper creating VkSemaphoreWaitInfo
435 auto makeSemaphoreWaitInfo = [&semaphore](VkSemaphoreWaitFlags flags, deUint64* valuePtr) -> VkSemaphoreWaitInfo
436 {
437 return
438 {
439 VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, // VkStructureType sType
440 DE_NULL, // const void* pNext
441 flags, // VkSemaphoreWaitFlags flags;
442 1u, // deUint32 semaphoreCount;
443 &*semaphore, // const VkSemaphore* pSemaphores;
444 valuePtr // const deUint64* pValues;
445 };
446 };
447
448 VkSemaphoreSignalInfo signalTheValue = makeSemaphoreSignalInfo(signal_value);
449 vk.signalSemaphore(device, &signalTheValue);
450
451 VkSemaphoreWaitInfo waitForTheValue = makeSemaphoreWaitInfo(wait_flags, &wait_value);
452 return vk.waitSemaphores(device, &waitForTheValue, waitTimeout);
453 }
454
basicWaitForAnyCurrentTimelineValueCase(Context & context,TestConfig config)455 tcu::TestStatus basicWaitForAnyCurrentTimelineValueCase(Context& context, TestConfig config)
456 {
457 VkResult mainResult = basicWaitForTimelineValueHelper(context, config, VK_SEMAPHORE_WAIT_ANY_BIT, 1, 1);
458 if (mainResult == VK_SUCCESS)
459 return tcu::TestStatus::pass("Pass");
460
461 return tcu::TestStatus::fail("Fail");
462 }
463
basicWaitForAnyLesserTimelineValueCase(Context & context,TestConfig config)464 tcu::TestStatus basicWaitForAnyLesserTimelineValueCase(Context& context, TestConfig config)
465 {
466 VkResult mainResult = basicWaitForTimelineValueHelper(context, config, VK_SEMAPHORE_WAIT_ANY_BIT, 4, 1);
467 if (mainResult == VK_SUCCESS)
468 return tcu::TestStatus::pass("Pass");
469
470 return tcu::TestStatus::fail("Fail");
471 }
472
basicWaitForAllCurrentTimelineValueCase(Context & context,TestConfig config)473 tcu::TestStatus basicWaitForAllCurrentTimelineValueCase(Context& context, TestConfig config)
474 {
475 VkResult mainResult = basicWaitForTimelineValueHelper(context, config, 0, 1, 1);
476 if (mainResult == VK_SUCCESS)
477 return tcu::TestStatus::pass("Pass");
478
479 return tcu::TestStatus::fail("Fail");
480 }
481
basicWaitForAllLesserTimelineValueCase(Context & context,TestConfig config)482 tcu::TestStatus basicWaitForAllLesserTimelineValueCase(Context& context, TestConfig config)
483 {
484 VkResult mainResult = basicWaitForTimelineValueHelper(context, config, 0, 4, 1);
485 if (mainResult == VK_SUCCESS)
486 return tcu::TestStatus::pass("Pass");
487
488 return tcu::TestStatus::fail("Fail");
489 }
490
basicMultiQueueCase(Context & context,TestConfig config)491 tcu::TestStatus basicMultiQueueCase (Context& context, TestConfig config)
492 {
493 enum { NO_MATCH_FOUND = ~((deUint32)0) };
494 enum QueuesIndexes { FIRST = 0, SECOND, COUNT };
495
496 struct Queues
497 {
498 VkQueue queue;
499 deUint32 queueFamilyIndex;
500 };
501
502 #ifndef CTS_USES_VULKANSC
503 const VkInstance instance = context.getInstance();
504 const InstanceInterface& instanceInterface = context.getInstanceInterface();
505 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
506 de::MovePtr<VideoDevice> videoDevice (config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
507 const DeviceInterface& vk = getSyncDeviceInterface(videoDevice, context);
508 std::vector<VkQueueFamilyVideoPropertiesKHR> videoQueueFamilyProperties2;
509 #else
510 const CustomInstance instance (createCustomInstanceFromContext(context));
511 const InstanceDriver& instanceDriver (instance.getDriver());
512 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
513 const InstanceInterface& instanceInterface = instanceDriver;
514 // const DeviceInterface& vk = context.getDeviceInterface();
515 // const InstanceInterface& instance = context.getInstanceInterface();
516 // const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
517 #endif // CTS_USES_VULKANSC
518 vk::Move<vk::VkDevice> logicalDevice;
519 std::vector<VkQueueFamilyProperties> queueFamilyProperties;
520 std::vector<VkQueueFamilyProperties2> queueFamilyProperties2;
521 VkDeviceCreateInfo deviceInfo;
522 VkPhysicalDeviceFeatures deviceFeatures;
523 const float queuePriorities[COUNT] = { 1.0f, 1.0f };
524 VkDeviceQueueCreateInfo queueInfos[COUNT];
525 Queues queues[COUNT] =
526 {
527 {DE_NULL, (deUint32)NO_MATCH_FOUND},
528 {DE_NULL, (deUint32)NO_MATCH_FOUND}
529 };
530 const VkCommandBufferBeginInfo info =
531 {
532 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
533 DE_NULL, // const void* pNext;
534 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // VkCommandBufferUsageFlags flags;
535 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
536 };
537
538 const bool isTimelineSemaphore = config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE;
539
540 if (config.videoCodecOperationFlags != 0)
541 {
542 #ifndef CTS_USES_VULKANSC
543 uint32_t queueFamilyPropertiesCount = 0;
544
545 instanceInterface.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
546
547 if (queueFamilyPropertiesCount > 0)
548 {
549 queueFamilyProperties2.resize(queueFamilyPropertiesCount);
550 videoQueueFamilyProperties2.resize(queueFamilyPropertiesCount);
551
552 for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
553 {
554 queueFamilyProperties2[ndx].sType = vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
555 queueFamilyProperties2[ndx].pNext = &videoQueueFamilyProperties2[ndx];
556 videoQueueFamilyProperties2[ndx].sType = vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
557 videoQueueFamilyProperties2[ndx].pNext = DE_NULL;
558 videoQueueFamilyProperties2[ndx].videoCodecOperations = 0;
559 }
560
561 instanceInterface.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties2.data());
562
563 if (queueFamilyPropertiesCount != queueFamilyProperties2.size())
564 TCU_FAIL("Device returns less queue families than initially reported");
565
566 queueFamilyProperties.reserve(queueFamilyPropertiesCount);
567
568 for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
569 queueFamilyProperties.push_back(queueFamilyProperties2[ndx].queueFamilyProperties);
570 }
571 #endif // CTS_USES_VULKANSC
572 }
573 else
574 {
575 queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instanceInterface, physicalDevice);
576 }
577
578 for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
579 {
580 #ifndef CTS_USES_VULKANSC
581 const bool usableQueue = videoQueueFamilyProperties2.empty()
582 || (videoQueueFamilyProperties2[queueNdx].videoCodecOperations & config.videoCodecOperationFlags) != 0;
583
584 if (!usableQueue)
585 continue;
586 #endif // CTS_USES_VULKANSC
587
588 if (NO_MATCH_FOUND == queues[FIRST].queueFamilyIndex)
589 queues[FIRST].queueFamilyIndex = queueNdx;
590
591 if (queues[FIRST].queueFamilyIndex != queueNdx || queueFamilyProperties[queueNdx].queueCount > 1u)
592 {
593 queues[SECOND].queueFamilyIndex = queueNdx;
594 break;
595 }
596 }
597
598 if (queues[FIRST].queueFamilyIndex == NO_MATCH_FOUND || queues[SECOND].queueFamilyIndex == NO_MATCH_FOUND)
599 TCU_THROW(NotSupportedError, "Queues couldn't be created");
600
601 for (int queueNdx = 0; queueNdx < COUNT; ++queueNdx)
602 {
603 VkDeviceQueueCreateInfo queueInfo;
604 deMemset(&queueInfo, 0, sizeof(queueInfo));
605
606 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
607 queueInfo.pNext = DE_NULL;
608 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
609 queueInfo.queueFamilyIndex = queues[queueNdx].queueFamilyIndex;
610 queueInfo.queueCount = (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 2 : 1;
611 queueInfo.pQueuePriorities = queuePriorities;
612
613 queueInfos[queueNdx] = queueInfo;
614
615 if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
616 break;
617 }
618
619 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
620 instanceInterface.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
621
622 VkPhysicalDeviceFeatures2 createPhysicalFeature { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, DE_NULL, deviceFeatures };
623 VkPhysicalDeviceTimelineSemaphoreFeatures timelineSemaphoreFeatures { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, DE_NULL, DE_TRUE };
624 VkPhysicalDeviceSynchronization2FeaturesKHR synchronization2Features { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR, DE_NULL, DE_TRUE };
625 void** nextPtr = &createPhysicalFeature.pNext;
626
627 std::vector<const char*> deviceExtensions;
628
629 if (config.videoCodecOperationFlags != 0)
630 VideoDevice::addVideoDeviceExtensions(deviceExtensions, context.getUsedApiVersion(), VideoDevice::getQueueFlags(config.videoCodecOperationFlags), config.videoCodecOperationFlags);
631
632 if (isTimelineSemaphore)
633 {
634 if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_timeline_semaphore"))
635 deviceExtensions.push_back("VK_KHR_timeline_semaphore");
636 addToChainVulkanStructure(&nextPtr, timelineSemaphoreFeatures);
637 }
638 if (config.type == SynchronizationType::SYNCHRONIZATION2)
639 {
640 deviceExtensions.push_back("VK_KHR_synchronization2");
641 addToChainVulkanStructure(&nextPtr, synchronization2Features);
642 }
643
644 void* pNext = &createPhysicalFeature;
645 #ifdef CTS_USES_VULKANSC
646 VkDeviceObjectReservationCreateInfo memReservationInfo = context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
647 memReservationInfo.pNext = pNext;
648 pNext = &memReservationInfo;
649
650 VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
651 sc10Features.pNext = pNext;
652 pNext = &sc10Features;
653
654 VkPipelineCacheCreateInfo pcCI;
655 std::vector<VkPipelinePoolSize> poolSizes;
656 if (context.getTestContext().getCommandLine().isSubProcess())
657 {
658 if (context.getResourceInterface()->getCacheDataSize() > 0)
659 {
660 pcCI =
661 {
662 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
663 DE_NULL, // const void* pNext;
664 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
665 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
666 context.getResourceInterface()->getCacheDataSize(), // deUintptr initialDataSize;
667 context.getResourceInterface()->getCacheData() // const void* pInitialData;
668 };
669 memReservationInfo.pipelineCacheCreateInfoCount = 1;
670 memReservationInfo.pPipelineCacheCreateInfos = &pcCI;
671 }
672
673 poolSizes = context.getResourceInterface()->getPipelinePoolSizes();
674 if (!poolSizes.empty())
675 {
676 memReservationInfo.pipelinePoolSizeCount = deUint32(poolSizes.size());
677 memReservationInfo.pPipelinePoolSizes = poolSizes.data();
678 }
679 }
680 #endif // CTS_USES_VULKANSC
681
682 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
683 deviceInfo.pNext = pNext;
684 deviceInfo.enabledExtensionCount = static_cast<deUint32>(deviceExtensions.size());
685 deviceInfo.ppEnabledExtensionNames = deviceExtensions.empty() ? DE_NULL : deviceExtensions.data();
686 deviceInfo.enabledLayerCount = 0u;
687 deviceInfo.ppEnabledLayerNames = DE_NULL;
688 deviceInfo.pEnabledFeatures = 0u;
689 deviceInfo.queueCreateInfoCount = (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 1 : COUNT;
690 deviceInfo.pQueueCreateInfos = queueInfos;
691
692 logicalDevice = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instance, instanceInterface, physicalDevice, &deviceInfo);
693
694 #ifndef CTS_USES_VULKANSC
695 de::MovePtr<vk::DeviceDriver> deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), instance, *logicalDevice, context.getUsedApiVersion()));
696 #else
697 de::MovePtr<vk::DeviceDriverSC, vk::DeinitDeviceDeleter> deviceDriver = de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(context.getPlatformInterface(), instance, *logicalDevice, context.getTestContext().getCommandLine(), context.getResourceInterface(), context.getDeviceVulkanSC10Properties(), context.getDeviceProperties(), context.getUsedApiVersion()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), *logicalDevice));
698 const DeviceInterface& vk = *deviceDriver;
699 #endif // CTS_USES_VULKANSC
700
701 for (deUint32 queueReqNdx = 0; queueReqNdx < COUNT; ++queueReqNdx)
702 {
703 if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
704 vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, queueReqNdx, &queues[queueReqNdx].queue);
705 else
706 vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, 0u, &queues[queueReqNdx].queue);
707 }
708
709 Move<VkSemaphore> semaphore;
710 Move<VkCommandPool> cmdPool[COUNT];
711 Move<VkCommandBuffer> cmdBuffer[COUNT];
712 deUint64 timelineValues[COUNT] = { 1ull, 2ull };
713 Move<VkFence> fence[COUNT];
714
715 semaphore = (createTestSemaphore(context, vk, *logicalDevice, config));
716 cmdPool[FIRST] = (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[FIRST].queueFamilyIndex));
717 cmdPool[SECOND] = (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[SECOND].queueFamilyIndex));
718 cmdBuffer[FIRST] = (makeCommandBuffer(vk, *logicalDevice, *cmdPool[FIRST]));
719 cmdBuffer[SECOND] = (makeCommandBuffer(vk, *logicalDevice, *cmdPool[SECOND]));
720
721 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[FIRST], &info));
722 endCommandBuffer(vk, *cmdBuffer[FIRST]);
723 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[SECOND], &info));
724 endCommandBuffer(vk, *cmdBuffer[SECOND]);
725
726 fence[FIRST] = (createFence(vk, *logicalDevice));
727 fence[SECOND] = (createFence(vk, *logicalDevice));
728
729 VkCommandBufferSubmitInfoKHR commandBufferInfo[]
730 {
731 makeCommonCommandBufferSubmitInfo(*cmdBuffer[FIRST]),
732 makeCommonCommandBufferSubmitInfo(*cmdBuffer[SECOND])
733 };
734
735 VkSemaphoreSubmitInfoKHR signalSemaphoreSubmitInfo[]
736 {
737 makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[FIRST], VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR),
738 makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[SECOND], VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR)
739 };
740 VkSemaphoreSubmitInfoKHR waitSemaphoreSubmitInfo =
741 makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[FIRST], VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
742
743 {
744 SynchronizationWrapperPtr synchronizationWrapper[]
745 {
746 getSynchronizationWrapper(config.type, vk, isTimelineSemaphore),
747 getSynchronizationWrapper(config.type, vk, isTimelineSemaphore)
748 };
749 synchronizationWrapper[FIRST]->addSubmitInfo(
750 0u, // deUint32 waitSemaphoreInfoCount
751 DE_NULL, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
752 1u, // deUint32 commandBufferInfoCount
753 &commandBufferInfo[FIRST], // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
754 1u, // deUint32 signalSemaphoreInfoCount
755 &signalSemaphoreSubmitInfo[FIRST], // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
756 DE_FALSE,
757 isTimelineSemaphore
758 );
759 synchronizationWrapper[SECOND]->addSubmitInfo(
760 1u, // deUint32 waitSemaphoreInfoCount
761 &waitSemaphoreSubmitInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
762 1u, // deUint32 commandBufferInfoCount
763 &commandBufferInfo[SECOND], // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
764 1u, // deUint32 signalSemaphoreInfoCount
765 &signalSemaphoreSubmitInfo[SECOND], // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
766 isTimelineSemaphore,
767 isTimelineSemaphore
768 );
769 VK_CHECK(synchronizationWrapper[FIRST]->queueSubmit(queues[FIRST].queue, *fence[FIRST]));
770 VK_CHECK(synchronizationWrapper[SECOND]->queueSubmit(queues[SECOND].queue, *fence[SECOND]));
771 }
772
773 if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
774 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
775
776 if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
777 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
778
779 if (isTimelineSemaphore)
780 {
781 signalSemaphoreSubmitInfo[FIRST].value = 3ull;
782 signalSemaphoreSubmitInfo[SECOND].value = 4ull;
783 waitSemaphoreSubmitInfo.value = 3ull;
784 }
785
786 // swap semaphore info compared to above submits
787 {
788 SynchronizationWrapperPtr synchronizationWrapper[]
789 {
790 getSynchronizationWrapper(config.type, vk, isTimelineSemaphore),
791 getSynchronizationWrapper(config.type, vk, isTimelineSemaphore)
792 };
793 synchronizationWrapper[FIRST]->addSubmitInfo(
794 1u, // deUint32 waitSemaphoreInfoCount
795 &waitSemaphoreSubmitInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
796 1u, // deUint32 commandBufferInfoCount
797 &commandBufferInfo[FIRST], // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
798 1u, // deUint32 signalSemaphoreInfoCount
799 &signalSemaphoreSubmitInfo[SECOND], // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
800 isTimelineSemaphore,
801 isTimelineSemaphore
802 );
803 synchronizationWrapper[SECOND]->addSubmitInfo(
804 isTimelineSemaphore ? 0u : 1u, // deUint32 waitSemaphoreInfoCount
805 isTimelineSemaphore ? DE_NULL : &waitSemaphoreSubmitInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
806 1u, // deUint32 commandBufferInfoCount
807 &commandBufferInfo[SECOND], // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
808 1u, // deUint32 signalSemaphoreInfoCount
809 &signalSemaphoreSubmitInfo[FIRST], // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
810 DE_FALSE,
811 isTimelineSemaphore
812 );
813
814 VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[FIRST].get()));
815 VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[SECOND].get()));
816 VK_CHECK(synchronizationWrapper[SECOND]->queueSubmit(queues[SECOND].queue, *fence[SECOND]));
817 VK_CHECK(synchronizationWrapper[FIRST]->queueSubmit(queues[FIRST].queue, *fence[FIRST]));
818 }
819
820 if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
821 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
822
823 if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
824 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
825
826 return tcu::TestStatus::pass("Basic semaphore tests with multi queue passed");
827 }
828
checkSupport(Context & context,TestConfig config)829 void checkSupport (Context& context, TestConfig config)
830 {
831 if (config.videoCodecOperationFlags != 0)
832 VideoDevice::checkSupport(context, config.videoCodecOperationFlags);
833
834 if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
835 context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
836
837 if (config.type == SynchronizationType::SYNCHRONIZATION2)
838 context.requireDeviceFunctionality("VK_KHR_synchronization2");
839 }
840
checkCommandBufferSimultaneousUseSupport(Context & context,TestConfig config)841 void checkCommandBufferSimultaneousUseSupport (Context& context, TestConfig config)
842 {
843 checkSupport(context, config);
844
845 #ifdef CTS_USES_VULKANSC
846 if (context.getDeviceVulkanSC10Properties().commandBufferSimultaneousUse == VK_FALSE)
847 TCU_THROW(NotSupportedError, "commandBufferSimultaneousUse is not supported");
848 #endif
849 }
850
851 } // anonymous
852
createBasicBinarySemaphoreTests(tcu::TestContext & testCtx,SynchronizationType type,VideoCodecOperationFlags videoCodecOperationFlags)853 tcu::TestCaseGroup* createBasicBinarySemaphoreTests (tcu::TestContext& testCtx, SynchronizationType type, VideoCodecOperationFlags videoCodecOperationFlags)
854 {
855 de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "binary_semaphore"));
856
857 TestConfig config =
858 {
859 0,
860 VK_SEMAPHORE_TYPE_BINARY,
861 type,
862 videoCodecOperationFlags,
863 };
864 for (deUint32 typedCreate = 0; typedCreate < 2; typedCreate++)
865 {
866 config.useTypeCreate = (typedCreate != 0);
867 const std::string createName = config.useTypeCreate ? "_typed" : "";
868
869 // Basic binary semaphore tests with one queue
870 addFunctionCase(basicTests.get(), "one_queue" + createName, checkCommandBufferSimultaneousUseSupport, basicOneQueueCase, config);
871 // Basic binary semaphore tests with multi queue
872 addFunctionCase(basicTests.get(), "multi_queue" + createName, checkCommandBufferSimultaneousUseSupport, basicMultiQueueCase, config);
873 }
874
875 if (type == SynchronizationType::SYNCHRONIZATION2)
876 // Test waiting on the none pipeline stage
877 addFunctionCase(basicTests.get(), "none_wait_submit", checkCommandBufferSimultaneousUseSupport, noneWaitSubmitTest, config);
878
879 // Binary semaphore chain test
880 addFunctionCase(basicTests.get(), "chain", checkSupport, basicChainCase, config);
881
882 return basicTests.release();
883 }
884
createBasicTimelineSemaphoreTests(tcu::TestContext & testCtx,SynchronizationType type,VideoCodecOperationFlags videoCodecOperationFlags)885 tcu::TestCaseGroup* createBasicTimelineSemaphoreTests (tcu::TestContext& testCtx, SynchronizationType type, VideoCodecOperationFlags videoCodecOperationFlags)
886 {
887 // Basic timeline semaphore tests
888 de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "timeline_semaphore"));
889 const TestConfig config =
890 {
891 true,
892 VK_SEMAPHORE_TYPE_TIMELINE,
893 type,
894 videoCodecOperationFlags,
895 };
896
897 // Basic timeline semaphore tests with one queue
898 addFunctionCase(basicTests.get(), "one_queue", checkCommandBufferSimultaneousUseSupport, basicOneQueueCase, config);
899 // Basic timeline semaphore tests with multi queue
900 addFunctionCase(basicTests.get(), "multi_queue", checkCommandBufferSimultaneousUseSupport, basicMultiQueueCase, config);
901 // Timeline semaphore chain test
902 addFunctionCase(basicTests.get(), "chain", checkSupport, basicChainTimelineCase, config);
903
904 // dont repeat this test for synchronization2
905 if (type == SynchronizationType::LEGACY) {
906 // Timeline semaphore used by two threads
907 addFunctionCase(basicTests.get(), "two_threads", checkSupport, basicThreadTimelineCase, config);
908 // Wait for the currently signalled timeline semaphore value (wait for any)
909 addFunctionCase(basicTests.get(), "wait_for_any_current_value", checkSupport, basicWaitForAnyCurrentTimelineValueCase, config);
910 // Wait for a value less than the currently signalled timeline semaphore value (wait for any)
911 addFunctionCase(basicTests.get(), "wait_for_any_lesser_value", checkSupport, basicWaitForAnyLesserTimelineValueCase, config);
912 // Wait for the currently signalled timeline semaphore value (wait for all)
913 addFunctionCase(basicTests.get(), "wait_for_all_current_value", checkSupport, basicWaitForAllCurrentTimelineValueCase, config);
914 // Wait for a value less than the currently signalled timeline semaphore value (wait for all)
915 addFunctionCase(basicTests.get(), "wait_for_all_lesser_value", checkSupport, basicWaitForAllLesserTimelineValueCase, config);
916 }
917
918 return basicTests.release();
919 }
920
921 } // synchronization
922 } // vkt
923