mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-10 02:41:47 +00:00
Check image usage in SwapchainBuilder and stricter format feature verifications
This commit is contained in:
parent
300b2abb49
commit
b9a98c61b3
@ -442,6 +442,8 @@ const char* to_string(SwapchainError err) {
|
|||||||
CASE_TO_STRING(SwapchainError, failed_create_swapchain)
|
CASE_TO_STRING(SwapchainError, failed_create_swapchain)
|
||||||
CASE_TO_STRING(SwapchainError, failed_get_swapchain_images)
|
CASE_TO_STRING(SwapchainError, failed_get_swapchain_images)
|
||||||
CASE_TO_STRING(SwapchainError, failed_create_swapchain_image_views)
|
CASE_TO_STRING(SwapchainError, failed_create_swapchain_image_views)
|
||||||
|
CASE_TO_STRING(SwapchainError, required_min_image_count_too_low)
|
||||||
|
CASE_TO_STRING(SwapchainError, required_usage_or_features_not_supported)
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -1583,21 +1585,19 @@ 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_format
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SurfaceSupportErrorCategory : std::error_category {
|
struct SurfaceSupportErrorCategory : std::error_category {
|
||||||
const char* name() const noexcept override { return "vbk_surface_support"; }
|
const char* name() const noexcept override { return "vbk_surface_support"; }
|
||||||
std::string message(int err) const override {
|
std::string message(int err) const override {
|
||||||
switch (static_cast<SurfaceSupportError>(err)) {
|
switch (static_cast<SurfaceSupportError>(err)) {
|
||||||
case SurfaceSupportError::surface_handle_null:
|
CASE_TO_STRING(SurfaceSupportError, surface_handle_null)
|
||||||
return "surface_handle_null";
|
CASE_TO_STRING(SurfaceSupportError, failed_get_surface_capabilities)
|
||||||
case SurfaceSupportError::failed_get_surface_capabilities:
|
CASE_TO_STRING(SurfaceSupportError, failed_enumerate_surface_formats)
|
||||||
return "failed_get_surface_capabilities";
|
CASE_TO_STRING(SurfaceSupportError, failed_enumerate_present_modes)
|
||||||
case SurfaceSupportError::failed_enumerate_surface_formats:
|
CASE_TO_STRING(SurfaceSupportError, no_suitable_format)
|
||||||
return "failed_enumerate_surface_formats";
|
|
||||||
case SurfaceSupportError::failed_enumerate_present_modes:
|
|
||||||
return "failed_enumerate_present_modes";
|
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -1633,7 +1633,7 @@ 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_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) {
|
VkFormatFeatureFlags feature_flags) {
|
||||||
@ -1648,8 +1648,8 @@ VkSurfaceFormatKHR find_surface_format(VkPhysicalDevice phys_device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// use the first available one if any desired formats aren't found
|
// If no format supports the provided feature, we report that no format is suitable to the user request
|
||||||
return available_formats[0];
|
return { make_error_code(SurfaceSupportError::no_suitable_format) };
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPresentModeKHR find_present_mode(std::vector<VkPresentModeKHR> const& available_resent_modes,
|
VkPresentModeKHR find_present_mode(std::vector<VkPresentModeKHR> const& available_resent_modes,
|
||||||
@ -1664,6 +1664,11 @@ VkPresentModeKHR find_present_mode(std::vector<VkPresentModeKHR> const& availabl
|
|||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_unextended_present_mode(VkPresentModeKHR present_mode) {
|
||||||
|
return (present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) || (present_mode == VK_PRESENT_MODE_MAILBOX_KHR) ||
|
||||||
|
(present_mode == VK_PRESENT_MODE_FIFO_KHR) || (present_mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T> T minimum(T a, T b) { return a < b ? a : b; }
|
template <typename T> T minimum(T a, T b) { return a < b ? a : b; }
|
||||||
template <typename T> T maximum(T a, T b) { return a > b ? a : b; }
|
template <typename T> T maximum(T a, T b) { return a > b ? a : b; }
|
||||||
|
|
||||||
@ -1767,8 +1772,10 @@ Result<Swapchain> SwapchainBuilder::build() const {
|
|||||||
image_count = surface_support.capabilities.maxImageCount;
|
image_count = surface_support.capabilities.maxImageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceFormatKHR surface_format =
|
auto surface_format_ret =
|
||||||
detail::find_surface_format(info.physical_device, surface_support.formats, desired_formats, info.format_feature_flags);
|
detail::find_surface_format(info.physical_device, surface_support.formats, desired_formats, info.format_feature_flags);
|
||||||
|
if (!surface_format_ret.has_value()) return Error{ SwapchainError::required_usage_or_features_not_supported };
|
||||||
|
auto surface_format = surface_format_ret.value();
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -1782,6 +1789,11 @@ 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);
|
||||||
|
|
||||||
|
if (detail::is_unextended_present_mode(present_mode) &&
|
||||||
|
(info.image_usage_flags & surface_support.capabilities.supportedUsageFlags) != info.image_usage_flags) {
|
||||||
|
return Error{ SwapchainError::required_usage_or_features_not_supported };
|
||||||
|
}
|
||||||
|
|
||||||
VkSurfaceTransformFlagBitsKHR pre_transform = info.pre_transform;
|
VkSurfaceTransformFlagBitsKHR pre_transform = info.pre_transform;
|
||||||
if (info.pre_transform == static_cast<VkSurfaceTransformFlagBitsKHR>(0))
|
if (info.pre_transform == static_cast<VkSurfaceTransformFlagBitsKHR>(0))
|
||||||
pre_transform = surface_support.capabilities.currentTransform;
|
pre_transform = surface_support.capabilities.currentTransform;
|
||||||
@ -1977,7 +1989,7 @@ SwapchainBuilder& SwapchainBuilder::add_format_feature_flags(VkFormatFeatureFlag
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SwapchainBuilder& SwapchainBuilder::use_default_format_feature_flags() {
|
SwapchainBuilder& SwapchainBuilder::use_default_format_feature_flags() {
|
||||||
info.format_feature_flags = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
|
info.format_feature_flags = 0;
|
||||||
return *this;
|
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) {
|
||||||
|
@ -213,6 +213,7 @@ enum class SwapchainError {
|
|||||||
failed_get_swapchain_images,
|
failed_get_swapchain_images,
|
||||||
failed_create_swapchain_image_views,
|
failed_create_swapchain_image_views,
|
||||||
required_min_image_count_too_low,
|
required_min_image_count_too_low,
|
||||||
|
required_usage_or_features_not_supported
|
||||||
};
|
};
|
||||||
|
|
||||||
std::error_code make_error_code(InstanceError instance_error);
|
std::error_code make_error_code(InstanceError instance_error);
|
||||||
@ -841,6 +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.
|
||||||
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);
|
||||||
@ -849,11 +851,14 @@ class SwapchainBuilder {
|
|||||||
SwapchainBuilder& use_default_image_usage_flags();
|
SwapchainBuilder& use_default_image_usage_flags();
|
||||||
|
|
||||||
// Set the bitmask of the format feature flag for acquired swapchain images.
|
// Set the bitmask of the format feature flag for acquired swapchain images.
|
||||||
|
// If the desired formats cannot allow it, building the swapchain will result in the
|
||||||
|
// `SwapchainError::required_usage_or_features_not_supported` error. 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);
|
SwapchainBuilder& set_format_feature_flags(VkFormatFeatureFlags feature_flags);
|
||||||
// Add a format feature to the bitmask for acquired swapchain images.
|
// Add a format feature to the bitmask for acquired swapchain images.
|
||||||
SwapchainBuilder& add_format_feature_flags(VkFormatFeatureFlags feature_flags);
|
SwapchainBuilder& add_format_feature_flags(VkFormatFeatureFlags feature_flags);
|
||||||
// Use the default format feature bitmask values. This is the default if no format features
|
// Use the default format feature bitmask values. This is the default if no format features
|
||||||
// are provided. The default is VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
|
// are provided. The default is 0
|
||||||
SwapchainBuilder& use_default_format_feature_flags();
|
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
|
||||||
@ -922,7 +927,7 @@ 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 = VK_FORMAT_FEATURE_SAMPLED_IMAGE_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);
|
||||||
|
@ -305,6 +305,7 @@ TEST_CASE("Swapchain", "[VkBootstrap.bootstrap]") {
|
|||||||
vkb::SwapchainBuilder swapchain_builder(device);
|
vkb::SwapchainBuilder swapchain_builder(device);
|
||||||
auto swapchain_ret = swapchain_builder.set_desired_extent(256, 256)
|
auto swapchain_ret = swapchain_builder.set_desired_extent(256, 256)
|
||||||
.set_desired_format({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR })
|
.set_desired_format({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR })
|
||||||
|
.add_fallback_format({ VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR })
|
||||||
.set_desired_present_mode(VK_PRESENT_MODE_IMMEDIATE_KHR)
|
.set_desired_present_mode(VK_PRESENT_MODE_IMMEDIATE_KHR)
|
||||||
.set_pre_transform_flags(VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
|
.set_pre_transform_flags(VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
|
||||||
.set_composite_alpha_flags(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
|
.set_composite_alpha_flags(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
|
||||||
|
Loading…
Reference in New Issue
Block a user