Vulkan-Hpp
EnableValidationWithCallback.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 : EnableValidationWithCallback
16 // Show how to enable validation layers and provide callback
17 
18 #if defined( _MSC_VER )
19 // no need to ignore any warnings with MSVC
20 #elif defined( __clang__ )
21 # pragma clang diagnostic ignored "-Wunused-variable"
22 #elif defined( __GNUC__ )
23 # pragma GCC diagnostic ignored "-Wunused-but-set-variable"
24 #else
25 // unknow compiler... just ignore the warnings for yourselves ;)
26 #endif
27 
28 #include "../utils/utils.hpp"
29 
30 #include <algorithm>
31 #include <iostream>
32 #include <sstream>
34 
35 static char const * AppName = "EnableValidationWithCallback";
36 static char const * EngineName = "Vulkan.hpp";
37 
40 
41 VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT( VkInstance instance,
42  const VkDebugUtilsMessengerCreateInfoEXT * pCreateInfo,
43  const VkAllocationCallbacks * pAllocator,
44  VkDebugUtilsMessengerEXT * pMessenger )
45 {
46  return pfnVkCreateDebugUtilsMessengerEXT( instance, pCreateInfo, pAllocator, pMessenger );
47 }
48 
49 VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT( VkInstance instance, VkDebugUtilsMessengerEXT messenger, VkAllocationCallbacks const * pAllocator )
50 {
51  return pfnVkDestroyDebugUtilsMessengerEXT( instance, messenger, pAllocator );
52 }
53 
54 VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageFunc( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
56  VkDebugUtilsMessengerCallbackDataEXT const * pCallbackData,
57  void * /*pUserData*/ )
58 {
59  std::string message;
60 
61  message += vk::to_string( static_cast<vk::DebugUtilsMessageSeverityFlagBitsEXT>( messageSeverity ) ) + ": " +
62  vk::to_string( static_cast<vk::DebugUtilsMessageTypeFlagsEXT>( messageTypes ) ) + ":\n";
63  message += std::string( "\t" ) + "messageIDName = <" + pCallbackData->pMessageIdName + ">\n";
64  message += std::string( "\t" ) + "messageIdNumber = " + std::to_string( pCallbackData->messageIdNumber ) + "\n";
65  message += std::string( "\t" ) + "message = <" + pCallbackData->pMessage + ">\n";
66  if ( 0 < pCallbackData->queueLabelCount )
67  {
68  message += std::string( "\t" ) + "Queue Labels:\n";
69  for ( uint32_t i = 0; i < pCallbackData->queueLabelCount; i++ )
70  {
71  message += std::string( "\t\t" ) + "labelName = <" + pCallbackData->pQueueLabels[i].pLabelName + ">\n";
72  }
73  }
74  if ( 0 < pCallbackData->cmdBufLabelCount )
75  {
76  message += std::string( "\t" ) + "CommandBuffer Labels:\n";
77  for ( uint32_t i = 0; i < pCallbackData->cmdBufLabelCount; i++ )
78  {
79  message += std::string( "\t\t" ) + "labelName = <" + pCallbackData->pCmdBufLabels[i].pLabelName + ">\n";
80  }
81  }
82  if ( 0 < pCallbackData->objectCount )
83  {
84  for ( uint32_t i = 0; i < pCallbackData->objectCount; i++ )
85  {
86  message += std::string( "\t" ) + "Object " + std::to_string( i ) + "\n";
87  message += std::string( "\t\t" ) + "objectType = " + vk::to_string( static_cast<vk::ObjectType>( pCallbackData->pObjects[i].objectType ) ) + "\n";
88  message += std::string( "\t\t" ) + "objectHandle = " + std::to_string( pCallbackData->pObjects[i].objectHandle ) + "\n";
89  if ( pCallbackData->pObjects[i].pObjectName )
90  {
91  message += std::string( "\t\t" ) + "objectName = <" + pCallbackData->pObjects[i].pObjectName + ">\n";
92  }
93  }
94  }
95 
96 #ifdef _WIN32
97  MessageBox( NULL, message.c_str(), "Alert", MB_OK );
98 #else
99  std::cout << message << std::endl;
100 #endif
101 
102  return false;
103 }
104 
105 bool checkLayers( std::vector<char const *> const & layers, std::vector<vk::LayerProperties> const & properties )
106 {
107  // return true if all layers are listed in the properties
108  return std::all_of( layers.begin(),
109  layers.end(),
110  [&properties]( char const * name )
111  {
112  return std::any_of( properties.begin(),
113  properties.end(),
114  [&name]( vk::LayerProperties const & property ) { return strcmp( property.layerName, name ) == 0; } );
115  } );
116 }
117 
118 int main( int /*argc*/, char ** /*argv*/ )
119 {
120  try
121  {
122 #if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 )
123  // initialize the DipatchLoaderDynamic to use
125 #endif
126 
127  std::vector<vk::LayerProperties> instanceLayerProperties = vk::enumerateInstanceLayerProperties();
128 
129  /* VULKAN_KEY_START */
130 
131  // Use standard_validation meta layer that enables all recommended validation layers
132  std::vector<char const *> instanceLayerNames;
133  instanceLayerNames.push_back( "VK_LAYER_KHRONOS_validation" );
134  if ( !checkLayers( instanceLayerNames, instanceLayerProperties ) )
135  {
136  std::cout << "Set the environment variable VK_LAYER_PATH to point to the location of your layers" << std::endl;
137  exit( 1 );
138  }
139 
140  /* Enable debug callback extension */
141  std::vector<char const *> instanceExtensionNames;
142  instanceExtensionNames.push_back( VK_EXT_DEBUG_UTILS_EXTENSION_NAME );
143 
144  vk::ApplicationInfo applicationInfo( AppName, 1, EngineName, 1, VK_API_VERSION_1_1 );
145  vk::InstanceCreateInfo instanceCreateInfo( vk::InstanceCreateFlags(), &applicationInfo, instanceLayerNames, instanceExtensionNames );
146  vk::Instance instance = vk::createInstance( instanceCreateInfo );
147 
148 #if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 )
149  // initialize function pointers for instance
150  VULKAN_HPP_DEFAULT_DISPATCHER.init( instance );
151 #endif
152 
153  pfnVkCreateDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>( instance.getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
155  {
156  std::cout << "GetInstanceProcAddr: Unable to find pfnVkCreateDebugUtilsMessengerEXT function." << std::endl;
157  exit( 1 );
158  }
159 
160  pfnVkDestroyDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>( instance.getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
162  {
163  std::cout << "GetInstanceProcAddr: Unable to find pfnVkDestroyDebugUtilsMessengerEXT function." << std::endl;
164  exit( 1 );
165  }
166 
171  vk::DebugUtilsMessengerEXT debugUtilsMessenger =
172  instance.createDebugUtilsMessengerEXT( vk::DebugUtilsMessengerCreateInfoEXT( {}, severityFlags, messageTypeFlags, &debugMessageFunc ) );
173 
174  vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
175 
176  // get the index of the first queue family that supports graphics
177  uint32_t graphicsQueueFamilyIndex = vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
178 
179  float queuePriority = 0.0f;
180  vk::DeviceQueueCreateInfo deviceQueueCreateInfo( vk::DeviceQueueCreateFlags(), graphicsQueueFamilyIndex, 1, &queuePriority );
181  vk::Device device = physicalDevice.createDevice( vk::DeviceCreateInfo( vk::DeviceCreateFlags(), deviceQueueCreateInfo ) );
182 
183  // Create a CommandPool and don't destroy it, for testing purposes!
184  vk::CommandPool commandPool = device.createCommandPool( vk::CommandPoolCreateInfo( vk::CommandPoolCreateFlags(), graphicsQueueFamilyIndex ) );
185 
186 #if true
187  // The commandPool is not destroyed automatically
188  // That is, the device is destroyed before the commmand pool and will trigger a validation error.
189  std::cout << "*** INTENTIONALLY destroying the Device before destroying a CommandPool ***\n";
190  std::cout << "*** The following error message is EXPECTED ***\n";
191 #else
192  device.destroyCommandPool( commandPool );
193 #endif
194 
195  device.destroy();
196 #if !defined( NDEBUG )
197  instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
198 #endif
199  instance.destroy();
200 
201  /* VULKAN_KEY_END */
202  }
203  catch ( vk::SystemError & err )
204  {
205  std::cout << "vk::SystemError: " << err.what() << std::endl;
206  exit( -1 );
207  }
208  catch ( std::exception & err )
209  {
210  std::cout << "std::exception: " << err.what() << std::endl;
211  exit( -1 );
212  }
213  catch ( ... )
214  {
215  std::cout << "unknown error\n";
216  exit( -1 );
217  }
218  return 0;
219 }
int main(int, char **)
PFN_vkCreateDebugUtilsMessengerEXT pfnVkCreateDebugUtilsMessengerEXT
bool checkLayers(std::vector< char const * > const &layers, std::vector< vk::LayerProperties > const &properties)
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger)
VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageFunc(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, VkDebugUtilsMessengerCallbackDataEXT const *pCallbackData, void *)
PFN_vkDestroyDebugUtilsMessengerEXT pfnVkDestroyDebugUtilsMessengerEXT
VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, VkAllocationCallbacks const *pAllocator)
void cout(vk::SurfaceCapabilitiesKHR const &surfaceCapabilities)
void destroy(const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
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 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 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
PFN_vkVoidFunction getProcAddr(const char *pName, 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 createDevice(const vk::DeviceCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::Device *pDevice, 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
VULKAN_HPP_INLINE std::string to_string(FormatFeatureFlags value)
DebugUtilsMessageSeverityFlagBitsEXT
VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE Result createInstance(const vk::InstanceCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::Instance *pInstance, Dispatch const &d) VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE Result enumerateInstanceLayerProperties(uint32_t *pPropertyCount, vk::LayerProperties *pProperties, Dispatch const &d) VULKAN_HPP_NOEXCEPT
const char * pLabelName
const VkDebugUtilsLabelEXT * pCmdBufLabels
const VkDebugUtilsLabelEXT * pQueueLabels
const VkDebugUtilsObjectNameInfoEXT * pObjects
VkResult(* PFN_vkCreateDebugUtilsMessengerEXT)(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger)
struct VkInstance_T * VkInstance
Definition: vulkan_core.h:101
VkFlags VkDebugUtilsMessageTypeFlagsEXT
#define VK_EXT_DEBUG_UTILS_EXTENSION_NAME
uint64_t VkDebugUtilsMessengerEXT
VkResult
Definition: vulkan_core.h:140
void(* PFN_vkDestroyDebugUtilsMessengerEXT)(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks *pAllocator)
uint32_t VkBool32
Definition: vulkan_core.h:94
#define VK_API_VERSION_1_1
Definition: vulkan_core.h:4854
VkDebugUtilsMessageSeverityFlagBitsEXT
#define VULKAN_HPP_DEFAULT_DISPATCHER