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 event basic tests 22 *//*--------------------------------------------------------------------*/ 23 24#include "vktSynchronizationBasicEventTests.hpp" 25#include "vktTestCaseUtil.hpp" 26#include "vktSynchronizationUtil.hpp" 27 28#include "vkDefs.hpp" 29#include "vkPlatform.hpp" 30 31#include "vkRef.hpp" 32 33namespace vkt 34{ 35namespace synchronization 36{ 37namespace 38{ 39 40using namespace vk; 41#define SHORT_FENCE_WAIT 1000ull 42#define LONG_FENCE_WAIT ~0ull 43 44tcu::TestStatus hostResetSetEventCase (Context& context) 45{ 46 const DeviceInterface& vk = context.getDeviceInterface(); 47 const VkDevice device = context.getDevice(); 48 const VkEventCreateInfo eventInfo = 49 { 50 VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, 51 DE_NULL, 52 0 53 }; 54 VkEvent event; 55 Move<VkEvent> ptrEvent; 56 57 if (VK_SUCCESS != vk.createEvent(device, &eventInfo, DE_NULL, &event)) 58 return tcu::TestStatus::fail("Couldn't create event"); 59 60 ptrEvent = Move<VkEvent>(check<VkEvent>(event), Deleter<VkEvent>(vk, device, DE_NULL)); 61 62 if (VK_EVENT_RESET != vk.getEventStatus(device, event)) 63 return tcu::TestStatus::fail("Created event should be in unsignaled state"); 64 65 if (VK_SUCCESS != vk.setEvent(device, event)) 66 return tcu::TestStatus::fail("Couldn't set event"); 67 68 if (VK_EVENT_SET != vk.getEventStatus(device, event)) 69 return tcu::TestStatus::fail("Event should be in signaled state after set"); 70 71 if (VK_SUCCESS != vk.resetEvent(device, event)) 72 return tcu::TestStatus::fail("Couldn't reset event"); 73 74 if (VK_EVENT_RESET != vk.getEventStatus(device, event)) 75 return tcu::TestStatus::fail("Event should be in unsignaled state after reset"); 76 77 return tcu::TestStatus::pass("Tests set and reset event on host pass"); 78} 79 80tcu::TestStatus deviceResetSetEventCase (Context& context) 81{ 82 const DeviceInterface& vk = context.getDeviceInterface(); 83 const VkDevice device = context.getDevice(); 84 const VkQueue queue = context.getUniversalQueue(); 85 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 86 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 87 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 88 const VkSubmitInfo submitInfo = 89 { 90 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 91 DE_NULL, // const void* pNext; 92 0u, // deUint32 waitSemaphoreCount; 93 DE_NULL, // const VkSemaphore* pWaitSemaphores; 94 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 95 1u, // deUint32 commandBufferCount; 96 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 97 0u, // deUint32 signalSemaphoreCount; 98 DE_NULL, // const VkSemaphore* pSignalSemaphores; 99 }; 100 const Unique<VkEvent> event (createEvent(vk, device)); 101 102 beginCommandBuffer(vk, *cmdBuffer); 103 vk.cmdSetEvent(*cmdBuffer, *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 104 endCommandBuffer(vk, *cmdBuffer); 105 106 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL)); 107 VK_CHECK(vk.queueWaitIdle(queue)); 108 109 if (VK_EVENT_SET != vk.getEventStatus(device, *event)) 110 return tcu::TestStatus::fail("Event should be in signaled state after set"); 111 112 beginCommandBuffer(vk, *cmdBuffer); 113 vk.cmdResetEvent(*cmdBuffer, *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 114 endCommandBuffer(vk, *cmdBuffer); 115 116 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL)); 117 VK_CHECK(vk.queueWaitIdle(queue)); 118 119 if (VK_EVENT_RESET != vk.getEventStatus(device, *event)) 120 return tcu::TestStatus::fail("Event should be in unsignaled state after set"); 121 122 return tcu::TestStatus::pass("Device set and reset event tests pass"); 123} 124 125tcu::TestStatus deviceWaitForEventCase (Context& context) 126{ 127 const DeviceInterface& vk = context.getDeviceInterface(); 128 const VkDevice device = context.getDevice(); 129 const VkQueue queue = context.getUniversalQueue(); 130 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 131 const Unique<VkFence> fence (createFence(vk, device)); 132 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 133 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 134 const VkSubmitInfo submitInfo = 135 { 136 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 137 DE_NULL, // const void* pNext; 138 0u, // deUint32 waitSemaphoreCount; 139 DE_NULL, // const VkSemaphore* pWaitSemaphores; 140 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 141 1u, // deUint32 commandBufferCount; 142 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 143 0u, // deUint32 signalSemaphoreCount; 144 DE_NULL, // const VkSemaphore* pSignalSemaphores; 145 }; 146 const VkEventCreateInfo eventInfo = 147 { 148 VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, 149 DE_NULL, 150 0 151 }; 152 const Unique<VkEvent> event (createEvent(vk, device, &eventInfo, DE_NULL)); 153 154 beginCommandBuffer(vk, *cmdBuffer); 155 vk.cmdWaitEvents(*cmdBuffer, 1u, &event.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); 156 endCommandBuffer(vk, *cmdBuffer); 157 158 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 159 if (VK_TIMEOUT != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, SHORT_FENCE_WAIT)) 160 return tcu::TestStatus::fail("Queue should not end execution"); 161 162 if (VK_SUCCESS != vk.setEvent(device, *event)) 163 return tcu::TestStatus::fail("Couldn't set event"); 164 165 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT)) 166 return tcu::TestStatus::fail("Queue should end execution"); 167 168 return tcu::TestStatus::pass("Device wait for event tests pass"); 169} 170 171tcu::TestStatus singleSubmissionCase (Context& context) 172{ 173 enum {SET=0, WAIT, COUNT}; 174 const DeviceInterface& vk = context.getDeviceInterface(); 175 const VkDevice device = context.getDevice(); 176 const VkQueue queue = context.getUniversalQueue(); 177 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 178 const Unique<VkFence> fence (createFence(vk, device)); 179 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 180 const Move<VkCommandBuffer> ptrCmdBuffer[COUNT] = {makeCommandBuffer(vk, device, *cmdPool), makeCommandBuffer(vk, device, *cmdPool)}; 181 VkCommandBuffer cmdBuffers[COUNT] = {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]}; 182 const VkSubmitInfo submitInfo = 183 { 184 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 185 DE_NULL, // const void* pNext; 186 0u, // deUint32 waitSemaphoreCount; 187 DE_NULL, // const VkSemaphore* pWaitSemaphores; 188 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 189 2u, // deUint32 commandBufferCount; 190 cmdBuffers, // const VkCommandBuffer* pCommandBuffers; 191 0u, // deUint32 signalSemaphoreCount; 192 DE_NULL, // const VkSemaphore* pSignalSemaphores; 193 }; 194 const Unique<VkEvent> event (createEvent(vk, device)); 195 196 beginCommandBuffer(vk, cmdBuffers[SET]); 197 vk.cmdSetEvent(cmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 198 endCommandBuffer(vk, cmdBuffers[SET]); 199 200 beginCommandBuffer(vk, cmdBuffers[WAIT]); 201 vk.cmdWaitEvents(cmdBuffers[WAIT], 1u, &event.get(),VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); 202 endCommandBuffer(vk, cmdBuffers[WAIT]); 203 204 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 205 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT)) 206 return tcu::TestStatus::fail("Queue should end execution"); 207 208 return tcu::TestStatus::pass("Wait and set even on device single submission tests pass"); 209} 210 211tcu::TestStatus multiSubmissionCase (Context& context) 212{ 213 enum {SET=0, WAIT, COUNT}; 214 const DeviceInterface& vk = context.getDeviceInterface(); 215 const VkDevice device = context.getDevice(); 216 const VkQueue queue = context.getUniversalQueue(); 217 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 218 const Move<VkFence> ptrFence[COUNT] = 219 { 220 createFence(vk, device), 221 createFence(vk, device) 222 }; 223 VkFence fence[COUNT] = {*ptrFence[SET], *ptrFence[WAIT]}; 224 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 225 const Move<VkCommandBuffer> ptrCmdBuffer[COUNT] = {makeCommandBuffer(vk, device, *cmdPool), makeCommandBuffer(vk, device, *cmdPool)}; 226 VkCommandBuffer cmdBuffers[COUNT] = {*ptrCmdBuffer[SET], *ptrCmdBuffer[WAIT]}; 227 const VkSubmitInfo submitInfo[COUNT] = 228 { 229 { 230 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 231 DE_NULL, // const void* pNext; 232 0u, // deUint32 waitSemaphoreCount; 233 DE_NULL, // const VkSemaphore* pWaitSemaphores; 234 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 235 1u, // deUint32 commandBufferCount; 236 &cmdBuffers[SET], // const VkCommandBuffer* pCommandBuffers; 237 0u, // deUint32 signalSemaphoreCount; 238 DE_NULL, // const VkSemaphore* pSignalSemaphores; 239 }, 240 { 241 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 242 DE_NULL, // const void* pNext; 243 0u, // deUint32 waitSemaphoreCount; 244 DE_NULL, // const VkSemaphore* pWaitSemaphores; 245 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 246 1u, // deUint32 commandBufferCount; 247 &cmdBuffers[WAIT], // const VkCommandBuffer* pCommandBuffers; 248 0u, // deUint32 signalSemaphoreCount; 249 DE_NULL, // const VkSemaphore* pSignalSemaphores; 250 } 251 }; 252 const Unique<VkEvent> event (createEvent(vk, device)); 253 254 beginCommandBuffer(vk, cmdBuffers[SET]); 255 vk.cmdSetEvent(cmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 256 endCommandBuffer(vk, cmdBuffers[SET]); 257 258 beginCommandBuffer(vk, cmdBuffers[WAIT]); 259 vk.cmdWaitEvents(cmdBuffers[WAIT], 1u, &event.get(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); 260 endCommandBuffer(vk, cmdBuffers[WAIT]); 261 262 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo[SET], fence[SET])); 263 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo[WAIT], fence[WAIT])); 264 265 if (VK_SUCCESS != vk.waitForFences(device, 2u, fence, DE_TRUE, LONG_FENCE_WAIT)) 266 return tcu::TestStatus::fail("Queue should end execution"); 267 268 return tcu::TestStatus::pass("Wait and set even on device multi submission tests pass"); 269} 270 271tcu::TestStatus secondaryCommandBufferCase (Context& context) 272{ 273 enum {SET=0, WAIT, COUNT}; 274 const DeviceInterface& vk = context.getDeviceInterface(); 275 const VkDevice device = context.getDevice(); 276 const VkQueue queue = context.getUniversalQueue(); 277 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 278 const Unique<VkFence> fence (createFence(vk, device)); 279 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 280 const Move<VkCommandBuffer> primaryCmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 281 const VkCommandBufferAllocateInfo cmdBufferInfo = 282 { 283 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 284 DE_NULL, // const void* pNext; 285 *cmdPool, // VkCommandPool commandPool; 286 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; 287 1u, // deUint32 commandBufferCount; 288 }; 289 const Move<VkCommandBuffer> prtCmdBuffers[COUNT] = {allocateCommandBuffer (vk, device, &cmdBufferInfo), allocateCommandBuffer (vk, device, &cmdBufferInfo)}; 290 VkCommandBuffer secondaryCmdBuffers[] = {*prtCmdBuffers[SET], *prtCmdBuffers[WAIT]}; 291 const VkSubmitInfo submitInfo = 292 { 293 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 294 DE_NULL, // const void* pNext; 295 0u, // deUint32 waitSemaphoreCount; 296 DE_NULL, // const VkSemaphore* pWaitSemaphores; 297 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 298 1u, // deUint32 commandBufferCount; 299 &primaryCmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 300 0u, // deUint32 signalSemaphoreCount; 301 DE_NULL, // const VkSemaphore* pSignalSemaphores; 302 }; 303 const Unique<VkEvent> event (createEvent(vk, device)); 304 305 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = 306 { 307 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, //VkStructureType sType; 308 DE_NULL, //const void* pNext; 309 DE_NULL, //VkRenderPass renderPass; 310 0u, //deUint32 subpass; 311 DE_NULL, //VkFramebuffer framebuffer; 312 VK_FALSE, //VkBool32 occlusionQueryEnable; 313 (VkQueryControlFlags)0u, //VkQueryControlFlags queryFlags; 314 (VkQueryPipelineStatisticFlags)0u, //VkQueryPipelineStatisticFlags pipelineStatistics; 315 }; 316 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 317 { 318 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 319 DE_NULL, // const void* pNext; 320 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 321 &secCmdBufInheritInfo, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 322 }; 323 324 VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[SET], &cmdBufferBeginInfo)); 325 vk.cmdSetEvent(secondaryCmdBuffers[SET], *event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 326 endCommandBuffer(vk, secondaryCmdBuffers[SET]); 327 328 VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffers[WAIT], &cmdBufferBeginInfo)); 329 vk.cmdWaitEvents(secondaryCmdBuffers[WAIT], 1u, &event.get(),VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); 330 endCommandBuffer(vk, secondaryCmdBuffers[WAIT]); 331 332 beginCommandBuffer(vk, *primaryCmdBuffer); 333 vk.cmdExecuteCommands(*primaryCmdBuffer, 2u, secondaryCmdBuffers); 334 endCommandBuffer(vk, *primaryCmdBuffer); 335 336 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 337 if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT)) 338 return tcu::TestStatus::fail("Queue should end execution"); 339 340 return tcu::TestStatus::pass("Wait and set even on device using secondary command buffers tests pass"); 341} 342 343} // anonymous 344 345tcu::TestCaseGroup* createBasicEventTests (tcu::TestContext& testCtx) 346{ 347 de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "event", "Basic event tests")); 348 addFunctionCase(basicTests.get(), "host_set_reset", "Basic event tests set and reset on host", hostResetSetEventCase); 349 addFunctionCase(basicTests.get(), "device_set_reset", "Basic event tests set and reset on device", deviceResetSetEventCase); 350 addFunctionCase(basicTests.get(), "host_set_device_wait", "Wait for event on device test", deviceWaitForEventCase); 351 addFunctionCase(basicTests.get(), "single_submit_multi_command_buffer", "Wait and set event single submission on device", singleSubmissionCase); 352 addFunctionCase(basicTests.get(), "multi_submit_multi_command_buffer", "Wait and set event mutli submission on device", multiSubmissionCase); 353 addFunctionCase(basicTests.get(), "multi_secondary_command_buffer", "Event used on secondary command buffer ", secondaryCommandBufferCase); 354 355 return basicTests.release(); 356} 357 358} // synchronization 359} // vkt 360