Skip to content

Commit

Permalink
layers: Add an message verbose setting
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-lunarg committed Feb 21, 2025
1 parent bf292b6 commit 352e3ef
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 67 deletions.
8 changes: 8 additions & 0 deletions layers/VkLayer_khronos_validation.json.in
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,14 @@
"type": "GROUP",
"expanded": true,
"settings": [
{
"key": "message_format_verbose",
"label": "Verbose",
"description": "Display Validation Type, Object Handles, Message ID, Spec Link",
"type": "BOOL",
"default": true,
"platforms": [ "WINDOWS", "LINUX", "MACOS", "ANDROID" ]
},
{
"key": "message_format_display_application_name",
"label": "Display Application Name",
Expand Down
88 changes: 55 additions & 33 deletions layers/error_message/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,44 +197,60 @@ bool DebugReport::DebugLogMsg(VkFlags msg_flags, const LogObjectList &objects, c
oss << "[AppName: " << message_format_settings.application_name << "] ";
}

if (msg_flags & kErrorBit) {
oss << "Validation Error: ";
} else if (msg_flags & kWarningBit) {
oss << "Validation Warning: ";
} else if (msg_flags & kPerformanceWarningBit) {
oss << "Validation Performance Warning: ";
} else if (msg_flags & kInformationBit) {
oss << "Validation Information: ";
} else if (msg_flags & kVerboseBit) {
oss << "Verbose Information: ";
// User can get this from VkDebugUtilsMessageSeverityFlagBitsEXT if desired
if (message_format_settings.verbose) {
if (msg_flags & kErrorBit) {
oss << "Validation Error: ";
} else if (msg_flags & kWarningBit) {
oss << "Validation Warning: ";
} else if (msg_flags & kPerformanceWarningBit) {
oss << "Validation Performance Warning: ";
} else if (msg_flags & kInformationBit) {
oss << "Validation Information: ";
} else if (msg_flags & kVerboseBit) {
oss << "Verbose Information: ";
}
}

if (text_vuid != nullptr) {
oss << "[ " << text_vuid << " ]";
}

if (!object_name_infos.empty()) {
oss << " Objects: ";
}
for (uint32_t i = 0; i < object_name_infos.size(); i++) {
const VkDebugUtilsObjectNameInfoEXT &src_object = object_name_infos[i];
if (0 != src_object.objectHandle) {
oss << string_VkObjectTypeHandleName(src_object.objectType) << " ";
if (!debug_stable_messages) {
oss << "0x" << std::hex << src_object.objectHandle;
// User can get these from VkDebugUtilsMessengerCallbackDataEXT::pObjects if desired
if (message_format_settings.verbose) {
if (!object_name_infos.empty()) {
oss << " Objects: ";
}
for (uint32_t i = 0; i < object_name_infos.size(); i++) {
const VkDebugUtilsObjectNameInfoEXT &src_object = object_name_infos[i];
if (0 != src_object.objectHandle) {
oss << string_VkObjectTypeHandleName(src_object.objectType) << " ";
if (!debug_stable_messages) {
oss << "0x" << std::hex << src_object.objectHandle;
}
if (src_object.pObjectName) {
oss << "[" << src_object.pObjectName << "]";
}
} else {
oss << string_VkObjectTypeHandleName(src_object.objectType) << " VK_NULL_HANDLE";
}
if (src_object.pObjectName) {
oss << "[" << src_object.pObjectName << "]";

if (i + 1 != object_name_infos.size()) {
oss << ", ";
}
} else {
oss << string_VkObjectTypeHandleName(src_object.objectType) << " VK_NULL_HANDLE";
}

if (i + 1 != object_name_infos.size()) {
oss << "; ";
}
oss << " | MessageID = 0x" << std::hex << message_id_number;
}
oss << " | MessageID = 0x" << std::hex << message_id_number << "\n" << msg;

// Add a new line to seperate everything from the start of the "real" error message
if (message_format_settings.verbose) {
oss << "\n";
} else {
oss << " ";
}

oss << msg;
std::string composite = oss.str();

const auto callback_list = &debug_callback_list;
Expand Down Expand Up @@ -627,12 +643,18 @@ bool DebugReport::LogMsg(VkFlags msg_flags, const LogObjectList &objects, const

full_message.append("The Vulkan spec states: ");
full_message.append(spec_text);
full_message.append(" (");
full_message.append(spec_url_base);
full_message.append(spec_url_section);
full_message.append("#"); // CMake hates hashes
full_message.append(vuid_text);
full_message.append(")");

// Spec link can always be found searching the VUID.
// But regardless of "verbose" setting, print the spec text as sometime it the error message in the layer is designed to
// compliment it.
if (message_format_settings.verbose) {
full_message.append(" (");
full_message.append(spec_url_base);
full_message.append(spec_url_section);
full_message.append("#"); // CMake hates hashes
full_message.append(vuid_text);
full_message.append(")");
}
}
}

Expand Down
1 change: 1 addition & 0 deletions layers/error_message/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ class TypedHandleWrapper {
struct Location;

struct MessageFormatSettings {
bool verbose = true;
bool display_application_name = false;
std::string application_name;
};
Expand Down
7 changes: 7 additions & 0 deletions layers/layer_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ const char *VK_LAYER_SYNCVAL_MESSAGE_EXTRA_PROPERTIES_PRETTY_PRINT = "syncval_me

// Message Formatting
// ---
const char *VK_LAYER_MESSAGE_FORMAT_VERBOSE = "message_format_verbose";
const char *VK_LAYER_MESSAGE_FORMAT_DISPLAY_APPLICATION_NAME = "message_format_display_application_name";
// Until post 1.3.290 SDK release, these were not possible to set via environment variables
const char *VK_LAYER_LOG_FILENAME = "log_filename";
Expand Down Expand Up @@ -629,6 +630,8 @@ static void ValidateLayerSettingsProvided(const VkLayerSettingsCreateInfoEXT *la
required_type = VK_LAYER_SETTING_TYPE_BOOL32_EXT;
} else if (strcmp(VK_LAYER_SYNCVAL_MESSAGE_EXTRA_PROPERTIES_PRETTY_PRINT, setting.pSettingName) == 0) {
required_type = VK_LAYER_SETTING_TYPE_BOOL32_EXT;
} else if (strcmp(VK_LAYER_MESSAGE_FORMAT_VERBOSE, setting.pSettingName) == 0) {
required_type = VK_LAYER_SETTING_TYPE_BOOL32_EXT;
} else if (strcmp(VK_LAYER_MESSAGE_FORMAT_DISPLAY_APPLICATION_NAME, setting.pSettingName) == 0) {
required_type = VK_LAYER_SETTING_TYPE_BOOL32_EXT;
} else if (strcmp(VK_LAYER_LOG_FILENAME, setting.pSettingName) == 0) {
Expand Down Expand Up @@ -764,6 +767,10 @@ static void ProcessDebugReportSettings(ConfigAndEnvSettings *settings_data, VkuL
}
debug_report->duplicate_message_limit = duplicate_message_limit;

if (vkuHasLayerSetting(layer_setting_set, VK_LAYER_MESSAGE_FORMAT_VERBOSE)) {
vkuGetLayerSettingValue(layer_setting_set, VK_LAYER_MESSAGE_FORMAT_VERBOSE, debug_report->message_format_settings.verbose);
}

if (vkuHasLayerSetting(layer_setting_set, VK_LAYER_MESSAGE_FORMAT_DISPLAY_APPLICATION_NAME)) {
vkuGetLayerSettingValue(layer_setting_set, VK_LAYER_MESSAGE_FORMAT_DISPLAY_APPLICATION_NAME,
debug_report->message_format_settings.display_application_name);
Expand Down
5 changes: 5 additions & 0 deletions layers/vk_layer_settings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ khronos_validation.enables =
# performance in multithreaded applications.
khronos_validation.fine_grained_locking = true

# Verbose error messages
# =====================
# Display Validation Type, Object Handles, Message ID, Spec Link
#khronos_validation.message_format_verbose = true

# Display Application Name
# =====================
# Useful when running multiple instances to know which instance the message is from
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/debug_extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,3 +584,34 @@ TEST_F(NegativeDebugExtensions, SwapchainImagesDebugMarker) {
m_errorMonitor->VerifyFound();
}
}

TEST_F(NegativeDebugExtensions, MultiObjectBindImage) {
TEST_DESCRIPTION("Make sure both VkDeviceMemory and VkImage are displayed in error message");
RETURN_IF_SKIP(Init());

// Create an image, allocate memory, free it, and then try to bind it
VkImageCreateInfo image_create_info =
vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
vkt::Image image(*m_device, image_create_info, vkt::no_mem);
VkMemoryRequirements mem_reqs = image.MemoryRequirements();

VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
// Introduce failure, do NOT set memProps to
// VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
mem_alloc.memoryTypeIndex = 1;
mem_alloc.allocationSize = mem_reqs.size;
ASSERT_TRUE(m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &mem_alloc, 0));

vkt::DeviceMemory mem1(*m_device, mem_alloc);
vkt::DeviceMemory mem2(*m_device, mem_alloc);

// Bind first memory object to Image object
vk::BindImageMemory(device(), image, mem1, 0);

// Introduce validation failure, try to bind a different memory object to
// the same image object
m_errorMonitor->SetDesiredErrorRegex("VUID-vkBindImageMemory-image-07460",
"Objects: VkDeviceMemory 0x[a-f0-9]+, VkImage 0x[a-f0-9]+, VkDeviceMemory 0x[a-f0-9]+");
vk::BindImageMemory(device(), image, mem2, 0);
m_errorMonitor->VerifyFound();
}
29 changes: 24 additions & 5 deletions tests/unit/layer_settings.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2024 The Khronos Group Inc.
* Copyright (c) 2024 Valve Corporation
* Copyright (c) 2024 LunarG, Inc.
* Copyright (c) 2024-2025 The Khronos Group Inc.
* Copyright (c) 2024-2025 Valve Corporation
* Copyright (c) 2024-2025 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -452,7 +452,7 @@ TEST_F(NegativeLayerSettings, WrongSettingType) {
VkLayerSettingsCreateInfoEXT create_info = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1, &setting};
Monitor().ExpectSuccess(kErrorBit | kWarningBit);
Monitor().SetDesiredWarning(
" The setting enable_message_limit in VkLayerSettingsCreateInfoEXT was set to type VK_LAYER_SETTING_TYPE_UINT32_EXT but "
"The setting enable_message_limit in VkLayerSettingsCreateInfoEXT was set to type VK_LAYER_SETTING_TYPE_UINT32_EXT but "
"requires type VK_LAYER_SETTING_TYPE_BOOL32_EXT and the value may be parsed incorrectly.");
RETURN_IF_SKIP(InitFramework(&create_info));
RETURN_IF_SKIP(InitState());
Expand All @@ -466,7 +466,7 @@ TEST_F(NegativeLayerSettings, WrongSettingType2) {
VkLayerSettingsCreateInfoEXT create_info = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1, &setting};
Monitor().ExpectSuccess(kErrorBit | kWarningBit);
Monitor().SetDesiredWarning(
" The setting thread_safety in VkLayerSettingsCreateInfoEXT was set to type VK_LAYER_SETTING_TYPE_UINT32_EXT but requires "
"The setting thread_safety in VkLayerSettingsCreateInfoEXT was set to type VK_LAYER_SETTING_TYPE_UINT32_EXT but requires "
"type VK_LAYER_SETTING_TYPE_BOOL32_EXT and the value may be parsed incorrectly.");
RETURN_IF_SKIP(InitFramework(&create_info));
RETURN_IF_SKIP(InitState());
Expand All @@ -487,4 +487,23 @@ TEST_F(NegativeLayerSettings, DuplicateSettings) {
RETURN_IF_SKIP(InitFramework(&create_info));
RETURN_IF_SKIP(InitState());
Monitor().VerifyFound();
}

TEST_F(NegativeLayerSettings, MessageFormatVerbose) {
VkBool32 disable = VK_FALSE;
const VkLayerSettingEXT setting[] = {
{OBJECT_LAYER_NAME, "message_format_verbose", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &disable}};
VkLayerSettingsCreateInfoEXT layer_setting_create_info = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1,
setting};
RETURN_IF_SKIP(InitFramework(&layer_setting_create_info));
RETURN_IF_SKIP(InitState());

VkBufferCreateInfo info = vku::InitStructHelper();
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
info.size = 0;
m_errorMonitor->SetDesiredError(
"[ VUID-VkBufferCreateInfo-size-00912 ] vkCreateBuffer(): pCreateInfo->size is zero.\nThe Vulkan spec states: size must be "
"greater than 0");
vkt::Buffer buffer(*m_device, info, vkt::no_mem);
m_errorMonitor->VerifyFound();
}
36 changes: 7 additions & 29 deletions tests/unit/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,54 +522,32 @@ TEST_F(NegativeMemory, MemoryMapRangePlacedDisabled) {
}
#endif

TEST_F(NegativeMemory, RebindMemoryMultiObjectDebugUtils) {
VkResult err;
bool pass;

m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-07460");

TEST_F(NegativeMemory, RebindMemoryMultiObject) {
RETURN_IF_SKIP(Init());

// Create an image, allocate memory, free it, and then try to bind it
VkMemoryRequirements mem_reqs;

const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
const int32_t tex_width = 32;
const int32_t tex_height = 32;
VkImageCreateInfo image_create_info =
vkt::Image::ImageCreateInfo2D(tex_width, tex_height, 1, 1, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT);
vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
vkt::Image image(*m_device, image_create_info, vkt::no_mem);
VkMemoryRequirements mem_reqs = image.MemoryRequirements();

VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
mem_alloc.allocationSize = 0;
mem_alloc.memoryTypeIndex = 0;

// Introduce failure, do NOT set memProps to
// VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
mem_alloc.memoryTypeIndex = 1;

vk::GetImageMemoryRequirements(device(), image, &mem_reqs);

mem_alloc.allocationSize = mem_reqs.size;
pass = m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &mem_alloc, 0);
ASSERT_TRUE(pass);
ASSERT_TRUE(m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &mem_alloc, 0));

// allocate 2 memory objects
vkt::DeviceMemory mem1(*m_device, mem_alloc);
vkt::DeviceMemory mem2(*m_device, mem_alloc);

// Bind first memory object to Image object
err = vk::BindImageMemory(device(), image, mem1, 0);
ASSERT_EQ(VK_SUCCESS, err);
vk::BindImageMemory(device(), image, mem1, 0);

// Introduce validation failure, try to bind a different memory object to
// the same image object
err = vk::BindImageMemory(device(), image, mem2, 0);
m_errorMonitor->VerifyFound();

// This particular VU should output three objects in its error message. Verify this works correctly.
m_errorMonitor->SetDesiredError("VK_OBJECT_TYPE_IMAGE");
err = vk::BindImageMemory(device(), image, mem2, 0);
m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-07460");
vk::BindImageMemory(device(), image, mem2, 0);
m_errorMonitor->VerifyFound();
}

Expand Down

0 comments on commit 352e3ef

Please sign in to comment.