mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 20:50:09 +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 */ \
|
/* 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. */ \
|
/* this extension. These are listed here in order to hide them from the application. */ \
|
||||||
EP(GetPhysicalDeviceExternalBufferPropertiesKHR, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \
|
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.
|
* @brief Struct representing the instance dispatch table.
|
||||||
|
|
|
||||||
|
|
@ -27,28 +27,92 @@
|
||||||
*
|
*
|
||||||
* @brief Contains the functionality to implement features for present timing extension.
|
* @brief Contains the functionality to implement features for present timing extension.
|
||||||
*/
|
*/
|
||||||
|
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||||
#include "present_timing_handler.hpp"
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <array>
|
#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_ext_present_timing_headless::wsi_ext_present_timing_headless(const util::allocator &allocator)
|
||||||
: wsi::wsi_ext_present_timing(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(
|
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 = {
|
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,
|
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
|
||||||
VK_TIME_DOMAIN_DEVICE_KHR),
|
VK_TIME_DOMAIN_DEVICE_KHR),
|
||||||
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT,
|
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT, monotonic_time_domain),
|
||||||
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR),
|
|
||||||
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT,
|
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,
|
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);
|
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;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -41,7 +41,8 @@
|
||||||
class wsi_ext_present_timing_headless : public wsi::wsi_ext_present_timing
|
class wsi_ext_present_timing_headless : public wsi::wsi_ext_present_timing
|
||||||
{
|
{
|
||||||
public:
|
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,
|
VkResult get_swapchain_timing_properties(uint64_t &timing_properties_counter,
|
||||||
VkSwapchainTimingPropertiesEXT &timing_properties) override;
|
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;
|
bool swapchain_support_enabled = swapchain_create_info->flags & VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT;
|
||||||
if (swapchain_support_enabled)
|
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;
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue