I was trying out C++20 ranges while working on my Vulkan project, I decided I wanted to try to check if a layer was available before the client added it in my builder object.
I set up my layer properties vector like so:
//...
vkEnumerateInstanceLayerProperties(&amount_of_layers, nullptr);
std::vector<VkLayerProperties> layer_properties(amount_of_layers);
vkEnumerateInstanceLayerProperties(&amount_of_layers, layer_properties.data());
//...
If I print them out like so, it works just fine:
for(auto& current_properties : layer_properties)
std::cout << current_properties.layerName << "\n";
The problem comes when I tried to use ranges to filter them, this is not the original filter I tried to apply, but this has similar problems:
auto available_layers = layer_properties | std::views::filter(
[&](auto current_layer_properties) {
return std::string{current_layer_properties.layerName}.size() % 2 == 0;
}
);
I just need a count at this point, not to iterate so I just store it in available_layers
.
However if I try to print out current_layer_properties.layerName
I get the first few layer names, and then what looks like a bunch of data that is from the data segment of the Vulkan library binaries, it looks like JSON.
VK_LAYER_MESA_device_select
VK_LAYER_INTEL_nullhw
VK_LAYER_MESA_overlay
VK_LAYER_LUNARG_monitor
VK_LAYER_KHRONOS_synchronization2
VK_LAYER_LUNARG_api_dump
E_CREATE_NEW",
"label": "Log File Overwrite",
"description": "Specifies that log file initialization should overwrite an existing file when true, or append to an existing file when false.",
"type": "BOOL",
"default": true
}
]
}
]
}
]
}
//...
Same happens if I try to apply std::views::transform
and turn layer_properties
into a container/view of std::string
the same thing happens.
Sometimes depending on my filter (I use a find to find a string in it, then omit the element if its not found) it goes on forever.
Am I doing something wrong with ranges? Or does this have something to do with Vulkan?
Does it have something to do with some sort of side effect these LunarG .gfxr
/gfxrecon_capture
log files I am seeing(the erroneous output looks related, but could be totally random)?
UPDATE[ 0 ]:
Someone in the comments requested I show how I print things, it has changed as I have debugged, but I will put it here (it also crashes without printing)
In the lambda for std::filter
and/or std::transform
I have put variations of the following:
std::cout << current_layer_properties.layerName << "\n";
std::cout << current_layer_properties << "\n"; //When I apply std::transform and turn it into a std::string or std::string_view
log<LogType::Debug>(std::cout, current_layer_properties);
Here is my log
function
template<typename LogParameterType>
void log(
LogParameterType& log,
const std::string_view message,
const std::source_location location =
std::source_location::current()
)
{
if constexpr(DebugParameterConstant == true
&& LogParameterConstant == LogType::Debug)
return;
log << to_string(LogParameterConstant) << "::"
<< location.file_name() << "("
<< location.line() << ":"
<< location.column() << ")::"
<< location.function_name() << ": "
<< message << "\n";
}
My debug layer is not working but here is the function it is suppose to run:
//If anyone can think of a better way to do this please let me know :)
void vulkan_log(
VkDebugUtilsMessageSeverityFlagBitsEXT vulkan_log_type,
VkDebugUtilsMessageTypeFlagsEXT message_type,
const VkDebugUtilsMessengerCallbackDataEXT* callback_data
)
{
LogType log_type = LogType::Unkown;
std::string message_type_string = to_string(message_type);
switch(vulkan_log_type)
{
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
{
std::cerr << message_type_string;
log<LogType::Diagnostic>(std::cerr, callback_data->pMessage);
break;
}
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
{
std::cerr << message_type_string;
log<LogType::Error>(std::cerr, callback_data->pMessage);
break;
}
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
{
std::cerr << message_type_string;
log<LogType::Warning>(std::cerr, callback_data->pMessage);
break;
}
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
{
std::cout << message_type_string;
log<LogType::Note>(std::cout, callback_data->pMessage);
break;
}
default:
break;
}
}
Thanks!
- TFB