@@ -59,6 +59,7 @@ static VkDescriptorType getDescriptorType(const ResourceKind RK) {
59
59
static VkBufferUsageFlagBits getFlagBits (const ResourceKind RK) {
60
60
switch (RK) {
61
61
case ResourceKind::Buffer:
62
+ return VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
62
63
case ResourceKind::RWBuffer:
63
64
return VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
64
65
case ResourceKind::ByteAddressBuffer:
@@ -67,7 +68,7 @@ static VkBufferUsageFlagBits getFlagBits(const ResourceKind RK) {
67
68
case ResourceKind::RWStructuredBuffer:
68
69
return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
69
70
case ResourceKind::ConstantBuffer:
70
- return VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ;
71
+ return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ;
71
72
}
72
73
llvm_unreachable (" All cases handled" );
73
74
}
@@ -86,6 +87,73 @@ static bool isUniform(const ResourceKind RK) {
86
87
}
87
88
llvm_unreachable (" All cases handled" );
88
89
}
90
+
91
+ static std::string getMessageSeverityString (
92
+ VkDebugUtilsMessageSeverityFlagBitsEXT MessageSeverity) {
93
+ if (MessageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
94
+ return " Error" ;
95
+ if (MessageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
96
+ return " Warning" ;
97
+ if (MessageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
98
+ return " Info" ;
99
+ if (MessageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)
100
+ return " Verbose" ;
101
+ return " Unknown" ;
102
+ }
103
+
104
+ static VkBool32
105
+ debugCallback (VkDebugUtilsMessageSeverityFlagBitsEXT MessageSeverity,
106
+ VkDebugUtilsMessageTypeFlagsEXT MessageType,
107
+ const VkDebugUtilsMessengerCallbackDataEXT *Data, void *) {
108
+ // Only interested in messages from the validation layers.
109
+ if (!(MessageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT))
110
+ return VK_FALSE;
111
+
112
+ llvm::dbgs () << " Validation " << getMessageSeverityString (MessageSeverity);
113
+ llvm::dbgs () << " : [ " << Data->pMessageIdName << " ]\n " ;
114
+ llvm::dbgs () << Data->pMessage ;
115
+
116
+ for (uint32_t I = 0 ; I < Data->objectCount ; I++) {
117
+ llvm::dbgs () << ' \n ' ;
118
+ if (Data->pObjects [I].pObjectName ) {
119
+ llvm::dbgs () << " [" << Data->pObjects [I].pObjectName << " ]" ;
120
+ }
121
+ }
122
+ llvm::dbgs () << ' \n ' ;
123
+
124
+ // Return true to turn the validation error or warning into an error in the
125
+ // vulkan API. This should causes tests to fail.
126
+ const bool IsErrorOrWarning =
127
+ MessageSeverity & (VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
128
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT);
129
+ if (IsErrorOrWarning)
130
+ return VK_TRUE;
131
+
132
+ // Continue to run even with VERBOSE and INFO messages.
133
+ return VK_FALSE;
134
+ }
135
+
136
+ static VkDebugUtilsMessengerEXT registerDebugUtilCallback (VkInstance Instance) {
137
+ VkDebugUtilsMessengerCreateInfoEXT CreateInfo = {};
138
+ CreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
139
+ CreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
140
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
141
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
142
+ CreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
143
+ VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
144
+ VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
145
+ CreateInfo.pfnUserCallback = debugCallback;
146
+ CreateInfo.pUserData = nullptr ; // Optional
147
+ auto Func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr (
148
+ Instance, " vkCreateDebugUtilsMessengerEXT" );
149
+ if (Func == nullptr )
150
+ return VK_NULL_HANDLE;
151
+
152
+ VkDebugUtilsMessengerEXT DebugMessenger;
153
+ Func (Instance, &CreateInfo, nullptr , &DebugMessenger);
154
+ return DebugMessenger;
155
+ }
156
+
89
157
namespace {
90
158
91
159
class VKDevice : public offloadtest ::Device {
@@ -800,6 +868,7 @@ class VKDevice : public offloadtest::Device {
800
868
class VKContext {
801
869
private:
802
870
VkInstance Instance = VK_NULL_HANDLE;
871
+ VkDebugUtilsMessengerEXT DebugMessenger = VK_NULL_HANDLE;
803
872
llvm::SmallVector<std::shared_ptr<VKDevice>> Devices;
804
873
805
874
VKContext () = default ;
@@ -813,6 +882,13 @@ class VKContext {
813
882
}
814
883
815
884
void cleanup () {
885
+ #ifndef NDEBUG
886
+ auto Func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr (
887
+ Instance, " vkDestroyDebugUtilsMessengerEXT" );
888
+ if (Func != nullptr ) {
889
+ Func (Instance, DebugMessenger, nullptr );
890
+ }
891
+ #endif
816
892
vkDestroyInstance (Instance, NULL );
817
893
Instance = VK_NULL_HANDLE;
818
894
}
@@ -869,6 +945,10 @@ class VKContext {
869
945
const char *ValidationLayer = " VK_LAYER_KHRONOS_validation" ;
870
946
CreateInfo.ppEnabledLayerNames = &ValidationLayer;
871
947
CreateInfo.enabledLayerCount = 1 ;
948
+
949
+ const char *DebugUtilsExtensionName = " VK_EXT_debug_utils" ;
950
+ CreateInfo.ppEnabledExtensionNames = &DebugUtilsExtensionName;
951
+ CreateInfo.enabledExtensionCount = 1 ;
872
952
#endif
873
953
874
954
// This second creation shouldn't ever fail, but it tries to create the
@@ -882,6 +962,10 @@ class VKContext {
882
962
" Unknown Vulkan initialization error %d" ,
883
963
Res);
884
964
965
+ #ifndef NDEBUG
966
+ DebugMessenger = registerDebugUtilCallback (Instance);
967
+ #endif
968
+
885
969
DeviceCount = 0 ;
886
970
if (vkEnumeratePhysicalDevices (Instance, &DeviceCount, nullptr ))
887
971
return llvm::createStringError (std::errc::no_such_device,
0 commit comments