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