Vulkan-Hpp
Events.cpp
Go to the documentation of this file.
1 // Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // VulkanHpp Samples : Events
16 // Use basic events
17 
18 #include "../utils/utils.hpp"
19 
20 #include <iostream>
21 
22 static char const * AppName = "Events";
23 static char const * EngineName = "Vulkan.hpp";
24 
25 int main( int /*argc*/, char ** /*argv*/ )
26 {
27  try
28  {
29  vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
30 #if !defined( NDEBUG )
32 #endif
33 
34  vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
35 
36  uint32_t graphicsQueueFamilyIndex = vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
37  vk::Device device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
38 
39  vk::CommandPool commandPool = device.createCommandPool( { {}, graphicsQueueFamilyIndex } );
40  vk::CommandBuffer commandBuffer =
42 
43  vk::Queue graphicsQueue = device.getQueue( graphicsQueueFamilyIndex, 0 );
44 
45  /* VULKAN_KEY_START */
46 
47  // Start with a trivial command buffer and make sure fence wait doesn't time out
49  commandBuffer.setViewport( 0, vk::Viewport( 0.0f, 0.0f, 10.0f, 10.0f, 0.0f, 1.0f ) );
50  commandBuffer.end();
51 
52  vk::Fence fence = device.createFence( vk::FenceCreateInfo() );
53 
54  vk::SubmitInfo submitInfo( {}, {}, commandBuffer );
55  graphicsQueue.submit( submitInfo, fence );
56 
57  // Make sure timeout is long enough for a simple command buffer without waiting for an event
58  vk::Result result;
59  int timeouts = -1;
60  do
61  {
62  result = device.waitForFences( fence, true, vk::su::FenceTimeout );
63  timeouts++;
64  } while ( result == vk::Result::eTimeout );
65  assert( result == vk::Result::eSuccess );
66  if ( timeouts != 0 )
67  {
68  std::cout << "Unsuitable timeout value, exiting\n";
69  exit( -1 );
70  }
71 
72  // Now create an event and wait for it on the GPU
74 
75  // reset the command buffer by resetting the complete command pool
76  device.resetCommandPool( commandPool );
77 
78  commandBuffer.begin( vk::CommandBufferBeginInfo() );
79  commandBuffer.waitEvents( event, vk::PipelineStageFlagBits::eHost, vk::PipelineStageFlagBits::eBottomOfPipe, nullptr, nullptr, nullptr );
80  commandBuffer.end();
81  device.resetFences( fence );
82 
83  // Note that stepping through this code in the debugger is a bad idea because the GPU can TDR waiting for the event.
84  // Execute the code from vk::Queue::submit() through vk::Device::setEvent() without breakpoints
85  graphicsQueue.submit( submitInfo, fence );
86 
87  // We should timeout waiting for the fence because the GPU should be waiting on the event
88  result = device.waitForFences( fence, true, vk::su::FenceTimeout );
89  if ( result != vk::Result::eTimeout )
90  {
91  std::cout << "Didn't get expected timeout in vk::Device::waitForFences, exiting\n";
92  exit( -1 );
93  }
94 
95  // Set the event from the CPU and wait for the fence.
96  // This should succeed since we set the event
97  device.setEvent( event );
98  do
99  {
100  result = device.waitForFences( fence, true, vk::su::FenceTimeout );
101  } while ( result == vk::Result::eTimeout );
102  assert( result == vk::Result::eSuccess );
103 
104  device.resetFences( fence );
105  device.resetEvent( event );
106 
107  // reset the command buffer by resetting the complete command pool
108  device.resetCommandPool( commandPool );
109 
110  // Now set the event from the GPU and wait on the CPU
111  commandBuffer.begin( vk::CommandBufferBeginInfo() );
112  commandBuffer.setEvent( event, vk::PipelineStageFlagBits::eBottomOfPipe );
113  commandBuffer.end();
114 
115  // Look for the event on the CPU. It should be vk::Result::eEventReset since we haven't sent the command buffer yet.
116  result = device.getEventStatus( event );
117  assert( result == vk::Result::eEventReset );
118 
119  // Send the command buffer and loop waiting for the event
120  graphicsQueue.submit( submitInfo, fence );
121 
122  int polls = 0;
123  do
124  {
125  result = device.getEventStatus( event );
126  polls++;
127  } while ( result != vk::Result::eEventSet );
128  printf( "%d polls to find the event set\n", polls );
129 
130  do
131  {
132  result = device.waitForFences( fence, true, vk::su::FenceTimeout );
133  } while ( result == vk::Result::eTimeout );
134  assert( result == vk::Result::eSuccess );
135 
136  device.destroyEvent( event );
137  device.destroyFence( fence );
138 
139  /* VULKAN_KEY_END */
140 
141  device.freeCommandBuffers( commandPool, commandBuffer );
142  device.destroyCommandPool( commandPool );
143  device.destroy();
144 #if !defined( NDEBUG )
145  instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
146 #endif
147  instance.destroy();
148  }
149  catch ( vk::SystemError & err )
150  {
151  std::cout << "vk::SystemError: " << err.what() << std::endl;
152  exit( -1 );
153  }
154  catch ( std::exception & err )
155  {
156  std::cout << "std::exception: " << err.what() << std::endl;
157  exit( -1 );
158  }
159  catch ( ... )
160  {
161  std::cout << "unknown error\n";
162  exit( -1 );
163  }
164  return 0;
165 }
int main(int, char **)
Definition: Events.cpp:25
void cout(vk::SurfaceCapabilitiesKHR const &surfaceCapabilities)
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS ResultValueType< void >::type end(Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const
VULKAN_HPP_NODISCARD Result begin(const vk::CommandBufferBeginInfo *pBeginInfo, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void setViewport(uint32_t firstViewport, uint32_t viewportCount, const vk::Viewport *pViewports, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void setEvent(vk::Event event, vk::PipelineStageFlags stageMask, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void waitEvents(uint32_t eventCount, const vk::Event *pEvents, vk::PipelineStageFlags srcStageMask, vk::PipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const vk::MemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const vk::BufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const vk::ImageMemoryBarrier *pImageMemoryBarriers, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createFence(const vk::FenceCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::Fence *pFence, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroyEvent(vk::Event event, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroy(const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void freeCommandBuffers(vk::CommandPool commandPool, uint32_t commandBufferCount, const vk::CommandBuffer *pCommandBuffers, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
ResultValueType< void >::type resetCommandPool(vk::CommandPool commandPool, vk::CommandPoolResetFlags flags VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS ResultValueType< void >::type setEvent(vk::Event event, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const
void destroyCommandPool(vk::CommandPool commandPool, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result waitForFences(uint32_t fenceCount, const vk::Fence *pFences, vk::Bool32 waitAll, uint64_t timeout, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result resetFences(uint32_t fenceCount, const vk::Fence *pFences, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createEvent(const vk::EventCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::Event *pEvent, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createCommandPool(const vk::CommandPoolCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::CommandPool *pCommandPool, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD vk::Result getEventStatus(vk::Event event, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const
void destroyFence(vk::Fence fence, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex, vk::Queue *pQueue, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result allocateCommandBuffers(const vk::CommandBufferAllocateInfo *pAllocateInfo, vk::CommandBuffer *pCommandBuffers, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
ResultValueType< void >::type resetEvent(vk::Event event, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const
VULKAN_HPP_NODISCARD Result createDebugUtilsMessengerEXT(const vk::DebugUtilsMessengerCreateInfoEXT *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::DebugUtilsMessengerEXT *pMessenger, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroy(const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result enumeratePhysicalDevices(uint32_t *pPhysicalDeviceCount, vk::PhysicalDevice *pPhysicalDevices, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroyDebugUtilsMessengerEXT(vk::DebugUtilsMessengerEXT messenger, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void getQueueFamilyProperties(uint32_t *pQueueFamilyPropertyCount, vk::QueueFamilyProperties *pQueueFamilyProperties, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result submit(uint32_t submitCount, const vk::SubmitInfo *pSubmits, vk::Fence fence, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
virtual const char * what() const VULKAN_HPP_NOEXCEPT
Definition: vulkan.hpp:6206
uint32_t findGraphicsQueueFamilyIndex(std::vector< vk::QueueFamilyProperties > const &queueFamilyProperties)
Definition: utils.cpp:409
vk::DebugUtilsMessengerCreateInfoEXT makeDebugUtilsMessengerCreateInfoEXT()
Definition: utils.cpp:1025
vk::Instance createInstance(std::string const &appName, std::string const &engineName, std::vector< std::string > const &layers, std::vector< std::string > const &extensions, uint32_t apiVersion)
Definition: utils.cpp:279
const uint64_t FenceTimeout
Definition: utils.hpp:31
vk::Device createDevice(vk::PhysicalDevice const &physicalDevice, uint32_t queueFamilyIndex, std::vector< std::string > const &extensions, vk::PhysicalDeviceFeatures const *physicalDeviceFeatures, void const *pNext)
Definition: utils.cpp:86
std::vector< std::string > getInstanceExtensions()
Definition: utils.cpp:477