Add support for scaling capabilities

Add support for handling VkSwapchainPresentScalingCreateInfoEXT and
VkSurfacePresentScalingCapabilitiesEXT, as part of the
swapchain_maintenance1 and surface_maintenance1 features.

On Wayland, we will report support for ONE_TO_ONE scaling (i.e. no
scaling) and a default gravity of top left. On Headless, we report 0
scaling support as there's no presentation engine anyway.

Change-Id: Ife41e7e06109bd917fa480b07e447008c9a4f9e1
Signed-off-by: Dennis Tsiang <dennis.tsiang@arm.com>
Signed-off-by: Fufu Fang <fufu.fang@arm.com>
This commit is contained in:
Dennis Tsiang 2024-04-22 14:52:05 +01:00 committed by Fufu Fang
parent 9edb068a38
commit bb31e7fba0
6 changed files with 76 additions and 0 deletions

View file

@ -87,6 +87,16 @@ VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_
TRY(check_surface_present_mode_query_is_supported(surface_info, supported_modes));
get_surface_capabilities_common(physical_device, &surface_capabilities->surfaceCapabilities);
get_surface_present_mode_compatibility_common(surface_info, surface_capabilities, present_mode_compatibilities);
auto surface_scaling_capabilities = util::find_extension<VkSurfacePresentScalingCapabilitiesEXT>(
VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT, surface_capabilities);
if (surface_scaling_capabilities != nullptr)
{
get_surface_present_scaling_and_gravity(surface_scaling_capabilities);
surface_scaling_capabilities->minScaledImageExtent = surface_capabilities->surfaceCapabilities.minImageExtent;
surface_scaling_capabilities->maxScaledImageExtent = surface_capabilities->surfaceCapabilities.maxImageExtent;
}
return VK_SUCCESS;
}
@ -190,5 +200,13 @@ bool surface_properties::is_surface_extension_enabled(const layer::instance_priv
return instance_data.is_instance_extension_enabled(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME);
}
void surface_properties::get_surface_present_scaling_and_gravity(
VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities)
{
scaling_capabilities->supportedPresentScaling = 0;
scaling_capabilities->supportedPresentGravityX = 0;
scaling_capabilities->supportedPresentGravityY = 0;
}
} /* namespace headless */
} /* namespace wsi */

View file

@ -68,6 +68,8 @@ private:
std::array<present_mode_compatibility, 4> present_mode_compatibilities;
void populate_present_mode_compatibilities() override;
void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
};
} /* namespace headless */

View file

@ -115,6 +115,12 @@ public:
/* There is no maximum theoretically speaking however we choose 6 for practicality */
static constexpr uint32_t MAX_SWAPCHAIN_IMAGE_COUNT = 6;
/**
* @brief Get the scaling and gravity capabilities of the surface.
*/
virtual void get_surface_present_scaling_and_gravity(
VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) = 0;
private:
/**
* @brief Set which presentation modes are compatible with each other for a particular surface

View file

@ -45,6 +45,7 @@
#include "util/helpers.hpp"
#include "swapchain_base.hpp"
#include "wsi_factory.hpp"
namespace wsi
{
@ -224,6 +225,34 @@ swapchain_base::swapchain_base(layer::device_private_data &dev_data, const VkAll
{
}
static VkResult handle_scaling_create_info(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info,
const VkSurfaceKHR &surface)
{
auto present_scaling_create_info = util::find_extension<VkSwapchainPresentScalingCreateInfoEXT>(
VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT, swapchain_create_info);
if (present_scaling_create_info != nullptr)
{
auto &device_data = layer::device_private_data::get(device);
auto &instance = device_data.instance_data;
VkSurfacePresentScalingCapabilitiesEXT scaling_capabilities = {};
wsi::surface_properties *props = wsi::get_surface_properties(instance, surface);
props->get_surface_present_scaling_and_gravity(&scaling_capabilities);
if (((present_scaling_create_info->scalingBehavior != 0) &&
((scaling_capabilities.supportedPresentScaling & present_scaling_create_info->scalingBehavior) == 0)) ||
((present_scaling_create_info->presentGravityX != 0) &&
((scaling_capabilities.supportedPresentGravityX & present_scaling_create_info->presentGravityX) == 0)) ||
((present_scaling_create_info->presentGravityY != 0) &&
((scaling_capabilities.supportedPresentGravityY & present_scaling_create_info->presentGravityY) == 0)))
{
return VK_ERROR_INITIALIZATION_FAILED;
}
}
return VK_SUCCESS;
}
VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info)
{
assert(device != VK_NULL_HANDLE);
@ -256,6 +285,8 @@ VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *s
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
TRY_LOG_CALL(handle_scaling_create_info(device, swapchain_create_info, m_surface));
/* We have allocated images, we can call the platform init function if something needs to be done. */
bool use_presentation_thread = true;
TRY_LOG_CALL(init_platform(device, swapchain_create_info, use_presentation_thread));

View file

@ -99,6 +99,15 @@ VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_
get_surface_present_mode_compatibility_common(pSurfaceInfo, pSurfaceCapabilities, present_mode_compatibilities);
auto surface_scaling_capabilities = util::find_extension<VkSurfacePresentScalingCapabilitiesEXT>(
VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT, pSurfaceCapabilities);
if (surface_scaling_capabilities != nullptr)
{
get_surface_present_scaling_and_gravity(surface_scaling_capabilities);
surface_scaling_capabilities->minScaledImageExtent = pSurfaceCapabilities->surfaceCapabilities.minImageExtent;
surface_scaling_capabilities->maxScaledImageExtent = pSurfaceCapabilities->surfaceCapabilities.maxImageExtent;
}
return VK_SUCCESS;
}
@ -394,5 +403,13 @@ bool surface_properties::is_surface_extension_enabled(const layer::instance_priv
return instance_data.is_instance_extension_enabled(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
}
void surface_properties::get_surface_present_scaling_and_gravity(
VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities)
{
scaling_capabilities->supportedPresentScaling = VK_PRESENT_SCALING_ONE_TO_ONE_BIT_EXT;
scaling_capabilities->supportedPresentGravityX = VK_PRESENT_GRAVITY_MIN_BIT_EXT;
scaling_capabilities->supportedPresentGravityY = VK_PRESENT_GRAVITY_MIN_BIT_EXT;
}
} // namespace wayland
} // namespace wsi

View file

@ -88,6 +88,8 @@ private:
std::array<present_mode_compatibility, 2> present_mode_compatibilities;
void populate_present_mode_compatibilities() override;
void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
};
} // namespace wayland