Remove format feature flag handling from SwapchainBuilder and more code comments

- format feature flags should not be used, as set_image_usage_flags is a better alternative
- split format search in two phases (desired / best)
- explain usage of is_unextended_present_mode for basic validation
This commit is contained in:
Odilon Vatonne 2022-10-12 20:56:16 +02:00 committed by Charles Giessen
parent 73295fed0b
commit d90ca8755f
2 changed files with 20 additions and 34 deletions

View File

@ -1585,7 +1585,8 @@ enum class SurfaceSupportError {
surface_handle_null, surface_handle_null,
failed_get_surface_capabilities, failed_get_surface_capabilities,
failed_enumerate_surface_formats, failed_enumerate_surface_formats,
failed_enumerate_present_modes failed_enumerate_present_modes,
no_suitable_desired_format
}; };
struct SurfaceSupportErrorCategory : std::error_category { struct SurfaceSupportErrorCategory : std::error_category {
@ -1596,7 +1597,7 @@ struct SurfaceSupportErrorCategory : std::error_category {
CASE_TO_STRING(SurfaceSupportError, failed_get_surface_capabilities) CASE_TO_STRING(SurfaceSupportError, failed_get_surface_capabilities)
CASE_TO_STRING(SurfaceSupportError, failed_enumerate_surface_formats) CASE_TO_STRING(SurfaceSupportError, failed_enumerate_surface_formats)
CASE_TO_STRING(SurfaceSupportError, failed_enumerate_present_modes) CASE_TO_STRING(SurfaceSupportError, failed_enumerate_present_modes)
CASE_TO_STRING(SurfaceSupportError, no_suitable_format) CASE_TO_STRING(SurfaceSupportError, no_suitable_desired_format)
default: default:
return ""; return "";
} }
@ -1632,22 +1633,29 @@ Result<SurfaceSupportDetails> query_surface_support_details(VkPhysicalDevice phy
return SurfaceSupportDetails{ capabilities, formats, present_modes }; return SurfaceSupportDetails{ capabilities, formats, present_modes };
} }
VkSurfaceFormatKHR find_surface_format(VkPhysicalDevice phys_device, Result<VkSurfaceFormatKHR> find_desired_surface_format(VkPhysicalDevice phys_device,
std::vector<VkSurfaceFormatKHR> const& available_formats, std::vector<VkSurfaceFormatKHR> const& available_formats,
std::vector<VkSurfaceFormatKHR> const& desired_formats, std::vector<VkSurfaceFormatKHR> const& desired_formats) {
VkFormatFeatureFlags feature_flags) {
for (auto const& desired_format : desired_formats) { for (auto const& desired_format : desired_formats) {
for (auto const& available_format : available_formats) { for (auto const& available_format : available_formats) {
// finds the first format that is desired and available // finds the first format that is desired and available
if (desired_format.format == available_format.format && desired_format.colorSpace == available_format.colorSpace) { if (desired_format.format == available_format.format && desired_format.colorSpace == available_format.colorSpace) {
VkFormatProperties properties; return desired_format;
detail::vulkan_functions().fp_vkGetPhysicalDeviceFormatProperties(phys_device, desired_format.format, &properties);
if ((properties.optimalTilingFeatures & feature_flags) == feature_flags) return desired_format;
} }
} }
} }
// use the first available one if any desired formats aren't found // if no desired format is available, we report that no format is suitable to the user request
return { make_error_code(SurfaceSupportError::no_suitable_desired_format) };
}
VkSurfaceFormatKHR find_best_surface_format(VkPhysicalDevice phys_device,
std::vector<VkSurfaceFormatKHR> const& available_formats,
std::vector<VkSurfaceFormatKHR> const& desired_formats) {
auto surface_format_ret = detail::find_desired_surface_format(phys_device, available_formats, desired_formats);
if (surface_format_ret.has_value()) return surface_format_ret.value();
// use the first available format as a fallback if any desired formats aren't found
return available_formats[0]; return available_formats[0];
} }
@ -1772,7 +1780,7 @@ Result<Swapchain> SwapchainBuilder::build() const {
} }
VkSurfaceFormatKHR surface_format = VkSurfaceFormatKHR surface_format =
detail::find_surface_format(info.physical_device, surface_support.formats, desired_formats, info.format_feature_flags); detail::find_best_surface_format(info.physical_device, surface_support.formats, desired_formats);
VkExtent2D extent = detail::find_extent(surface_support.capabilities, info.desired_width, info.desired_height); VkExtent2D extent = detail::find_extent(surface_support.capabilities, info.desired_width, info.desired_height);
@ -1786,6 +1794,7 @@ Result<Swapchain> SwapchainBuilder::build() const {
VkPresentModeKHR present_mode = detail::find_present_mode(surface_support.present_modes, desired_present_modes); VkPresentModeKHR present_mode = detail::find_present_mode(surface_support.present_modes, desired_present_modes);
// VkSurfaceCapabilitiesKHR::supportedUsageFlags is only only valid for some present modes. For shared present modes, we should also check VkSharedPresentSurfaceCapabilitiesKHR::sharedPresentSupportedUsageFlags.
if (detail::is_unextended_present_mode(present_mode) && if (detail::is_unextended_present_mode(present_mode) &&
(info.image_usage_flags & surface_support.capabilities.supportedUsageFlags) != info.image_usage_flags) { (info.image_usage_flags & surface_support.capabilities.supportedUsageFlags) != info.image_usage_flags) {
return Error{ SwapchainError::required_usage_not_supported }; return Error{ SwapchainError::required_usage_not_supported };
@ -1977,18 +1986,6 @@ SwapchainBuilder& SwapchainBuilder::use_default_image_usage_flags() {
info.image_usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; info.image_usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
return *this; return *this;
} }
SwapchainBuilder& SwapchainBuilder::set_format_feature_flags(VkFormatFeatureFlags feature_flags) {
info.format_feature_flags = feature_flags;
return *this;
}
SwapchainBuilder& SwapchainBuilder::add_format_feature_flags(VkFormatFeatureFlags feature_flags) {
info.format_feature_flags = info.format_feature_flags | feature_flags;
return *this;
}
SwapchainBuilder& SwapchainBuilder::use_default_format_feature_flags() {
info.format_feature_flags = 0;
return *this;
}
SwapchainBuilder& SwapchainBuilder::set_image_array_layer_count(uint32_t array_layer_count) { SwapchainBuilder& SwapchainBuilder::set_image_array_layer_count(uint32_t array_layer_count) {
info.array_layer_count = array_layer_count; info.array_layer_count = array_layer_count;
return *this; return *this;

View File

@ -842,7 +842,7 @@ class SwapchainBuilder {
SwapchainBuilder& use_default_present_mode_selection(); SwapchainBuilder& use_default_present_mode_selection();
// Set the bitmask of the image usage for acquired swapchain images. // Set the bitmask of the image usage for acquired swapchain images.
// If the surface capabilities cannot allow it, building the swapchain will result in the `SwapchainError::required_usage_or_features_not_supported` error. // If the surface capabilities cannot allow it, building the swapchain will result in the `SwapchainError::required_usage_not_supported` error.
SwapchainBuilder& set_image_usage_flags(VkImageUsageFlags usage_flags); SwapchainBuilder& set_image_usage_flags(VkImageUsageFlags usage_flags);
// Add a image usage to the bitmask for acquired swapchain images. // Add a image usage to the bitmask for acquired swapchain images.
SwapchainBuilder& add_image_usage_flags(VkImageUsageFlags usage_flags); SwapchainBuilder& add_image_usage_flags(VkImageUsageFlags usage_flags);
@ -850,16 +850,6 @@ class SwapchainBuilder {
// are provided. The default is VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT // are provided. The default is VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
SwapchainBuilder& use_default_image_usage_flags(); SwapchainBuilder& use_default_image_usage_flags();
// Set the bitmask of the format feature flag for acquired swapchain images.
// Use this functionnality only if you require formats to support a set of feature flags
// that are not already implied by set_image_usage_flags
SwapchainBuilder& set_format_feature_flags(VkFormatFeatureFlags feature_flags);
// Add a format feature to the bitmask for acquired swapchain images.
SwapchainBuilder& add_format_feature_flags(VkFormatFeatureFlags feature_flags);
// Use the default format feature bitmask values. This is the default if no format features
// are provided. The default is 0
SwapchainBuilder& use_default_format_feature_flags();
// Set the number of views in for multiview/stereo surface // Set the number of views in for multiview/stereo surface
SwapchainBuilder& set_image_array_layer_count(uint32_t array_layer_count); SwapchainBuilder& set_image_array_layer_count(uint32_t array_layer_count);
@ -926,7 +916,6 @@ class SwapchainBuilder {
uint32_t min_image_count = 0; uint32_t min_image_count = 0;
uint32_t required_min_image_count = 0; uint32_t required_min_image_count = 0;
VkImageUsageFlags image_usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; VkImageUsageFlags image_usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
VkFormatFeatureFlags format_feature_flags = 0;
uint32_t graphics_queue_index = 0; uint32_t graphics_queue_index = 0;
uint32_t present_queue_index = 0; uint32_t present_queue_index = 0;
VkSurfaceTransformFlagBitsKHR pre_transform = static_cast<VkSurfaceTransformFlagBitsKHR>(0); VkSurfaceTransformFlagBitsKHR pre_transform = static_cast<VkSurfaceTransformFlagBitsKHR>(0);