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
37VkBool32 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
41class DebugReportTest : public ::testing::Test {
42   public:
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:
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
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
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
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
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.
124VkBool32 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
133class CreateDestroyInstanceReport : public DebugReportTest {};
134class SeparateReport : public DebugReportTest {};
135class ManualReport : public DebugReportTest {};
136
137// Test creating and destroying instance looking for errors, but none should occur.
138TEST_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
152TEST_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.
168TEST_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.
186TEST_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.
205TEST_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.
229TEST_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.
254TEST_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.
278TEST_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.
305TEST_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.
332TEST_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
364VkBool32 VKAPI_CALL test_DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
365                                            VkDebugUtilsMessageTypeFlagsEXT message_types,
366                                            const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data);
367
368class DebugUtilTest : public ::testing::Test {
369   public:
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:
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
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
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
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
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
465VkBool32 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
473class CreateDestroyInstanceMessenger : public DebugUtilTest {};
474class SeparateMessenger : public DebugUtilTest {};
475class ManualMessage : public DebugUtilTest {};
476
477// Test creating and destroying instance looking for errors, but none should occur.
478TEST_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
495TEST_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
513TEST_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.
533TEST_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.
554TEST_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.
584TEST_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.
611TEST_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.
639TEST_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.
670TEST_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.
702TEST_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.
733TEST_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.
775TEST_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.
815TEST_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
854void 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
1042TEST(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
1070TEST(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
1104TEST(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
1138TEST(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