1 /*
2 * Copyright (c) 2022 The Khronos Group Inc.
3 * Copyright (c) 2022 Valve Corporation
4 * Copyright (c) 2022 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials are
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice(s) and this permission notice shall be included in
14 * all copies or substantial portions of the Materials.
15 *
16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 *
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23 * USE OR OTHER DEALINGS IN THE MATERIALS.
24 *
25 * Author: Charles Giessen <charles@lunarg.com>
26 * Author: Mark Young <marky@lunarg.com>
27 */
28
29 #include "test_environment.h"
30
31 //
32 // VK_EXT_debug_report specific tests
33 // =========================================
34 //
35
36 // Prototype declaration for callback so we can use it in class utility methods
37 VkBool32 VKAPI_CALL test_DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object,
38 size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage,
39 void* pUserData);
40
41 class DebugReportTest : public ::testing::Test {
42 public:
VerifyExpected(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type, const std::string& message)43 void VerifyExpected(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type, const std::string& message) {
44 if (object_type == expected_object_type && 0 < (flags | expected_flag)) {
45 if (allow_any_message || (std::string::npos != message.find(expected_message))) {
46 message_found = true;
47 }
48 }
49 }
50
51 protected:
SetUp()52 virtual void SetUp() {
53 env = std::unique_ptr<FrameworkEnvironment>(new FrameworkEnvironment());
54 for (uint32_t icd = 0; icd < 3; ++icd) {
55 env->add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0));
56 env->get_test_icd(icd).physical_devices.push_back({});
57 env->get_test_icd(icd).physical_devices.push_back({});
58 }
59 // Initialize the expected output
60 allow_any_message = false;
61 expected_message = "";
62 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
63 message_found = false;
64 }
65
CreateReportInstance(VkDebugReportFlagsEXT debug_report_flags, VkInstance* inst, VkApplicationInfo* app_info = nullptr)66 VkResult CreateReportInstance(VkDebugReportFlagsEXT debug_report_flags, VkInstance* inst,
67 VkApplicationInfo* app_info = nullptr) {
68 std::vector<const char*> enabled_extensions;
69 enabled_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
70
71 // Setup the debug report struct
72 VkDebugReportCallbackCreateInfoEXT debug_report_info{VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT};
73 debug_report_info.pNext = nullptr;
74 debug_report_info.flags = debug_report_flags;
75 debug_report_info.pfnCallback = reinterpret_cast<PFN_vkDebugReportCallbackEXT>(test_DebugReportCallback);
76 debug_report_info.pUserData = reinterpret_cast<void*>(this);
77
78 // Pass it into instance create struct
79 VkInstanceCreateInfo create_info{};
80 create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
81 create_info.pNext = &debug_report_info;
82 create_info.pApplicationInfo = app_info;
83 create_info.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
84 create_info.ppEnabledExtensionNames = enabled_extensions.data();
85
86 return env->vulkan_functions.vkCreateInstance(&create_info, nullptr, inst);
87 }
88
CreateReportCallback(VkInstance inst, VkDebugReportFlagsEXT debug_report_flags, VkDebugReportCallbackEXT* callback)89 VkResult CreateReportCallback(VkInstance inst, VkDebugReportFlagsEXT debug_report_flags, VkDebugReportCallbackEXT* callback) {
90 PFN_vkCreateDebugReportCallbackEXT create_debug_report = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
91 env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkCreateDebugReportCallbackEXT"));
92 if (nullptr == create_debug_report) {
93 return VK_ERROR_INITIALIZATION_FAILED;
94 }
95 VkDebugReportCallbackCreateInfoEXT debug_report_info{VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT};
96 debug_report_info.pNext = nullptr;
97 debug_report_info.flags = debug_report_flags;
98 debug_report_info.pfnCallback = reinterpret_cast<PFN_vkDebugReportCallbackEXT>(test_DebugReportCallback);
99 debug_report_info.pUserData = reinterpret_cast<void*>(this);
100 return create_debug_report(inst, &debug_report_info, nullptr, callback);
101 }
102
DestroyReportCallback(VkInstance inst, VkDebugReportCallbackEXT callback)103 VkResult DestroyReportCallback(VkInstance inst, VkDebugReportCallbackEXT callback) {
104 PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
105 env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDestroyDebugReportCallbackEXT"));
106 if (nullptr == destroy_debug_report) {
107 return VK_ERROR_INITIALIZATION_FAILED;
108 }
109 destroy_debug_report(inst, callback, nullptr);
110 return VK_SUCCESS;
111 }
112
TearDown()113 virtual void TearDown() { env.reset(); }
114
115 std::unique_ptr<FrameworkEnvironment> env;
116 bool allow_any_message;
117 std::string expected_message;
118 VkDebugReportObjectTypeEXT expected_object_type;
119 VkDebugReportFlagBitsEXT expected_flag;
120 bool message_found;
121 };
122
123 // This is the actual callback prototyped above.
test_DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, [[maybe_unused]] uint64_t object, [[maybe_unused]] size_t location, [[maybe_unused]] int32_t messageCode, [[maybe_unused]] const char* pLayerPrefix, const char* pMessage, void* pUserData)124 VkBool32 VKAPI_CALL test_DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType,
125 [[maybe_unused]] uint64_t object, [[maybe_unused]] size_t location,
126 [[maybe_unused]] int32_t messageCode, [[maybe_unused]] const char* pLayerPrefix,
127 const char* pMessage, void* pUserData) {
128 DebugReportTest* debug_report_test = reinterpret_cast<DebugReportTest*>(pUserData);
129 debug_report_test->VerifyExpected(flags, objectType, pMessage);
130 return VK_FALSE;
131 }
132
133 class CreateDestroyInstanceReport : public DebugReportTest {};
134 class SeparateReport : public DebugReportTest {};
135 class ManualReport : public DebugReportTest {};
136
137 // Test creating and destroying instance looking for errors, but none should occur.
TEST_F(CreateDestroyInstanceReport, NoCallback)138 TEST_F(CreateDestroyInstanceReport, NoCallback) {
139 // Make sure we don't find any errors
140 allow_any_message = true;
141 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
142 expected_flag = VK_DEBUG_REPORT_ERROR_BIT_EXT;
143
144 VkInstance inst = VK_NULL_HANDLE;
145 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst));
146 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
147
148 ASSERT_EQ(false, message_found);
149 }
150
151 // Test report (error) created in vkCreateInstance with warning in vkCreateInstance
TEST_F(CreateDestroyInstanceReport, WarnInCreateIgnored)152 TEST_F(CreateDestroyInstanceReport, WarnInCreateIgnored) {
153 expected_message = "The API Variant specified";
154 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
155 expected_flag = VK_DEBUG_REPORT_WARNING_BIT_EXT;
156
157 VkApplicationInfo app_info;
158 app_info.apiVersion = VK_MAKE_API_VERSION(1, 1, 0, 0);
159 VkInstance inst = VK_NULL_HANDLE;
160 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst, &app_info));
161 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
162
163 // Message should NOT be found (because we only have errors reported in create)
164 ASSERT_EQ(false, message_found);
165 }
166
167 // Test creating and destroying instance looking for errors, but none should occur.
TEST_F(CreateDestroyInstanceReport, WarnInCreate)168 TEST_F(CreateDestroyInstanceReport, WarnInCreate) {
169 expected_message = "The API Variant specified";
170 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
171 expected_flag = VK_DEBUG_REPORT_WARNING_BIT_EXT;
172
173 VkApplicationInfo app_info;
174 app_info.apiVersion = VK_MAKE_API_VERSION(1, 1, 0, 0);
175 VkInstance inst = VK_NULL_HANDLE;
176 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_WARNING_BIT_EXT, &inst, &app_info));
177 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
178
179 // Message should be found (because we only have errors reported in create)
180 ASSERT_EQ(true, message_found);
181 }
182
183 // Test report (error/warning) created in vkCreateInstance with error in vkEnumeratePhysicalDevices.
184 // This should not be logged because we have only defined the debug report logging for vkCreateInstance
185 // and vkDestroyInstance.
TEST_F(SeparateReport, ErrorInEnumDevsNoCallback)186 TEST_F(SeparateReport, ErrorInEnumDevsNoCallback) {
187 // Look for the invaid count param message
188 expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter";
189 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
190 expected_flag = VK_DEBUG_REPORT_ERROR_BIT_EXT;
191
192 VkInstance inst = VK_NULL_HANDLE;
193 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst));
194
195 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED);
196
197 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
198
199 // Message should NOT be found (because we don't have a report callback setup outside of the create/destroy instance chain)
200 ASSERT_EQ(false, message_found);
201 }
202
203 // Test report created outside of vkCreateInstance with error in vkEnumeratePhysicalDevices.
204 // This should be logged now.
TEST_F(SeparateReport, ErrorInEnumDevs)205 TEST_F(SeparateReport, ErrorInEnumDevs) {
206 // Look for the invaid count param message
207 expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter";
208 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
209 expected_flag = VK_DEBUG_REPORT_ERROR_BIT_EXT;
210
211 VkInstance inst = VK_NULL_HANDLE;
212 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst));
213
214 VkDebugReportCallbackEXT callback;
215 ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, &callback));
216
217 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED);
218
219 ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback));
220
221 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
222
223 // Message should be found
224 ASSERT_EQ(true, message_found);
225 }
226
227 // Test report created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
228 // This should not be logged because type is wrong.
TEST_F(SeparateReport, InfoInEnumDevsIgnored)229 TEST_F(SeparateReport, InfoInEnumDevsIgnored) {
230 expected_message = "Trimming device count from 6 to 5";
231 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
232 expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
233
234 VkInstance inst = VK_NULL_HANDLE;
235 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst));
236
237 VkDebugReportCallbackEXT callback;
238 ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, &callback));
239
240 uint32_t max_count = 5;
241 std::array<VkPhysicalDevice, 5> devices;
242 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE);
243
244 ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback));
245
246 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
247
248 // Message should not be found (because it's info)
249 ASSERT_EQ(false, message_found);
250 }
251
252 // Test report created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
253 // This should be logged because type is correct.
TEST_F(SeparateReport, InfoInEnumDevs)254 TEST_F(SeparateReport, InfoInEnumDevs) {
255 expected_message = "Trimming device count from 6 to 5";
256 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
257 expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
258
259 VkInstance inst = VK_NULL_HANDLE;
260 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst));
261
262 VkDebugReportCallbackEXT callback;
263 ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, &callback));
264
265 uint32_t max_count = 5;
266 std::array<VkPhysicalDevice, 5> devices;
267 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE);
268
269 ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback));
270
271 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
272
273 // Message should be found
274 ASSERT_EQ(true, message_found);
275 }
276
277 // Test report created outside of vkCreateInstance with a manual info message of the wrong message flag type to be logged.
TEST_F(ManualReport, InfoIgnoredWrongType)278 TEST_F(ManualReport, InfoIgnoredWrongType) {
279 const char my_message[] = "This is my special message!";
280 expected_message = my_message;
281 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
282 expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
283
284 VkInstance inst = VK_NULL_HANDLE;
285 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst));
286
287 VkDebugReportCallbackEXT callback;
288 ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, &callback));
289
290 PFN_vkDebugReportMessageEXT log_debug_report =
291 reinterpret_cast<PFN_vkDebugReportMessageEXT>(env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDebugReportMessageEXT"));
292 ASSERT_NE(nullptr, log_debug_report);
293 log_debug_report(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)(inst), 0, 0,
294 nullptr, my_message);
295
296 ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback));
297
298 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
299
300 // Message should not be found
301 ASSERT_EQ(false, message_found);
302 }
303
304 // Test report created outside of vkCreateInstance with a manual info message of the wrong object type to be logged.
TEST_F(ManualReport, InfoIgnoredWrongObject)305 TEST_F(ManualReport, InfoIgnoredWrongObject) {
306 const char my_message[] = "This is my special message!";
307 expected_message = my_message;
308 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
309 expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
310
311 VkInstance inst = VK_NULL_HANDLE;
312 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst));
313
314 VkDebugReportCallbackEXT callback;
315 ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, &callback));
316
317 PFN_vkDebugReportMessageEXT log_debug_report =
318 reinterpret_cast<PFN_vkDebugReportMessageEXT>(env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDebugReportMessageEXT"));
319 ASSERT_NE(nullptr, log_debug_report);
320 log_debug_report(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)(inst), 0, 0,
321 nullptr, my_message);
322
323 ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback));
324
325 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
326
327 // Message should not be found
328 ASSERT_EQ(false, message_found);
329 }
330
331 // Test report created outside of vkCreateInstance with a manual info message to be logged.
TEST_F(ManualReport, InfoMessage)332 TEST_F(ManualReport, InfoMessage) {
333 const char my_message[] = "This is my special message!";
334 expected_message = my_message;
335 expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
336 expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
337
338 VkInstance inst = VK_NULL_HANDLE;
339 ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst));
340
341 VkDebugReportCallbackEXT callback;
342 ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, &callback));
343
344 PFN_vkDebugReportMessageEXT log_debug_report =
345 reinterpret_cast<PFN_vkDebugReportMessageEXT>(env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDebugReportMessageEXT"));
346 ASSERT_NE(nullptr, log_debug_report);
347 log_debug_report(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)(inst), 0, 0,
348 nullptr, my_message);
349
350 ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback));
351
352 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
353
354 // Message should be found
355 ASSERT_EQ(true, message_found);
356 }
357
358 //
359 // VK_EXT_debug_util specific tests
360 // =========================================
361 //
362
363 // Prototype declaration for callback so we can use it in class utility methods
364 VkBool32 VKAPI_CALL test_DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
365 VkDebugUtilsMessageTypeFlagsEXT message_types,
366 const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data);
367
368 class DebugUtilTest : public ::testing::Test {
369 public:
VerifyExpected(VkDebugUtilsMessageTypeFlagsEXT message_flags, VkDebugUtilsMessageSeverityFlagsEXT severity_flags, const std::string& message, const VkDebugUtilsMessengerCallbackDataEXT* callback_data)370 void VerifyExpected(VkDebugUtilsMessageTypeFlagsEXT message_flags, VkDebugUtilsMessageSeverityFlagsEXT severity_flags,
371 const std::string& message, const VkDebugUtilsMessengerCallbackDataEXT* callback_data) {
372 if ((0 < (severity_flags | expected_severity_flags)) && (0 < (message_flags | expected_message_flags))) {
373 if (allow_any_message || (std::string::npos != message.find(expected_message))) {
374 for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
375 if (callback_data->pObjects[obj].objectType == expected_object_type &&
376 (!check_object_handle || callback_data->pObjects[obj].objectHandle == expected_object_handle)) {
377 message_found = true;
378 break;
379 }
380 }
381 }
382 }
383 }
384
385 protected:
SetUp()386 virtual void SetUp() {
387 env = std::unique_ptr<FrameworkEnvironment>(new FrameworkEnvironment());
388 for (uint32_t icd = 0; icd < 3; ++icd) {
389 env->add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0));
390 env->get_test_icd(icd).physical_devices.push_back({});
391 env->get_test_icd(icd).physical_devices.push_back({});
392 }
393 // Initialize the expected output
394 allow_any_message = false;
395 expected_message = "";
396 expected_object_type = VK_OBJECT_TYPE_UNKNOWN;
397 check_object_handle = false;
398 expected_object_handle = 0;
399 message_found = false;
400 }
401
CreateUtilsInstance(VkDebugUtilsMessageTypeFlagsEXT types, VkDebugUtilsMessageSeverityFlagsEXT severities, VkInstance* inst, VkApplicationInfo* app_info = nullptr)402 VkResult CreateUtilsInstance(VkDebugUtilsMessageTypeFlagsEXT types, VkDebugUtilsMessageSeverityFlagsEXT severities,
403 VkInstance* inst, VkApplicationInfo* app_info = nullptr) {
404 std::vector<const char*> enabled_extensions;
405 enabled_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
406
407 // Setup the debug utils struct
408 VkDebugUtilsMessengerCreateInfoEXT debug_utils_info{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT};
409 debug_utils_info.pNext = nullptr;
410 debug_utils_info.messageSeverity = severities;
411 debug_utils_info.messageType = types;
412 debug_utils_info.pfnUserCallback = reinterpret_cast<PFN_vkDebugUtilsMessengerCallbackEXT>(test_DebugUtilsCallback);
413 debug_utils_info.pUserData = reinterpret_cast<void*>(this);
414
415 VkInstanceCreateInfo create_info{};
416 create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
417 create_info.pNext = &debug_utils_info;
418 create_info.pApplicationInfo = app_info;
419 create_info.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
420 create_info.ppEnabledExtensionNames = enabled_extensions.data();
421 return env->vulkan_functions.vkCreateInstance(&create_info, nullptr, inst);
422 }
423
CreateUtilsMessenger(VkInstance inst, VkDebugUtilsMessageTypeFlagsEXT types, VkDebugUtilsMessageSeverityFlagsEXT severities, VkDebugUtilsMessengerEXT* messenger)424 VkResult CreateUtilsMessenger(VkInstance inst, VkDebugUtilsMessageTypeFlagsEXT types,
425 VkDebugUtilsMessageSeverityFlagsEXT severities, VkDebugUtilsMessengerEXT* messenger) {
426 PFN_vkCreateDebugUtilsMessengerEXT create_messenger = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(
427 env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkCreateDebugUtilsMessengerEXT"));
428 if (nullptr == create_messenger) {
429 return VK_ERROR_INITIALIZATION_FAILED;
430 }
431 VkDebugUtilsMessengerCreateInfoEXT debug_utils_info{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT};
432 debug_utils_info.pNext = nullptr;
433 debug_utils_info.messageSeverity = severities;
434 debug_utils_info.messageType = types;
435 debug_utils_info.pfnUserCallback = reinterpret_cast<PFN_vkDebugUtilsMessengerCallbackEXT>(test_DebugUtilsCallback);
436 debug_utils_info.pUserData = reinterpret_cast<void*>(this);
437 return create_messenger(inst, &debug_utils_info, nullptr, messenger);
438 }
439
DestroyUtilsMessenger(VkInstance inst, VkDebugUtilsMessengerEXT messenger)440 VkResult DestroyUtilsMessenger(VkInstance inst, VkDebugUtilsMessengerEXT messenger) {
441 PFN_vkDestroyDebugUtilsMessengerEXT destroy_messenger = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(
442 env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDestroyDebugUtilsMessengerEXT"));
443 if (nullptr == destroy_messenger) {
444 return VK_ERROR_INITIALIZATION_FAILED;
445 }
446 destroy_messenger(inst, messenger, nullptr);
447 return VK_SUCCESS;
448 }
449
TearDown()450 virtual void TearDown() { env.reset(); }
451
452 std::unique_ptr<FrameworkEnvironment> env;
453 bool allow_any_message;
454 std::string expected_message;
455 VkObjectType expected_object_type;
456 bool check_object_handle;
457 uint64_t expected_object_handle;
458 VkDebugUtilsMessageTypeFlagsEXT expected_message_flags;
459 VkDebugUtilsMessageSeverityFlagsEXT expected_severity_flags;
460 bool message_found;
461 };
462
463 // This is the actual callback prototyped above.
464
test_DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, VkDebugUtilsMessageTypeFlagsEXT message_types, const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data)465 VkBool32 VKAPI_CALL test_DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
466 VkDebugUtilsMessageTypeFlagsEXT message_types,
467 const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) {
468 DebugUtilTest* debug_util_test = reinterpret_cast<DebugUtilTest*>(user_data);
469 debug_util_test->VerifyExpected(message_types, message_severity, callback_data->pMessage, callback_data);
470 return VK_FALSE;
471 }
472
473 class CreateDestroyInstanceMessenger : public DebugUtilTest {};
474 class SeparateMessenger : public DebugUtilTest {};
475 class ManualMessage : public DebugUtilTest {};
476
477 // Test creating and destroying instance looking for errors, but none should occur.
TEST_F(CreateDestroyInstanceMessenger, NoCallback)478 TEST_F(CreateDestroyInstanceMessenger, NoCallback) {
479 // Make sure we don't find any errors
480 allow_any_message = true;
481 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
482 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
483 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
484
485 VkInstance inst = VK_NULL_HANDLE;
486 ASSERT_EQ(VK_SUCCESS,
487 CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
488 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
489 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
490
491 ASSERT_EQ(false, message_found);
492 }
493
494 // Test debug utils (error) created in vkCreateInstance with warning in vkCreateInstance
TEST_F(CreateDestroyInstanceMessenger, WarnInCreateIgnored)495 TEST_F(CreateDestroyInstanceMessenger, WarnInCreateIgnored) {
496 expected_message = "The API Variant specified";
497 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
498 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
499 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
500
501 VkApplicationInfo app_info;
502 app_info.apiVersion = VK_MAKE_API_VERSION(1, 1, 0, 0);
503
504 VkInstance inst = VK_NULL_HANDLE;
505 ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
506 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst, &app_info));
507 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
508
509 ASSERT_EQ(false, message_found);
510 }
511
512 // Test debug utils (error/warning) created in vkCreateInstance with warning in vkCreateInstance
TEST_F(CreateDestroyInstanceMessenger, WarnInCreate)513 TEST_F(CreateDestroyInstanceMessenger, WarnInCreate) {
514 expected_message = "The API Variant specified";
515 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
516 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
517 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
518
519 VkApplicationInfo app_info;
520 app_info.apiVersion = VK_MAKE_API_VERSION(1, 1, 0, 0);
521
522 VkInstance inst = VK_NULL_HANDLE;
523 ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
524 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, &inst, &app_info));
525 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
526
527 ASSERT_EQ(true, message_found);
528 }
529
530 // Test debug utils error created in vkCreateInstance with error in vkEnumeratePhysicalDevices.
531 // This should not be logged because we have only defined the debug utils logging for vkCreateInstance
532 // and vkDestroyInstance.
TEST_F(SeparateMessenger, ErrorInEnumDevsNoMessenger)533 TEST_F(SeparateMessenger, ErrorInEnumDevsNoMessenger) {
534 expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter";
535 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
536 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
537 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
538
539 VkInstance inst = VK_NULL_HANDLE;
540 ASSERT_EQ(VK_SUCCESS,
541 CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
542 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
543
544 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED);
545
546 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
547
548 // Message should NOT be found (because we don't have a report callback setup outside of the create/destroy instance chain)
549 ASSERT_EQ(false, message_found);
550 }
551
552 // Test debug utils created outside of vkCreateInstance with error in vkEnumeratePhysicalDevices, but, with the wrong
553 // message type so it still won't be logged.
TEST_F(SeparateMessenger, ErrorInEnumDevsWrongType)554 TEST_F(SeparateMessenger, ErrorInEnumDevsWrongType) {
555 expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter";
556 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
557 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
558 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
559
560 VkInstance inst = VK_NULL_HANDLE;
561 ASSERT_EQ(VK_SUCCESS,
562 CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
563 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
564
565 // Create the debug utils messenger to collect performance warnings and errors
566 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
567 ASSERT_EQ(VK_SUCCESS,
568 CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
569 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
570 &messenger));
571
572 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED);
573
574 // Now that we should have gotten our message, destroy the messenger
575 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
576
577 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
578
579 ASSERT_EQ(false, message_found);
580 }
581
582 // Test debug utils created outside of vkCreateInstance with error in vkEnumeratePhysicalDevices, but, with the wrong
583 // message severity so it still won't be logged.
TEST_F(SeparateMessenger, ErrorInEnumDevsWrongSeverity)584 TEST_F(SeparateMessenger, ErrorInEnumDevsWrongSeverity) {
585 expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter";
586 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
587 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
588 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
589
590 VkInstance inst = VK_NULL_HANDLE;
591 ASSERT_EQ(VK_SUCCESS,
592 CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
593 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
594
595 // Create the debug utils messenger to collect only validation warnings
596 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
597 ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
598 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, &messenger));
599
600 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED);
601
602 // Now that we should have gotten our message, destroy the messenger
603 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
604
605 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
606
607 ASSERT_EQ(false, message_found);
608 }
609
610 // Test debug utils created outside of vkCreateInstance with error in vkEnumeratePhysicalDevices with the correct type.
TEST_F(SeparateMessenger, ErrorInEnumDevs)611 TEST_F(SeparateMessenger, ErrorInEnumDevs) {
612 expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter";
613 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
614 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
615 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
616
617 VkInstance inst = VK_NULL_HANDLE;
618 ASSERT_EQ(VK_SUCCESS,
619 CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
620 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
621
622 // Create the debug utils messenger to collect validation errors
623 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
624 ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
625 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &messenger));
626
627 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED);
628
629 // Now that we should have gotten our message, destroy the messenger
630 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
631
632 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
633
634 ASSERT_EQ(true, message_found);
635 }
636
637 // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
638 // This should not be logged because type is wrong.
TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredType)639 TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredType) {
640 expected_message = "Trimming device count from 6 to 5";
641 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
642 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
643 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
644
645 VkInstance inst = VK_NULL_HANDLE;
646 ASSERT_EQ(VK_SUCCESS,
647 CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
648 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
649
650 // Create the debug utils messenger to collect validation info
651 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
652 ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
653 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, &messenger));
654
655 uint32_t max_count = 5;
656 std::array<VkPhysicalDevice, 5> devices;
657 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE);
658
659 // Now that we should have gotten our message, destroy the messenger
660 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
661
662 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
663
664 // Message should not be found (because it's info)
665 ASSERT_EQ(false, message_found);
666 }
667
668 // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
669 // This should not be logged because severity is wrong.
TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredSeverity)670 TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredSeverity) {
671 expected_message = "Trimming device count from 6 to 5";
672 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
673 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
674 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
675
676 VkInstance inst = VK_NULL_HANDLE;
677 ASSERT_EQ(VK_SUCCESS,
678 CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
679 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
680
681 // Create the debug utils messenger to collect general errors/warnings
682 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
683 ASSERT_EQ(VK_SUCCESS,
684 CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
685 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
686 &messenger));
687
688 uint32_t max_count = 5;
689 std::array<VkPhysicalDevice, 5> devices;
690 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE);
691
692 // Now that we should have gotten our message, destroy the messenger
693 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
694
695 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
696
697 // Message should not be found (because it's info)
698 ASSERT_EQ(false, message_found);
699 }
700
701 // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
TEST_F(SeparateMessenger, InfoInEnumDevs)702 TEST_F(SeparateMessenger, InfoInEnumDevs) {
703 expected_message = "Trimming device count from 6 to 5";
704 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
705 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
706 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
707
708 VkInstance inst = VK_NULL_HANDLE;
709 ASSERT_EQ(VK_SUCCESS,
710 CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
711 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
712 ASSERT_EQ(false, message_found);
713
714 // Create the debug utils messenger to collect general errors/warnings
715 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
716 ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
717 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, &messenger));
718
719 uint32_t max_count = 5;
720 std::array<VkPhysicalDevice, 5> devices;
721 ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE);
722
723 // Now that we should have gotten our message, destroy the messenger
724 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
725
726 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
727
728 // Message should be found
729 ASSERT_EQ(true, message_found);
730 }
731
732 // Test messenger created outside of vkCreateInstance with a manual info message of the wrong message severity to be logged.
TEST_F(ManualMessage, InfoMessageIgnoredSeverity)733 TEST_F(ManualMessage, InfoMessageIgnoredSeverity) {
734 const char my_message[] = "This is my special message!";
735 expected_message = my_message;
736 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
737 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
738 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
739
740 VkInstance inst = VK_NULL_HANDLE;
741 ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
742 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
743
744 // Create the debug utils messenger to collect general errors/warnings
745 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
746 ASSERT_EQ(VK_SUCCESS,
747 CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
748 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
749 &messenger));
750
751 // Trigger the message
752 PFN_vkSubmitDebugUtilsMessageEXT submit_message = reinterpret_cast<PFN_vkSubmitDebugUtilsMessageEXT>(
753 env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkSubmitDebugUtilsMessageEXT"));
754 ASSERT_NE(nullptr, submit_message);
755
756 VkDebugUtilsObjectNameInfoEXT object{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT};
757 object.objectType = VK_OBJECT_TYPE_INSTANCE;
758 object.objectHandle = (uint64_t)inst;
759 VkDebugUtilsMessengerCallbackDataEXT message_data{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT};
760 message_data.pMessage = my_message;
761 message_data.objectCount = 1;
762 message_data.pObjects = &object;
763 submit_message(inst, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &message_data);
764
765 // Now that we should have gotten our message, destroy the messenger
766 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
767
768 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
769
770 // Message should not be found
771 ASSERT_EQ(false, message_found);
772 }
773
774 // Test messenger created outside of vkCreateInstance with a manual info message of the wrong object type to be logged.
TEST_F(ManualMessage, InfoMessageIgnoredObject)775 TEST_F(ManualMessage, InfoMessageIgnoredObject) {
776 const char my_message[] = "This is my special message!";
777 expected_message = my_message;
778 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
779 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
780 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
781
782 VkInstance inst = VK_NULL_HANDLE;
783 ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
784 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
785
786 // Create the debug utils messenger to collect general errors/warnings
787 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
788 ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
789 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, &messenger));
790
791 // Trigger the message
792 PFN_vkSubmitDebugUtilsMessageEXT submit_message = reinterpret_cast<PFN_vkSubmitDebugUtilsMessageEXT>(
793 env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkSubmitDebugUtilsMessageEXT"));
794 ASSERT_NE(nullptr, submit_message);
795
796 VkDebugUtilsObjectNameInfoEXT object{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT};
797 object.objectType = VK_OBJECT_TYPE_COMMAND_POOL;
798 object.objectHandle = (uint64_t)inst;
799 VkDebugUtilsMessengerCallbackDataEXT message_data{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT};
800 message_data.pMessage = my_message;
801 message_data.objectCount = 1;
802 message_data.pObjects = &object;
803 submit_message(inst, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &message_data);
804
805 // Now that we should have gotten our message, destroy the messenger
806 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
807
808 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
809
810 // Message should not be found
811 ASSERT_EQ(false, message_found);
812 }
813
814 // Test messenger created outside of vkCreateInstance with a manual info message.
TEST_F(ManualMessage, InfoMessage)815 TEST_F(ManualMessage, InfoMessage) {
816 const char my_message[] = "This is my special message!";
817 expected_message = my_message;
818 expected_object_type = VK_OBJECT_TYPE_INSTANCE;
819 expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
820 expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
821
822 VkInstance inst = VK_NULL_HANDLE;
823 ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
824 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst));
825
826 // Create the debug utils messenger to collect general errors/warnings
827 VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
828 ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
829 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, &messenger));
830
831 // Trigger the message
832 PFN_vkSubmitDebugUtilsMessageEXT submit_message = reinterpret_cast<PFN_vkSubmitDebugUtilsMessageEXT>(
833 env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkSubmitDebugUtilsMessageEXT"));
834 ASSERT_NE(nullptr, submit_message);
835
836 VkDebugUtilsObjectNameInfoEXT object{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT};
837 object.objectType = VK_OBJECT_TYPE_INSTANCE;
838 object.objectHandle = (uint64_t)inst;
839 VkDebugUtilsMessengerCallbackDataEXT message_data{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT};
840 message_data.pMessage = my_message;
841 message_data.objectCount = 1;
842 message_data.pObjects = &object;
843 submit_message(inst, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &message_data);
844
845 // Now that we should have gotten our message, destroy the messenger
846 ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger));
847
848 env->vulkan_functions.vkDestroyInstance(inst, nullptr);
849
850 // Message should be found
851 ASSERT_EQ(true, message_found);
852 }
853
CheckDeviceFunctions(FrameworkEnvironment& env, bool use_GIPA, bool enable_debug_extensions, bool hardware_supports_debug_exts)854 void CheckDeviceFunctions(FrameworkEnvironment& env, bool use_GIPA, bool enable_debug_extensions,
855 bool hardware_supports_debug_exts) {
856 InstWrapper inst(env.vulkan_functions);
857 if (enable_debug_extensions) {
858 inst.create_info.add_extension("VK_EXT_debug_utils");
859 inst.create_info.add_extension("VK_EXT_debug_report");
860 }
861 inst.create_info.setup_WSI();
862 ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
863
864 auto phys_dev = inst.GetPhysDev();
865
866 DeviceWrapper dev{inst};
867 dev.create_info.add_extension("VK_KHR_swapchain");
868 dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
869 if (enable_debug_extensions) {
870 dev.create_info.add_extension("VK_EXT_debug_marker");
871 }
872
873 if (enable_debug_extensions && !hardware_supports_debug_exts) {
874 // if the hardware doesn't support VK_EXT_debug_marker and we are trying to enable it, then we should exit since that will
875 // fail to create a device
876
877 dev.CheckCreate(phys_dev, VK_ERROR_EXTENSION_NOT_PRESENT);
878 return;
879 } else {
880 ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
881 }
882 DeviceFunctions dev_funcs{env.vulkan_functions, dev};
883
884 VkSurfaceKHR surface{};
885 ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
886
887 VkSwapchainCreateInfoKHR info{};
888 info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
889 info.surface = surface;
890
891 VkSwapchainKHR swapchain{};
892 ASSERT_EQ(VK_SUCCESS, dev_funcs.vkCreateSwapchainKHR(dev.dev, &info, nullptr, &swapchain));
893
894 auto load_function = [&inst, &dev, use_GIPA](const char* func_name) {
895 return use_GIPA ? inst.load(func_name) : dev.load(func_name);
896 };
897
898 // Debug marker
899 PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT = load_function("vkDebugMarkerSetObjectTagEXT");
900 PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT = load_function("vkDebugMarkerSetObjectNameEXT");
901 PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT = load_function("vkCmdDebugMarkerBeginEXT");
902 PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT = load_function("vkCmdDebugMarkerEndEXT");
903 PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT = load_function("vkCmdDebugMarkerInsertEXT");
904 // Debug utils
905 PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT = load_function("vkSetDebugUtilsObjectNameEXT");
906 PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT = load_function("vkSetDebugUtilsObjectTagEXT");
907 PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT = load_function("vkQueueBeginDebugUtilsLabelEXT");
908 PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT = load_function("vkQueueEndDebugUtilsLabelEXT");
909 PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT = load_function("vkQueueInsertDebugUtilsLabelEXT");
910 PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT = load_function("vkCmdBeginDebugUtilsLabelEXT");
911 PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT = load_function("vkCmdEndDebugUtilsLabelEXT");
912 PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT = load_function("vkCmdInsertDebugUtilsLabelEXT");
913
914 // Debug marker functions - should always be found when using GIPA but when using GDPA found only when the extension is enabled
915 if (use_GIPA) {
916 ASSERT_TRUE(nullptr != DebugMarkerSetObjectTagEXT);
917 ASSERT_TRUE(nullptr != DebugMarkerSetObjectNameEXT);
918 ASSERT_TRUE(nullptr != CmdDebugMarkerBeginEXT);
919 ASSERT_TRUE(nullptr != CmdDebugMarkerEndEXT);
920 ASSERT_TRUE(nullptr != CmdDebugMarkerInsertEXT);
921 } else {
922 ASSERT_EQ(enable_debug_extensions, nullptr != DebugMarkerSetObjectTagEXT);
923 ASSERT_EQ(enable_debug_extensions, nullptr != DebugMarkerSetObjectNameEXT);
924 ASSERT_EQ(enable_debug_extensions, nullptr != CmdDebugMarkerBeginEXT);
925 ASSERT_EQ(enable_debug_extensions, nullptr != CmdDebugMarkerEndEXT);
926 ASSERT_EQ(enable_debug_extensions, nullptr != CmdDebugMarkerInsertEXT);
927 }
928
929 // Debug utils functions - should only be found if the extension was enabled (because its instance level)
930 ASSERT_EQ(enable_debug_extensions, nullptr != SetDebugUtilsObjectNameEXT);
931 ASSERT_EQ(enable_debug_extensions, nullptr != SetDebugUtilsObjectTagEXT);
932 ASSERT_EQ(enable_debug_extensions, nullptr != QueueBeginDebugUtilsLabelEXT);
933 ASSERT_EQ(enable_debug_extensions, nullptr != QueueEndDebugUtilsLabelEXT);
934 ASSERT_EQ(enable_debug_extensions, nullptr != QueueInsertDebugUtilsLabelEXT);
935 ASSERT_EQ(enable_debug_extensions, nullptr != CmdBeginDebugUtilsLabelEXT);
936 ASSERT_EQ(enable_debug_extensions, nullptr != CmdEndDebugUtilsLabelEXT);
937 ASSERT_EQ(enable_debug_extensions, nullptr != CmdInsertDebugUtilsLabelEXT);
938
939 if (SetDebugUtilsObjectNameEXT) {
940 VkDebugUtilsObjectNameInfoEXT obj_name_info{};
941 obj_name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
942 obj_name_info.objectHandle = (uint64_t)swapchain;
943 obj_name_info.objectType = VK_OBJECT_TYPE_SWAPCHAIN_KHR;
944 obj_name_info.pObjectName = " Your mom!";
945 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info));
946
947 obj_name_info.objectHandle = (uint64_t)(uintptr_t)surface;
948 obj_name_info.objectType = VK_OBJECT_TYPE_SURFACE_KHR;
949 obj_name_info.pObjectName = " Your moms surface!";
950 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info));
951
952 obj_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev;
953 obj_name_info.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
954 obj_name_info.pObjectName = "Physical Device AAAAAAAAA";
955 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info));
956
957 obj_name_info.objectHandle = (uint64_t)(uintptr_t)inst.inst;
958 obj_name_info.objectType = VK_OBJECT_TYPE_INSTANCE;
959 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info));
960 }
961 if (SetDebugUtilsObjectTagEXT) {
962 VkDebugUtilsObjectTagInfoEXT utils_object_tag{};
963 utils_object_tag.objectHandle = (uint64_t)(uintptr_t)inst.inst;
964 utils_object_tag.objectType = VK_OBJECT_TYPE_INSTANCE;
965 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(dev.dev, &utils_object_tag));
966
967 utils_object_tag.objectHandle = (uint64_t)(uintptr_t)phys_dev;
968 utils_object_tag.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
969 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(dev.dev, &utils_object_tag));
970
971 utils_object_tag.objectHandle = (uint64_t)surface;
972 utils_object_tag.objectType = VK_OBJECT_TYPE_SURFACE_KHR;
973 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(dev.dev, &utils_object_tag));
974 }
975 VkDebugMarkerObjectTagInfoEXT marker_object_tag{};
976 VkDebugMarkerObjectNameInfoEXT marker_object_name{};
977 if (use_GIPA && !enable_debug_extensions) {
978 // These functions crash when the extension isn't enabled and the function was acquired with GIPA.
979 ASSERT_DEATH(DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag), "");
980 ASSERT_DEATH(DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name), "");
981 } else {
982 if (DebugMarkerSetObjectTagEXT) {
983 marker_object_tag.object = (uint64_t)(uintptr_t)swapchain;
984 marker_object_tag.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT;
985 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag));
986
987 marker_object_tag.object = (uint64_t)(uintptr_t)phys_dev;
988 marker_object_tag.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT;
989 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag));
990
991 marker_object_tag.object = (uint64_t)surface;
992 marker_object_tag.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT;
993 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag));
994
995 marker_object_tag.object = (uint64_t)(uintptr_t)inst.inst;
996 marker_object_tag.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
997 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag));
998 }
999 if (DebugMarkerSetObjectNameEXT) {
1000 marker_object_name.object = (uint64_t)(uintptr_t)swapchain;
1001 marker_object_name.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT;
1002 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name));
1003
1004 marker_object_name.object = (uint64_t)(uintptr_t)phys_dev;
1005 marker_object_name.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT;
1006 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name));
1007
1008 marker_object_name.object = (uint64_t)surface;
1009 marker_object_name.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT;
1010 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name));
1011
1012 marker_object_name.object = (uint64_t)(uintptr_t)inst.inst;
1013 marker_object_name.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
1014 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name));
1015 }
1016 }
1017 VkQueue queue{};
1018 dev.functions->vkGetDeviceQueue(dev.dev, 0, 0, &queue);
1019 VkDebugUtilsLabelEXT utils_label{};
1020 utils_label.pLabelName = "Testing testing 123";
1021 if (QueueBeginDebugUtilsLabelEXT) QueueBeginDebugUtilsLabelEXT(queue, &utils_label);
1022 if (QueueEndDebugUtilsLabelEXT) QueueEndDebugUtilsLabelEXT(queue);
1023 if (QueueInsertDebugUtilsLabelEXT) QueueInsertDebugUtilsLabelEXT(queue, &utils_label);
1024 VkCommandBuffer cmd_buf{};
1025 VkCommandPool cmd_pool;
1026 VkCommandPoolCreateInfo cmd_pool_info{};
1027 cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1028 ASSERT_EQ(VK_SUCCESS, dev_funcs.vkCreateCommandPool(dev.dev, &cmd_pool_info, nullptr, &cmd_pool));
1029 VkCommandBufferAllocateInfo cmd_buf_alloc_info{};
1030 cmd_buf_alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1031 cmd_buf_alloc_info.commandBufferCount = 1;
1032 cmd_buf_alloc_info.commandPool = cmd_pool;
1033 ASSERT_EQ(VK_SUCCESS, dev_funcs.vkAllocateCommandBuffers(dev.dev, &cmd_buf_alloc_info, &cmd_buf));
1034 if (CmdBeginDebugUtilsLabelEXT) CmdBeginDebugUtilsLabelEXT(cmd_buf, &utils_label);
1035 if (CmdEndDebugUtilsLabelEXT) CmdEndDebugUtilsLabelEXT(cmd_buf);
1036 if (CmdInsertDebugUtilsLabelEXT) CmdInsertDebugUtilsLabelEXT(cmd_buf, &utils_label);
1037
1038 dev_funcs.vkDestroySwapchainKHR(dev.dev, swapchain, nullptr);
1039 env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr);
1040 }
1041
TEST(GetProcAddr, DebugFuncsWithTerminator)1042 TEST(GetProcAddr, DebugFuncsWithTerminator) {
1043 FrameworkEnvironment env{};
1044 auto& driver =
1045 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0");
1046 driver.physical_devices.at(0).add_extensions({"VK_KHR_swapchain"});
1047 // Hardware doesn't support the debug extensions
1048
1049 // Use getDeviceProcAddr & vary enabling the debug extensions
1050 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, false));
1051 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, false));
1052
1053 // Use getInstanceProcAddr & vary enabling the debug extensions
1054 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, false));
1055 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, false));
1056
1057 // Now set the hardware to support the extensions and run the situations again
1058 driver.add_instance_extensions({"VK_EXT_debug_utils", "VK_EXT_debug_report"});
1059 driver.physical_devices.at(0).add_extensions({"VK_EXT_debug_marker"});
1060
1061 // Use getDeviceProcAddr & vary enabling the debug extensions
1062 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true));
1063 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, true));
1064
1065 // Use getInstanceProcAddr & vary enabling the debug extensions
1066 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, true));
1067 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, true));
1068 }
1069
TEST(GetProcAddr, DebugFuncsWithTrampoline)1070 TEST(GetProcAddr, DebugFuncsWithTrampoline) {
1071 FrameworkEnvironment env{};
1072 auto& driver =
1073 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0");
1074 driver.physical_devices.at(0).add_extensions({"VK_KHR_swapchain"});
1075 // Hardware doesn't support the debug extensions
1076
1077 // Use getDeviceProcAddr & vary enabling the debug extensions
1078 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, false));
1079 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, false));
1080
1081 // Use getInstanceProcAddr & vary enabling the debug extensions
1082 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, false));
1083 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, false));
1084
1085 // Now add a layer that supports the extensions and run the situations again
1086 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1087 .set_name("VK_LAYER_test_layer")
1088 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1089 .set_disable_environment("DISABLE_ME")
1090 .add_instance_extensions({{VK_EXT_DEBUG_REPORT_EXTENSION_NAME},
1091 {VK_EXT_DEBUG_UTILS_EXTENSION_NAME}})
1092 .add_device_extension({VK_EXT_DEBUG_MARKER_EXTENSION_NAME})),
1093 "test_layer.json");
1094
1095 // // Use getDeviceProcAddr & vary enabling the debug extensions
1096 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true));
1097 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, true));
1098
1099 // Use getInstanceProcAddr & vary enabling the debug extensions
1100 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, true));
1101 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, true));
1102 }
1103
TEST(GetProcAddr, DebugFuncsWithDebugExtsForceAdded)1104 TEST(GetProcAddr, DebugFuncsWithDebugExtsForceAdded) {
1105 FrameworkEnvironment env{};
1106 auto& driver =
1107 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0");
1108 driver.physical_devices.at(0).add_extensions({"VK_KHR_swapchain"});
1109 // Hardware doesn't support the debug extensions
1110
1111 // Use getDeviceProcAddr & vary enabling the debug extensions
1112 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, false));
1113 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, false));
1114
1115 // Use getInstanceProcAddr & vary enabling the debug extensions
1116 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, false));
1117 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, false));
1118
1119 // Now add a layer that supports the extensions and run the situations again
1120 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1121 .set_name("VK_LAYER_test_layer")
1122 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1123 .set_disable_environment("DISABLE_ME")),
1124 "test_layer.json");
1125 env.get_test_layer()
1126 .add_injected_instance_extensions({{VK_EXT_DEBUG_REPORT_EXTENSION_NAME}, {VK_EXT_DEBUG_UTILS_EXTENSION_NAME}})
1127 .add_injected_device_extension({VK_EXT_DEBUG_MARKER_EXTENSION_NAME});
1128
1129 // Use getDeviceProcAddr & vary enabling the debug extensions
1130 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true));
1131 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, true));
1132
1133 // Use getInstanceProcAddr & vary enabling the debug extensions
1134 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, true));
1135 ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, true));
1136 }
1137
TEST(DebugUtils, WrappingLayer)1138 TEST(DebugUtils, WrappingLayer) {
1139 FrameworkEnvironment env{};
1140 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
1141 .set_min_icd_interface_version(5)
1142 .add_physical_device(PhysicalDevice{}.add_extension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME).finish())
1143 .add_instance_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
1144
1145 const char* wrap_objects_name = "VK_LAYER_LUNARG_wrap_objects";
1146 env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1147 .set_name(wrap_objects_name)
1148 .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
1149 .set_disable_environment("DISABLE_ME")
1150 .add_instance_extension({VK_EXT_DEBUG_UTILS_EXTENSION_NAME})),
1151 "wrap_objects_layer.json");
1152
1153 InstWrapper inst{env.vulkan_functions};
1154 inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
1155 inst.create_info.add_extension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
1156 inst.create_info.add_layer(wrap_objects_name);
1157 inst.CheckCreate();
1158 DebugUtilsWrapper log{inst};
1159 CreateDebugUtilsMessenger(log);
1160
1161 auto phys_dev = inst.GetPhysDev();
1162 DeviceWrapper device{inst};
1163 device.create_info.add_extension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
1164 device.CheckCreate(phys_dev);
1165 {
1166 PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT = inst.load("vkSetDebugUtilsObjectNameEXT");
1167
1168 VkDebugUtilsObjectNameInfoEXT info = {};
1169 info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
1170 info.objectType = VK_OBJECT_TYPE_DEVICE;
1171 info.objectHandle = (uint64_t)device.dev;
1172 info.pObjectName = "Test Name";
1173 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(device, &info));
1174
1175 info.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
1176 info.objectHandle = (uint64_t)phys_dev;
1177 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(device, &info));
1178
1179 info.objectType = VK_OBJECT_TYPE_INSTANCE;
1180 info.objectHandle = (uint64_t)inst.inst;
1181 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(device, &info));
1182 }
1183 {
1184 PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT = inst.load("vkSetDebugUtilsObjectTagEXT");
1185
1186 VkDebugUtilsObjectTagInfoEXT info = {};
1187 info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT;
1188 info.objectType = VK_OBJECT_TYPE_DEVICE;
1189 info.objectHandle = (uint64_t)device.dev;
1190 info.pTag = "Test Name";
1191 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(device, &info));
1192
1193 info.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
1194 info.objectHandle = (uint64_t)phys_dev;
1195 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(device, &info));
1196
1197 info.objectType = VK_OBJECT_TYPE_INSTANCE;
1198 info.objectHandle = (uint64_t)inst.inst;
1199 ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(device, &info));
1200 }
1201 // Debug marker
1202 {
1203 PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT = inst.load("vkDebugMarkerSetObjectNameEXT");
1204
1205 VkDebugMarkerObjectNameInfoEXT info = {};
1206 info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT;
1207 info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT;
1208 info.object = (uint64_t)device.dev;
1209 info.pObjectName = "Test Name";
1210 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(device, &info));
1211
1212 info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT;
1213 info.object = (uint64_t)phys_dev;
1214 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(device, &info));
1215
1216 info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
1217 info.object = (uint64_t)inst.inst;
1218 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(device, &info));
1219 }
1220 {
1221 PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT = inst.load("vkDebugMarkerSetObjectTagEXT");
1222
1223 VkDebugMarkerObjectTagInfoEXT info = {};
1224 info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT;
1225 info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT;
1226 info.object = (uint64_t)device.dev;
1227 info.pTag = "Test Name";
1228 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(device, &info));
1229
1230 info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT;
1231 info.object = (uint64_t)phys_dev;
1232 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(device, &info));
1233
1234 info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
1235 info.object = (uint64_t)inst.inst;
1236 ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(device, &info));
1237 }
1238 }
1239