Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shader_debugprintf: support new VVL-DEBUG-PRINTF message and fix VVL version check for API selection #1187

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
6 changes: 4 additions & 2 deletions framework/core/hpp_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,10 @@ HPPInstance::HPPInstance(const std::string &applicati

vk::LayerSettingsCreateInfoEXT layerSettingsCreateInfo;

// If layer settings extension enabled by sample, then activate layer settings during instance creation
if (std::find(enabled_extensions.begin(), enabled_extensions.end(), VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) != enabled_extensions.end())
// If layer settings extension available, then activate the sample's layer settings during instance creation
if (std::any_of(available_instance_extensions.begin(),
available_instance_extensions.end(),
[](VkExtensionProperties const &extension) { return strcmp(extension.extensionName, VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) == 0; }))
{
layerSettingsCreateInfo.settingCount = static_cast<uint32_t>(required_layer_settings.size());
layerSettingsCreateInfo.pSettings = required_layer_settings.data();
Expand Down
6 changes: 4 additions & 2 deletions framework/core/instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,10 @@ Instance::Instance(const std::string &application_nam

VkLayerSettingsCreateInfoEXT layerSettingsCreateInfo{VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT};

// If layer settings extension enabled by sample, then activate layer settings during instance creation
if (std::find(enabled_extensions.begin(), enabled_extensions.end(), VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) != enabled_extensions.end())
// If layer settings extension available, then activate the sample's layer settings during instance creation
if (std::any_of(available_instance_extensions.begin(),
available_instance_extensions.end(),
[](VkExtensionProperties const &extension) { return strcmp(extension.extensionName, VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) == 0; }))
{
layerSettingsCreateInfo.settingCount = static_cast<uint32_t>(required_layer_settings.size());
layerSettingsCreateInfo.pSettings = required_layer_settings.data();
Expand Down
67 changes: 40 additions & 27 deletions samples/extensions/shader_debugprintf/shader_debugprintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ VKAPI_ATTR VkBool32 VKAPI_CALL ShaderDebugPrintf::debug_utils_message_callback(
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
void *pUserData)
{
// Look for Validation Layer message id names: WARNING-DEBUG-PRINTF or UNASSIGNED-DEBUG-PRINTF (have observed UNASSIGNED with older Vulkan SDKs)
if (strcmp(pCallbackData->pMessageIdName, "WARNING-DEBUG-PRINTF") == 0 || strcmp(pCallbackData->pMessageIdName, "UNASSIGNED-DEBUG-PRINTF") == 0)
// Look for Validation Layer message id names: VVL-DEBUG-PRINTF or WARNING-DEBUG-PRINTF or UNASSIGNED-DEBUG-PRINTF (have observed WARNING and UNASSIGNED with older Vulkan SDKs)
if (strcmp(pCallbackData->pMessageIdName, "VVL-DEBUG-PRINTF") == 0 || strcmp(pCallbackData->pMessageIdName, "WARNING-DEBUG-PRINTF") == 0 || strcmp(pCallbackData->pMessageIdName, "UNASSIGNED-DEBUG-PRINTF") == 0)
{
// Validation messages are a bit verbose, but we only want the text from the shader, so we cut off everything before the first word from the shader message
// See scene.vert: debugPrintfEXT("Position = %v4f", outPos);
Expand All @@ -44,21 +44,6 @@ ShaderDebugPrintf::ShaderDebugPrintf()
title = "Shader debugprintf";

add_device_extension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME);

// If layer settings available, use it to configure validation layer for debugPrintfEXT
add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true);

VkLayerSettingEXT layerSetting;
layerSetting.pLayerName = "VK_LAYER_KHRONOS_validation";
layerSetting.pSettingName = "enables";
layerSetting.type = VK_LAYER_SETTING_TYPE_STRING_EXT;
layerSetting.valueCount = 1;

// Make this static so layer setting reference remains valid after leaving constructor scope
static const char *layerEnables = "VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT";
layerSetting.pValues = &layerEnables;

add_layer_setting(layerSetting);
}

ShaderDebugPrintf::~ShaderDebugPrintf()
Expand Down Expand Up @@ -433,32 +418,57 @@ const std::vector<const char *> ShaderDebugPrintf::get_validation_layers()
// This sample overrides the instance creation part of the framework to chain in additional structures
std::unique_ptr<vkb::Instance> ShaderDebugPrintf::create_instance(bool headless)
{
uint32_t instanceApiVersion;
VK_CHECK(vkEnumerateInstanceVersion(&instanceApiVersion));
// Enumerate all instance layer properties so we can find and use the validation layer (VVL) version in subsequent steps
// The VVL version is needed to work around validation layer performance issues when running with Vulkan SDKs <= 1.3.290
uint32_t layer_property_count;
SRSaunders marked this conversation as resolved.
Show resolved Hide resolved
VK_CHECK(vkEnumerateInstanceLayerProperties(&layer_property_count, nullptr));
std::vector<VkLayerProperties> layer_properties(layer_property_count);
VK_CHECK(vkEnumerateInstanceLayerProperties(&layer_property_count, layer_properties.data()));

const auto vvl_properties = std::find_if(layer_properties.begin(),
layer_properties.end(),
[](VkLayerProperties const &properties) { return strcmp(properties.layerName, "VK_LAYER_KHRONOS_validation") == 0; });

// debugPrintfEXT layer feature requires Vulkan API 1.1, but override with API 1.2 for Vulkan SDKs <= 1.3.290 to work around VVL performance defect
// See VVL issue https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7562 for defect and fix information (fix available in SDK 1.3.296)
auto debugprintf_api_version = VK_API_VERSION_1_1;
if (vvl_properties != layer_properties.end() && vvl_properties->specVersion <= VK_MAKE_API_VERSION(0, 1, 3, 290))
{
debugprintf_api_version = VK_API_VERSION_1_2;
}

uint32_t instance_extension_count;
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, nullptr));
std::vector<VkExtensionProperties> available_instance_extensions(instance_extension_count);
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, available_instance_extensions.data()));

// When VK_EXT_layer_settings is available at runtime, the debugPrintfEXT layer feature is enabled using the standard framework
// For backwards compatibility with SDKs < 1.3.272 without VK_EXT_layer_settings, the remainder of this custom override is required
// For this case set Vulkan API version and return via base class, otherwise the remainder of this custom override is required
if (std::any_of(available_instance_extensions.begin(),
available_instance_extensions.end(),
[](VkExtensionProperties const &extension) { return strcmp(extension.extensionName, VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) == 0; }))
{
// debugPrintfEXT layer feature requires Vulkan API 1.1, but use API 1.2 until VVL performance fix is available in SDKs > 1.3.290
// See VVL issue https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7562 for defect and fix information
set_api_version(instanceApiVersion <= VK_MAKE_API_VERSION(0, 1, 3, 290) ? VK_API_VERSION_1_2 : VK_API_VERSION_1_1);
set_api_version(debugprintf_api_version);

// Run standard create_instance() from framework (with set_api_version and layer settings support) and return
// Since layer settings extension is available, use it to configure validation layer for debugPrintfEXT
VkLayerSettingEXT layerSetting;
layerSetting.pLayerName = "VK_LAYER_KHRONOS_validation";
layerSetting.pSettingName = "enables";
layerSetting.type = VK_LAYER_SETTING_TYPE_STRING_EXT;
layerSetting.valueCount = 1;

// Make this static so layer setting reference remains valid after leaving constructor scope
static const char *layerEnables = "VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT";
layerSetting.pValues = &layerEnables;

add_layer_setting(layerSetting);

// Run standard create_instance() from framework with set_api_version() and add_layer_setting() support
return VulkanSample::create_instance(headless);
}

// Run remainder of this custom create_instance() (without layer settings support) and return
std::vector<const char *> enabled_extensions;
enabled_extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);

for (const char *extension_name : window->get_required_surface_extensions())
{
enabled_extensions.push_back(extension_name);
Expand All @@ -480,7 +490,10 @@ std::unique_ptr<vkb::Instance> ShaderDebugPrintf::create_instance(bool headless)
VkApplicationInfo app_info{VK_STRUCTURE_TYPE_APPLICATION_INFO};
app_info.pApplicationName = "Shader debugprintf";
app_info.pEngineName = "Vulkan Samples";
app_info.apiVersion = instanceApiVersion <= VK_MAKE_API_VERSION(0, 1, 3, 290) ? VK_API_VERSION_1_2 : VK_API_VERSION_1_1;
app_info.apiVersion = debugprintf_api_version;

// Legacy extension for configuring validation layer features using VkValidationFeaturesEXT
enabled_extensions.push_back(VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME);

// Shader printf is a feature of the validation layers that needs to be enabled
std::vector<VkValidationFeatureEnableEXT> validation_feature_enables = {VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT};
Expand Down
Loading