mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 05:40:10 +01:00
Support WSI present timing if time domain supported
This commit is contained in:
parent
c3b192ac2f
commit
16e77d770a
4 changed files with 79 additions and 10 deletions
|
|
@ -262,7 +262,10 @@ static constexpr uint32_t API_VERSION_MAX = UINT32_MAX;
|
|||
/* The layer does not use these entrypoints directly but does use VkExternalImageFormatPropertiesKHR introduced by */ \
|
||||
/* this extension. These are listed here in order to hide them from the application. */ \
|
||||
EP(GetPhysicalDeviceExternalBufferPropertiesKHR, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \
|
||||
VK_API_VERSION_1_1, false, GetPhysicalDeviceExternalBufferProperties)
|
||||
VK_API_VERSION_1_1, false, GetPhysicalDeviceExternalBufferProperties) \
|
||||
/* VK_KHR_calibrated_timestamps */ \
|
||||
EP(GetPhysicalDeviceCalibrateableTimeDomainsKHR, VK_KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, API_VERSION_MAX, \
|
||||
false, )
|
||||
|
||||
/**
|
||||
* @brief Struct representing the instance dispatch table.
|
||||
|
|
|
|||
|
|
@ -27,28 +27,92 @@
|
|||
*
|
||||
* @brief Contains the functionality to implement features for present timing extension.
|
||||
*/
|
||||
|
||||
#include "present_timing_handler.hpp"
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
#include "present_timing_handler.hpp"
|
||||
#include "layer/private_data.hpp"
|
||||
|
||||
wsi_ext_present_timing_headless::wsi_ext_present_timing_headless(const util::allocator &allocator)
|
||||
: wsi::wsi_ext_present_timing(allocator)
|
||||
{
|
||||
}
|
||||
/**
|
||||
* @brief Queries whether the driver supports the raw monotonic clock domain.
|
||||
*
|
||||
* This function invokes vkGetPhysicalDeviceCalibrateableTimeDomainsKHR twice:
|
||||
* 1. To query the count of supported time domains.
|
||||
* 2. To retrieve the list of supported time domains.
|
||||
*
|
||||
* @param device The Vulkan logical device whose physical device is queried. Must be valid.
|
||||
* @return A std::optional<bool> with:
|
||||
* - true if VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR is supported.
|
||||
* - false if VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR is not supported.
|
||||
* - std::nullopt if the query fails (e.g., vkGetPhysicalDeviceCalibrateableTimeDomainsKHR
|
||||
* returns an error or memory allocation fails).
|
||||
*/
|
||||
static std::optional<bool> is_time_domain_clock_monotonic_raw_supported(const VkDevice &device)
|
||||
{
|
||||
auto &dev_data = layer::device_private_data::get(device);
|
||||
auto &physicalDevice = dev_data.physical_device;
|
||||
auto &instance = dev_data.instance_data;
|
||||
|
||||
uint32_t supported_domains_count = 0;
|
||||
VkResult result =
|
||||
instance.disp.GetPhysicalDeviceCalibrateableTimeDomainsKHR(physicalDevice, &supported_domains_count, nullptr);
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
util::allocator allocator(instance.get_allocator(), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
util::vector<VkTimeDomainEXT> supported_domains(allocator);
|
||||
if (!supported_domains.try_resize(supported_domains_count))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
result = instance.disp.GetPhysicalDeviceCalibrateableTimeDomainsKHR(physicalDevice, &supported_domains_count,
|
||||
supported_domains.data());
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool supported = std::find(supported_domains.begin(), supported_domains.end(),
|
||||
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR) != supported_domains.end();
|
||||
return supported;
|
||||
}
|
||||
|
||||
util::unique_ptr<wsi_ext_present_timing_headless> wsi_ext_present_timing_headless::create(
|
||||
const util::allocator &allocator)
|
||||
const VkDevice &device, const util::allocator &allocator)
|
||||
{
|
||||
/*
|
||||
* Select the hardware raw monotonic clock domain (unaffected by NTP or adjtime adjustments)
|
||||
* when the driver supports it; otherwise use the standard monotonic clock.
|
||||
*/
|
||||
VkTimeDomainKHR monotonic_time_domain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR;
|
||||
|
||||
auto clock_monotonic_raw_support = is_time_domain_clock_monotonic_raw_supported(device);
|
||||
if (!clock_monotonic_raw_support.has_value())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else if (clock_monotonic_raw_support.value() == false)
|
||||
{
|
||||
monotonic_time_domain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR;
|
||||
}
|
||||
|
||||
std::array<util::unique_ptr<wsi::vulkan_time_domain>, 4> time_domains_array = {
|
||||
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
|
||||
VK_TIME_DOMAIN_DEVICE_KHR),
|
||||
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT,
|
||||
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR),
|
||||
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT, monotonic_time_domain),
|
||||
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT,
|
||||
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR),
|
||||
monotonic_time_domain),
|
||||
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT,
|
||||
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR)
|
||||
monotonic_time_domain)
|
||||
};
|
||||
|
||||
return wsi_ext_present_timing::create<wsi_ext_present_timing_headless>(allocator, time_domains_array);
|
||||
|
|
@ -66,3 +130,4 @@ VkResult wsi_ext_present_timing_headless::get_swapchain_timing_properties(
|
|||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -41,7 +41,8 @@
|
|||
class wsi_ext_present_timing_headless : public wsi::wsi_ext_present_timing
|
||||
{
|
||||
public:
|
||||
static util::unique_ptr<wsi_ext_present_timing_headless> create(const util::allocator &allocator);
|
||||
static util::unique_ptr<wsi_ext_present_timing_headless> create(const VkDevice &device,
|
||||
const util::allocator &allocator);
|
||||
|
||||
VkResult get_swapchain_timing_properties(uint64_t &timing_properties_counter,
|
||||
VkSwapchainTimingPropertiesEXT &timing_properties) override;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
|
|||
bool swapchain_support_enabled = swapchain_create_info->flags & VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT;
|
||||
if (swapchain_support_enabled)
|
||||
{
|
||||
if (!add_swapchain_extension(wsi_ext_present_timing_headless::create(m_allocator)))
|
||||
if (!add_swapchain_extension(wsi_ext_present_timing_headless::create(device, m_allocator)))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue