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