renderer_vulkan: Update validation layer name and test before enabling

Update validation layer string to VK_LAYER_KHRONOS_validation.

While we are at it, properly check for available validation layers
before enabling them.
master
ReinUsesLisp 2020-06-22 04:10:45 +07:00
parent 14a1181a97
commit 2f09c7ddd3
3 changed files with 43 additions and 5 deletions

@ -155,11 +155,31 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc
} }
} }
static constexpr std::array layers_data{"VK_LAYER_LUNARG_standard_validation"}; std::vector<const char*> layers;
vk::Span<const char*> layers = layers_data; layers.reserve(1);
if (!enable_layers) { if (enable_layers) {
layers = {}; layers.push_back("VK_LAYER_KHRONOS_validation");
} }
const std::optional layer_properties = vk::EnumerateInstanceLayerProperties(dld);
if (!layer_properties) {
LOG_ERROR(Render_Vulkan, "Failed to query layer properties, disabling layers");
layers.clear();
}
for (auto layer_it = layers.begin(); layer_it != layers.end();) {
const char* const layer = *layer_it;
const auto it = std::find_if(
layer_properties->begin(), layer_properties->end(),
[layer](const VkLayerProperties& prop) { return !std::strcmp(layer, prop.layerName); });
if (it == layer_properties->end()) {
LOG_ERROR(Render_Vulkan, "Layer {} not available, removing it", layer);
layer_it = layers.erase(layer_it);
} else {
++layer_it;
}
}
vk::Instance instance = vk::Instance::Create(layers, extensions, dld); vk::Instance instance = vk::Instance::Create(layers, extensions, dld);
if (!instance) { if (!instance) {
LOG_ERROR(Render_Vulkan, "Failed to create Vulkan instance"); LOG_ERROR(Render_Vulkan, "Failed to create Vulkan instance");

@ -153,7 +153,8 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
bool Load(InstanceDispatch& dld) noexcept { bool Load(InstanceDispatch& dld) noexcept {
#define X(name) Proc(dld.name, dld, #name) #define X(name) Proc(dld.name, dld, #name)
return X(vkCreateInstance) && X(vkEnumerateInstanceExtensionProperties); return X(vkCreateInstance) && X(vkEnumerateInstanceExtensionProperties) &&
X(vkEnumerateInstanceLayerProperties);
#undef X #undef X
} }
@ -770,4 +771,17 @@ std::optional<std::vector<VkExtensionProperties>> EnumerateInstanceExtensionProp
return properties; return properties;
} }
std::optional<std::vector<VkLayerProperties>> EnumerateInstanceLayerProperties(
const InstanceDispatch& dld) {
u32 num;
if (dld.vkEnumerateInstanceLayerProperties(&num, nullptr) != VK_SUCCESS) {
return std::nullopt;
}
std::vector<VkLayerProperties> properties(num);
if (dld.vkEnumerateInstanceLayerProperties(&num, properties.data()) != VK_SUCCESS) {
return std::nullopt;
}
return properties;
}
} // namespace Vulkan::vk } // namespace Vulkan::vk

@ -141,6 +141,7 @@ struct InstanceDispatch {
PFN_vkCreateInstance vkCreateInstance; PFN_vkCreateInstance vkCreateInstance;
PFN_vkDestroyInstance vkDestroyInstance; PFN_vkDestroyInstance vkDestroyInstance;
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT; PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
PFN_vkCreateDevice vkCreateDevice; PFN_vkCreateDevice vkCreateDevice;
@ -996,4 +997,7 @@ private:
std::optional<std::vector<VkExtensionProperties>> EnumerateInstanceExtensionProperties( std::optional<std::vector<VkExtensionProperties>> EnumerateInstanceExtensionProperties(
const InstanceDispatch& dld); const InstanceDispatch& dld);
std::optional<std::vector<VkLayerProperties>> EnumerateInstanceLayerProperties(
const InstanceDispatch& dld);
} // namespace Vulkan::vk } // namespace Vulkan::vk