@@ -67,7 +67,7 @@ static VkBufferUsageFlagBits getFlagBits(const ResourceKind RK) {
67
67
case ResourceKind::RWStructuredBuffer:
68
68
return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
69
69
case ResourceKind::ConstantBuffer:
70
- return VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ;
70
+ return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ;
71
71
}
72
72
llvm_unreachable (" All cases handled" );
73
73
}
@@ -86,6 +86,74 @@ static bool isUniform(const ResourceKind RK) {
86
86
}
87
87
llvm_unreachable (" All cases handled" );
88
88
}
89
+
90
+ static std::string getMessageSeverityString (
91
+ VkDebugUtilsMessageSeverityFlagBitsEXT MessageSeverity) {
92
+ if (MessageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
93
+ return " Error" ;
94
+ if (MessageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
95
+ return " Warning" ;
96
+ if (MessageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
97
+ return " Info" ;
98
+ if (MessageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)
99
+ return " Verbose" ;
100
+ return " Unknown" ;
101
+ }
102
+
103
+ static VkBool32
104
+ debugCallback (VkDebugUtilsMessageSeverityFlagBitsEXT MessageSeverity,
105
+ VkDebugUtilsMessageTypeFlagsEXT MessageType,
106
+ const VkDebugUtilsMessengerCallbackDataEXT *Data, void *) {
107
+ // Only interested in messages from the validation layers.
108
+ if (!(MessageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT))
109
+ return VK_FALSE;
110
+
111
+ llvm::dbgs () << " Validation " << getMessageSeverityString (MessageSeverity);
112
+ llvm::dbgs () << " : [ " << Data->pMessageIdName << " ]\n " ;
113
+ llvm::dbgs () << Data->pMessage ;
114
+
115
+ for (uint32_t I = 0 ; I < Data->objectCount ; I++) {
116
+ llvm::dbgs () << ' \n ' ;
117
+ if (Data->pObjects [I].pObjectName ) {
118
+ llvm::dbgs () << " [" << Data->pObjects [I].pObjectName << " ]" ;
119
+ }
120
+ }
121
+ llvm::dbgs () << ' \n ' ;
122
+
123
+ // Return true to true the validation error or warning into an error in the
124
+ // vulkan API. This should causes tests to fail.
125
+ const bool IsErrorOrWarning =
126
+ MessageSeverity & (VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
127
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT);
128
+ if (IsErrorOrWarning)
129
+ return VK_TRUE;
130
+
131
+ // Continue to run even with VERBOSE and INFO messages.
132
+ return VK_FALSE;
133
+ }
134
+
135
+ static VkDebugUtilsMessengerEXT registerDebugUtilCallback (VkInstance Instance) {
136
+ VkDebugUtilsMessengerCreateInfoEXT CreateInfo = {};
137
+ CreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
138
+ CreateInfo.messageSeverity =
139
+ 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
}
@@ -860,6 +936,10 @@ class VKContext {
860
936
const char *ValidationLayer = " VK_LAYER_KHRONOS_validation" ;
861
937
CreateInfo.ppEnabledLayerNames = &ValidationLayer;
862
938
CreateInfo.enabledLayerCount = 1 ;
939
+
940
+ const char *DebugUtilsExtensionName = " VK_EXT_debug_utils" ;
941
+ CreateInfo.ppEnabledExtensionNames = &DebugUtilsExtensionName;
942
+ CreateInfo.enabledExtensionCount = 1 ;
863
943
#endif
864
944
865
945
Res = vkCreateInstance (&CreateInfo, NULL , &Instance);
@@ -871,6 +951,10 @@ class VKContext {
871
951
" Unknown Vulkan initialization error %d" ,
872
952
Res);
873
953
954
+ #ifndef NDEBUG
955
+ DebugMessenger = registerDebugUtilCallback (Instance);
956
+ #endif
957
+
874
958
DeviceCount = 0 ;
875
959
if (vkEnumeratePhysicalDevices (Instance, &DeviceCount, nullptr ))
876
960
return llvm::createStringError (std::errc::no_such_device,
0 commit comments