mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 04:30:11 +01:00
Merge 'Implement schedule present at relative time on headless' into 'main'
See merge request mesa/vulkan-wsi-layer!201
This commit is contained in:
commit
623f803387
4 changed files with 58 additions and 14 deletions
|
|
@ -151,4 +151,17 @@ std::optional<uint64_t> wsi_ext_present_timing_headless::get_current_clock_time_
|
|||
return now.tv_sec * static_cast<uint64_t>(1e9) + now.tv_nsec;
|
||||
}
|
||||
|
||||
std::optional<uint64_t> wsi_ext_present_timing_headless::get_first_pixel_visible_timestamp_for_last_image() const
|
||||
{
|
||||
if (!m_first_pixel_visible_timestamp_for_last_image.has_value())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return m_first_pixel_visible_timestamp_for_last_image.value();
|
||||
}
|
||||
|
||||
void wsi_ext_present_timing_headless::set_first_pixel_visible_timestamp_for_last_image(uint64_t timestamp)
|
||||
{
|
||||
m_first_pixel_visible_timestamp_for_last_image = timestamp;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -67,6 +67,19 @@ public:
|
|||
*/
|
||||
std::optional<uint64_t> get_current_clock_time_ns() const;
|
||||
|
||||
/**
|
||||
* @brief Get the first pixel visible timestamp for the last presented image.
|
||||
*
|
||||
* @return first pixel visible timestamp for the last presented image or std::nullopt in case of error.
|
||||
*/
|
||||
std::optional<uint64_t> get_first_pixel_visible_timestamp_for_last_image() const;
|
||||
|
||||
/**
|
||||
* @brief Caches the first pixel visible timestamp for the last presented image.
|
||||
*
|
||||
*/
|
||||
void set_first_pixel_visible_timestamp_for_last_image(uint64_t timestamp);
|
||||
|
||||
private:
|
||||
wsi_ext_present_timing_headless(const util::allocator &allocator, VkDevice device, uint32_t num_images,
|
||||
std::optional<VkTimeDomainEXT> monotonic_domain);
|
||||
|
|
@ -76,6 +89,11 @@ private:
|
|||
|
||||
/* Monotonic time domain supported by the driver */
|
||||
std::optional<VkTimeDomainEXT> m_monotonic_domain;
|
||||
|
||||
/**
|
||||
* Timestamp for the last VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT stage.
|
||||
*/
|
||||
std::optional<uint64_t> m_first_pixel_visible_timestamp_for_last_image;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ VkResult surface_properties::get_present_timing_surface_caps(
|
|||
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
|
||||
{
|
||||
present_timing_surface_caps->presentTimingSupported = VK_TRUE;
|
||||
present_timing_surface_caps->presentAtAbsoluteTimeSupported = VK_TRUE;
|
||||
present_timing_surface_caps->presentAtAbsoluteTimeSupported = VK_FALSE;
|
||||
present_timing_surface_caps->presentAtRelativeTimeSupported = VK_FALSE;
|
||||
|
||||
VkPresentStageFlagsEXT monotonic_present_stages_supported = 0;
|
||||
|
|
@ -264,6 +264,8 @@ VkResult surface_properties::get_present_timing_surface_caps(
|
|||
monotonic_present_stages_supported |= VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT |
|
||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT |
|
||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT;
|
||||
present_timing_surface_caps->presentAtAbsoluteTimeSupported = VK_TRUE;
|
||||
present_timing_surface_caps->presentAtRelativeTimeSupported = VK_TRUE;
|
||||
}
|
||||
|
||||
present_timing_surface_caps->presentStageQueries =
|
||||
|
|
|
|||
|
|
@ -227,25 +227,35 @@ void swapchain::present_image(const pending_present_request &pending_present)
|
|||
if (ext_present_timing)
|
||||
{
|
||||
auto presentation_target = ext_present_timing->get_presentation_target_entry(pending_present.image_index);
|
||||
uint64_t absolute_future_present_time_ns = 0;
|
||||
if (presentation_target)
|
||||
{
|
||||
/* No support for relative presentation mode currently */
|
||||
assert(!(presentation_target->m_flags & VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT));
|
||||
if (!(presentation_target->m_flags & VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT))
|
||||
if (presentation_target->m_flags & VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT)
|
||||
{
|
||||
std::optional<uint64_t> first_pixel_visible_timestamp_for_last_image =
|
||||
ext_present_timing->get_first_pixel_visible_timestamp_for_last_image();
|
||||
|
||||
if (first_pixel_visible_timestamp_for_last_image.has_value())
|
||||
{
|
||||
absolute_future_present_time_ns =
|
||||
first_pixel_visible_timestamp_for_last_image.value() + presentation_target->m_target_present_time;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No need to check whether we need to present at nearest refresh cycle since this backend is not
|
||||
limited by the refresh cycles. */
|
||||
uint64_t absolute_future_present_time_ns = presentation_target->m_target_present_time;
|
||||
auto current_time_ns = ext_present_timing->get_current_clock_time_ns();
|
||||
if (*current_time_ns < absolute_future_present_time_ns)
|
||||
{
|
||||
/* Sleep until we can schedule the image for completion.
|
||||
* This is OK as the sleep should only be dispatched on the page_flip thread and not on main. */
|
||||
assert(m_page_flip_thread_run);
|
||||
absolute_future_present_time_ns = presentation_target->m_target_present_time;
|
||||
}
|
||||
auto current_time_ns = ext_present_timing->get_current_clock_time_ns();
|
||||
if (*current_time_ns < absolute_future_present_time_ns)
|
||||
{
|
||||
/* Sleep until we can schedule the image for completion.
|
||||
* This is OK as the sleep should only be dispatched on the page_flip thread and not on main. */
|
||||
assert(m_page_flip_thread_run);
|
||||
|
||||
int64_t time_diff = absolute_future_present_time_ns - *current_time_ns;
|
||||
std::this_thread::sleep_for(std::chrono::nanoseconds(time_diff));
|
||||
}
|
||||
int64_t time_diff = absolute_future_present_time_ns - *current_time_ns;
|
||||
std::this_thread::sleep_for(std::chrono::nanoseconds(time_diff));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -268,6 +278,7 @@ void swapchain::present_image(const pending_present_request &pending_present)
|
|||
/* Set all times to 0 as we were not able to query them. */
|
||||
current_time = 0;
|
||||
}
|
||||
ext_present_timing->set_first_pixel_visible_timestamp_for_last_image(*current_time);
|
||||
|
||||
VkPresentStageFlagBitsEXT stages[] = {
|
||||
VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue