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
basicMultiQueueCase(Context & context,TestConfig config)411 tcu::TestStatus basicMultiQueueCase (Context& context, TestConfig config)
412 {
413 enum { NO_MATCH_FOUND = ~((deUint32)0) };
414 enum QueuesIndexes { FIRST = 0, SECOND, COUNT };
415
416 struct Queues
417 {
418 VkQueue queue;
419 deUint32 queueFamilyIndex;
420 };
421
422 #ifndef CTS_USES_VULKANSC
423 const VkInstance instance = context.getInstance();
424 const InstanceInterface& instanceInterface = context.getInstanceInterface();
425 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
426 de::MovePtr<VideoDevice> videoDevice (config.videoCodecOperationFlags != 0 ? new VideoDevice(context, config.videoCodecOperationFlags) : DE_NULL);
427 const DeviceInterface& vk = getSyncDeviceInterface(videoDevice, context);
428 std::vector<VkQueueFamilyVideoPropertiesKHR> videoQueueFamilyProperties2;
429 #else
430 const CustomInstance instance (createCustomInstanceFromContext(context));
431 const InstanceDriver& instanceDriver (instance.getDriver());
432 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
433 const InstanceInterface& instanceInterface = instanceDriver;
434 // const DeviceInterface& vk = context.getDeviceInterface();
435 // const InstanceInterface& instance = context.getInstanceInterface();
436 // const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
437 #endif // CTS_USES_VULKANSC
438 vk::Move<vk::VkDevice> logicalDevice;
439 std::vector<VkQueueFamilyProperties> queueFamilyProperties;
440 std::vector<VkQueueFamilyProperties2> queueFamilyProperties2;
441 VkDeviceCreateInfo deviceInfo;
442 VkPhysicalDeviceFeatures deviceFeatures;
443 const float queuePriorities[COUNT] = { 1.0f, 1.0f };
444 VkDeviceQueueCreateInfo queueInfos[COUNT];
445 Queues queues[COUNT] =
446 {
447 {DE_NULL, (deUint32)NO_MATCH_FOUND},
448 {DE_NULL, (deUint32)NO_MATCH_FOUND}
449 };
450 const VkCommandBufferBeginInfo info =
451 {
452 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
453 DE_NULL, // const void* pNext;
454 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // VkCommandBufferUsageFlags flags;
455 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
456 };
457
458 const bool isTimelineSemaphore = config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE;
459
460 if (config.videoCodecOperationFlags != 0)
461 {
462 #ifndef CTS_USES_VULKANSC
463 uint32_t queueFamilyPropertiesCount = 0;
464
465 instanceInterface.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
466
467 if (queueFamilyPropertiesCount > 0)
468 {
469 queueFamilyProperties2.resize(queueFamilyPropertiesCount);
470 videoQueueFamilyProperties2.resize(queueFamilyPropertiesCount);
471
472 for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
473 {
474 queueFamilyProperties2[ndx].sType = vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
475 queueFamilyProperties2[ndx].pNext = &videoQueueFamilyProperties2[ndx];
476 videoQueueFamilyProperties2[ndx].sType = vk::VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
477 videoQueueFamilyProperties2[ndx].pNext = DE_NULL;
478 videoQueueFamilyProperties2[ndx].videoCodecOperations = 0;
479 }
480
481 instanceInterface.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties2.data());
482
483 if (queueFamilyPropertiesCount != queueFamilyProperties2.size())
484 TCU_FAIL("Device returns less queue families than initially reported");
485
486 queueFamilyProperties.reserve(queueFamilyPropertiesCount);
487
488 for (size_t ndx = 0; ndx < queueFamilyPropertiesCount; ++ndx)
489 queueFamilyProperties.push_back(queueFamilyProperties2[ndx].queueFamilyProperties);
490 }
491 #endif // CTS_USES_VULKANSC
492 }
493 else
494 {
495 queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instanceInterface, physicalDevice);
496 }
497
498 for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
499 {
500 #ifndef CTS_USES_VULKANSC
501 const bool usableQueue = videoQueueFamilyProperties2.empty()
502 || (videoQueueFamilyProperties2[queueNdx].videoCodecOperations & config.videoCodecOperationFlags) != 0;
503
504 if (!usableQueue)
505 continue;
506 #endif // CTS_USES_VULKANSC
507
508 if (NO_MATCH_FOUND == queues[FIRST].queueFamilyIndex)
509 queues[FIRST].queueFamilyIndex = queueNdx;
510
511 if (queues[FIRST].queueFamilyIndex != queueNdx || queueFamilyProperties[queueNdx].queueCount > 1u)
512 {
513 queues[SECOND].queueFamilyIndex = queueNdx;
514 break;
515 }
516 }
517
518 if (queues[FIRST].queueFamilyIndex == NO_MATCH_FOUND || queues[SECOND].queueFamilyIndex == NO_MATCH_FOUND)
519 TCU_THROW(NotSupportedError, "Queues couldn't be created");
520
521 for (int queueNdx = 0; queueNdx < COUNT; ++queueNdx)
522 {
523 VkDeviceQueueCreateInfo queueInfo;
524 deMemset(&queueInfo, 0, sizeof(queueInfo));
525
526 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
527 queueInfo.pNext = DE_NULL;
528 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
529 queueInfo.queueFamilyIndex = queues[queueNdx].queueFamilyIndex;
530 queueInfo.queueCount = (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 2 : 1;
531 queueInfo.pQueuePriorities = queuePriorities;
532
533 queueInfos[queueNdx] = queueInfo;
534
535 if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
536 break;
537 }
538
539 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
540 instanceInterface.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
541
542 VkPhysicalDeviceFeatures2 createPhysicalFeature { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, DE_NULL, deviceFeatures };
543 VkPhysicalDeviceTimelineSemaphoreFeatures timelineSemaphoreFeatures { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, DE_NULL, DE_TRUE };
544 VkPhysicalDeviceSynchronization2FeaturesKHR synchronization2Features { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR, DE_NULL, DE_TRUE };
545 void** nextPtr = &createPhysicalFeature.pNext;
546
547 std::vector<const char*> deviceExtensions;
548
549 if (config.videoCodecOperationFlags != 0)
550 VideoDevice::addVideoDeviceExtensions(deviceExtensions, context.getUsedApiVersion(), VideoDevice::getQueueFlags(config.videoCodecOperationFlags), config.videoCodecOperationFlags);
551
552 if (isTimelineSemaphore)
553 {
554 if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_timeline_semaphore"))
555 deviceExtensions.push_back("VK_KHR_timeline_semaphore");
556 addToChainVulkanStructure(&nextPtr, timelineSemaphoreFeatures);
557 }
558 if (config.type == SynchronizationType::SYNCHRONIZATION2)
559 {
560 deviceExtensions.push_back("VK_KHR_synchronization2");
561 addToChainVulkanStructure(&nextPtr, synchronization2Features);
562 }
563
564 void* pNext = &createPhysicalFeature;
565 #ifdef CTS_USES_VULKANSC
566 VkDeviceObjectReservationCreateInfo memReservationInfo = context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
567 memReservationInfo.pNext = pNext;
568 pNext = &memReservationInfo;
569
570 VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
571 sc10Features.pNext = pNext;
572 pNext = &sc10Features;
573
574 VkPipelineCacheCreateInfo pcCI;
575 std::vector<VkPipelinePoolSize> poolSizes;
576 if (context.getTestContext().getCommandLine().isSubProcess())
577 {
578 if (context.getResourceInterface()->getCacheDataSize() > 0)
579 {
580 pcCI =
581 {
582 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
583 DE_NULL, // const void* pNext;
584 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
585 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
586 context.getResourceInterface()->getCacheDataSize(), // deUintptr initialDataSize;
587 context.getResourceInterface()->getCacheData() // const void* pInitialData;
588 };
589 memReservationInfo.pipelineCacheCreateInfoCount = 1;
590 memReservationInfo.pPipelineCacheCreateInfos = &pcCI;
591 }
592
593 poolSizes = context.getResourceInterface()->getPipelinePoolSizes();
594 if (!poolSizes.empty())
595 {
596 memReservationInfo.pipelinePoolSizeCount = deUint32(poolSizes.size());
597 memReservationInfo.pPipelinePoolSizes = poolSizes.data();
598 }
599 }
600 #endif // CTS_USES_VULKANSC
601
602 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
603 deviceInfo.pNext = pNext;
604 deviceInfo.enabledExtensionCount = static_cast<deUint32>(deviceExtensions.size());
605 deviceInfo.ppEnabledExtensionNames = deviceExtensions.empty() ? DE_NULL : deviceExtensions.data();
606 deviceInfo.enabledLayerCount = 0u;
607 deviceInfo.ppEnabledLayerNames = DE_NULL;
608 deviceInfo.pEnabledFeatures = 0u;
609 deviceInfo.queueCreateInfoCount = (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 1 : COUNT;
610 deviceInfo.pQueueCreateInfos = queueInfos;
611
612 logicalDevice = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instance, instanceInterface, physicalDevice, &deviceInfo);
613
614 #ifndef CTS_USES_VULKANSC
615 de::MovePtr<vk::DeviceDriver> deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), instance, *logicalDevice));
616 #else
617 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()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), *logicalDevice));
618 const DeviceInterface& vk = *deviceDriver;
619 #endif // CTS_USES_VULKANSC
620
621 for (deUint32 queueReqNdx = 0; queueReqNdx < COUNT; ++queueReqNdx)
622 {
623 if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
624 vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, queueReqNdx, &queues[queueReqNdx].queue);
625 else
626 vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, 0u, &queues[queueReqNdx].queue);
627 }
628
629 Move<VkSemaphore> semaphore;
630 Move<VkCommandPool> cmdPool[COUNT];
631 Move<VkCommandBuffer> cmdBuffer[COUNT];
632 deUint64 timelineValues[COUNT] = { 1ull, 2ull };
633 Move<VkFence> fence[COUNT];
634
635 semaphore = (createTestSemaphore(context, vk, *logicalDevice, config));
636 cmdPool[FIRST] = (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[FIRST].queueFamilyIndex));
637 cmdPool[SECOND] = (createCommandPool(vk, *logicalDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues[SECOND].queueFamilyIndex));
638 cmdBuffer[FIRST] = (makeCommandBuffer(vk, *logicalDevice, *cmdPool[FIRST]));
639 cmdBuffer[SECOND] = (makeCommandBuffer(vk, *logicalDevice, *cmdPool[SECOND]));
640
641 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[FIRST], &info));
642 endCommandBuffer(vk, *cmdBuffer[FIRST]);
643 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[SECOND], &info));
644 endCommandBuffer(vk, *cmdBuffer[SECOND]);
645
646 fence[FIRST] = (createFence(vk, *logicalDevice));
647 fence[SECOND] = (createFence(vk, *logicalDevice));
648
649 VkCommandBufferSubmitInfoKHR commandBufferInfo[]
650 {
651 makeCommonCommandBufferSubmitInfo(*cmdBuffer[FIRST]),
652 makeCommonCommandBufferSubmitInfo(*cmdBuffer[SECOND])
653 };
654
655 VkSemaphoreSubmitInfoKHR signalSemaphoreSubmitInfo[]
656 {
657 makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[FIRST], VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR),
658 makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[SECOND], VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR)
659 };
660 VkSemaphoreSubmitInfoKHR waitSemaphoreSubmitInfo =
661 makeCommonSemaphoreSubmitInfo(semaphore.get(), timelineValues[FIRST], VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
662
663 {
664 SynchronizationWrapperPtr synchronizationWrapper[]
665 {
666 getSynchronizationWrapper(config.type, vk, isTimelineSemaphore),
667 getSynchronizationWrapper(config.type, vk, isTimelineSemaphore)
668 };
669 synchronizationWrapper[FIRST]->addSubmitInfo(
670 0u, // deUint32 waitSemaphoreInfoCount
671 DE_NULL, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
672 1u, // deUint32 commandBufferInfoCount
673 &commandBufferInfo[FIRST], // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
674 1u, // deUint32 signalSemaphoreInfoCount
675 &signalSemaphoreSubmitInfo[FIRST], // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
676 DE_FALSE,
677 isTimelineSemaphore
678 );
679 synchronizationWrapper[SECOND]->addSubmitInfo(
680 1u, // deUint32 waitSemaphoreInfoCount
681 &waitSemaphoreSubmitInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
682 1u, // deUint32 commandBufferInfoCount
683 &commandBufferInfo[SECOND], // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
684 1u, // deUint32 signalSemaphoreInfoCount
685 &signalSemaphoreSubmitInfo[SECOND], // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
686 isTimelineSemaphore,
687 isTimelineSemaphore
688 );
689 VK_CHECK(synchronizationWrapper[FIRST]->queueSubmit(queues[FIRST].queue, *fence[FIRST]));
690 VK_CHECK(synchronizationWrapper[SECOND]->queueSubmit(queues[SECOND].queue, *fence[SECOND]));
691 }
692
693 if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
694 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
695
696 if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
697 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
698
699 if (isTimelineSemaphore)
700 {
701 signalSemaphoreSubmitInfo[FIRST].value = 3ull;
702 signalSemaphoreSubmitInfo[SECOND].value = 4ull;
703 waitSemaphoreSubmitInfo.value = 3ull;
704 }
705
706 // swap semaphore info compared to above submits
707 {
708 SynchronizationWrapperPtr synchronizationWrapper[]
709 {
710 getSynchronizationWrapper(config.type, vk, isTimelineSemaphore),
711 getSynchronizationWrapper(config.type, vk, isTimelineSemaphore)
712 };
713 synchronizationWrapper[FIRST]->addSubmitInfo(
714 1u, // deUint32 waitSemaphoreInfoCount
715 &waitSemaphoreSubmitInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
716 1u, // deUint32 commandBufferInfoCount
717 &commandBufferInfo[FIRST], // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
718 1u, // deUint32 signalSemaphoreInfoCount
719 &signalSemaphoreSubmitInfo[SECOND], // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
720 isTimelineSemaphore,
721 isTimelineSemaphore
722 );
723 synchronizationWrapper[SECOND]->addSubmitInfo(
724 isTimelineSemaphore ? 0u : 1u, // deUint32 waitSemaphoreInfoCount
725 isTimelineSemaphore ? DE_NULL : &waitSemaphoreSubmitInfo, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
726 1u, // deUint32 commandBufferInfoCount
727 &commandBufferInfo[SECOND], // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
728 1u, // deUint32 signalSemaphoreInfoCount
729 &signalSemaphoreSubmitInfo[FIRST], // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
730 DE_FALSE,
731 isTimelineSemaphore
732 );
733
734 VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[FIRST].get()));
735 VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[SECOND].get()));
736 VK_CHECK(synchronizationWrapper[SECOND]->queueSubmit(queues[SECOND].queue, *fence[SECOND]));
737 VK_CHECK(synchronizationWrapper[FIRST]->queueSubmit(queues[FIRST].queue, *fence[FIRST]));
738 }
739
740 if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
741 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
742
743 if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
744 return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
745
746 return tcu::TestStatus::pass("Basic semaphore tests with multi queue passed");
747 }
748
checkSupport(Context & context,TestConfig config)749 void checkSupport (Context& context, TestConfig config)
750 {
751 if (config.videoCodecOperationFlags != 0)
752 VideoDevice::checkSupport(context, config.videoCodecOperationFlags);
753
754 if (config.semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
755 context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
756
757 if (config.type == SynchronizationType::SYNCHRONIZATION2)
758 context.requireDeviceFunctionality("VK_KHR_synchronization2");
759 }
760
checkCommandBufferSimultaneousUseSupport(Context & context,TestConfig config)761 void checkCommandBufferSimultaneousUseSupport (Context& context, TestConfig config)
762 {
763 checkSupport(context, config);
764
765 #ifdef CTS_USES_VULKANSC
766 if (context.getDeviceVulkanSC10Properties().commandBufferSimultaneousUse == VK_FALSE)
767 TCU_THROW(NotSupportedError, "commandBufferSimultaneousUse is not supported");
768 #endif
769 }
770
771 } // anonymous
772
createBasicBinarySemaphoreTests(tcu::TestContext & testCtx,SynchronizationType type,VideoCodecOperationFlags videoCodecOperationFlags)773 tcu::TestCaseGroup* createBasicBinarySemaphoreTests (tcu::TestContext& testCtx, SynchronizationType type, VideoCodecOperationFlags videoCodecOperationFlags)
774 {
775 de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "binary_semaphore", "Basic semaphore tests"));
776
777 TestConfig config =
778 {
779 0,
780 VK_SEMAPHORE_TYPE_BINARY,
781 type,
782 videoCodecOperationFlags,
783 };
784 for (deUint32 typedCreate = 0; typedCreate < 2; typedCreate++)
785 {
786 config.useTypeCreate = (typedCreate != 0);
787 const std::string createName = config.useTypeCreate ? "_typed" : "";
788
789 addFunctionCase(basicTests.get(), "one_queue" + createName, "Basic binary semaphore tests with one queue", checkCommandBufferSimultaneousUseSupport, basicOneQueueCase, config);
790 addFunctionCase(basicTests.get(), "multi_queue" + createName, "Basic binary semaphore tests with multi queue", checkCommandBufferSimultaneousUseSupport, basicMultiQueueCase, config);
791 }
792
793 if (type == SynchronizationType::SYNCHRONIZATION2)
794 addFunctionCase(basicTests.get(), "none_wait_submit", "Test waiting on the none pipeline stage", checkCommandBufferSimultaneousUseSupport, noneWaitSubmitTest, config);
795
796 addFunctionCase(basicTests.get(), "chain", "Binary semaphore chain test", checkSupport, basicChainCase, config);
797
798 return basicTests.release();
799 }
800
createBasicTimelineSemaphoreTests(tcu::TestContext & testCtx,SynchronizationType type,VideoCodecOperationFlags videoCodecOperationFlags)801 tcu::TestCaseGroup* createBasicTimelineSemaphoreTests (tcu::TestContext& testCtx, SynchronizationType type, VideoCodecOperationFlags videoCodecOperationFlags)
802 {
803 de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "timeline_semaphore", "Basic timeline semaphore tests"));
804 const TestConfig config =
805 {
806 true,
807 VK_SEMAPHORE_TYPE_TIMELINE,
808 type,
809 videoCodecOperationFlags,
810 };
811
812 addFunctionCase(basicTests.get(), "one_queue", "Basic timeline semaphore tests with one queue", checkCommandBufferSimultaneousUseSupport, basicOneQueueCase, config);
813 addFunctionCase(basicTests.get(), "multi_queue", "Basic timeline semaphore tests with multi queue", checkCommandBufferSimultaneousUseSupport, basicMultiQueueCase, config);
814 addFunctionCase(basicTests.get(), "chain", "Timeline semaphore chain test", checkSupport, basicChainTimelineCase, config);
815
816 // dont repeat this test for synchronization2
817 if (type == SynchronizationType::LEGACY)
818 addFunctionCase(basicTests.get(), "two_threads","Timeline semaphore used by two threads", checkSupport, basicThreadTimelineCase, config);
819
820 return basicTests.release();
821 }
822
823 } // synchronization
824 } // vkt
825