mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 16:10:09 +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;
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,19 @@ public:
|
||||||
*/
|
*/
|
||||||
std::optional<uint64_t> get_current_clock_time_ns() const;
|
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:
|
private:
|
||||||
wsi_ext_present_timing_headless(const util::allocator &allocator, VkDevice device, uint32_t num_images,
|
wsi_ext_present_timing_headless(const util::allocator &allocator, VkDevice device, uint32_t num_images,
|
||||||
std::optional<VkTimeDomainEXT> monotonic_domain);
|
std::optional<VkTimeDomainEXT> monotonic_domain);
|
||||||
|
|
@ -76,6 +89,11 @@ private:
|
||||||
|
|
||||||
/* Monotonic time domain supported by the driver */
|
/* Monotonic time domain supported by the driver */
|
||||||
std::optional<VkTimeDomainEXT> m_monotonic_domain;
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ VkResult surface_properties::get_present_timing_surface_caps(
|
||||||
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
|
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
|
||||||
{
|
{
|
||||||
present_timing_surface_caps->presentTimingSupported = VK_TRUE;
|
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;
|
present_timing_surface_caps->presentAtRelativeTimeSupported = VK_FALSE;
|
||||||
|
|
||||||
VkPresentStageFlagsEXT monotonic_present_stages_supported = 0;
|
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 |
|
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_OUT_BIT_EXT |
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_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 =
|
present_timing_surface_caps->presentStageQueries =
|
||||||
|
|
|
||||||
|
|
@ -227,25 +227,35 @@ void swapchain::present_image(const pending_present_request &pending_present)
|
||||||
if (ext_present_timing)
|
if (ext_present_timing)
|
||||||
{
|
{
|
||||||
auto presentation_target = ext_present_timing->get_presentation_target_entry(pending_present.image_index);
|
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)
|
if (presentation_target)
|
||||||
{
|
{
|
||||||
/* No support for relative presentation mode currently */
|
if (presentation_target->m_flags & VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT)
|
||||||
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))
|
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
|
/* No need to check whether we need to present at nearest refresh cycle since this backend is not
|
||||||
limited by the refresh cycles. */
|
limited by the refresh cycles. */
|
||||||
uint64_t absolute_future_present_time_ns = presentation_target->m_target_present_time;
|
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)
|
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. */
|
/* Sleep until we can schedule the image for completion.
|
||||||
assert(m_page_flip_thread_run);
|
* 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;
|
int64_t time_diff = absolute_future_present_time_ns - *current_time_ns;
|
||||||
std::this_thread::sleep_for(std::chrono::nanoseconds(time_diff));
|
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. */
|
/* Set all times to 0 as we were not able to query them. */
|
||||||
current_time = 0;
|
current_time = 0;
|
||||||
}
|
}
|
||||||
|
ext_present_timing->set_first_pixel_visible_timestamp_for_last_image(*current_time);
|
||||||
|
|
||||||
VkPresentStageFlagBitsEXT stages[] = {
|
VkPresentStageFlagBitsEXT stages[] = {
|
||||||
VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT,
|
VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue