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 41namespace vkt 42{ 43namespace synchronization 44{ 45namespace 46{ 47 48using namespace vk; 49using vkt::synchronization::VideoCodecOperationFlags; 50 51struct TestConfig 52{ 53 bool useTypeCreate; 54 VkSemaphoreType semaphoreType; 55 SynchronizationType type; 56 VideoCodecOperationFlags videoCodecOperationFlags; 57}; 58 59#ifdef CTS_USES_VULKANSC 60static const int basicChainLength = 1024; 61#else 62static const int basicChainLength = 32768; 63#endif 64 65Move<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 75tcu::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 130tcu::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 203tcu::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 263tcu::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 333tcu::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 411VkResult 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 455tcu::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 464tcu::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 473tcu::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 482tcu::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 491tcu::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 829void 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 841void 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 853tcu::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 885tcu::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