mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2026-05-05 19:18:10 +02:00
Update time domain handling to comply with Vulkan spec
- Refactor vkGetSwapchainTimeDomainPropertiesEXT to follow spec - Ensure all time values are returned in nanoseconds according to the active time domain Signed-off-by: Maged Elnaggar <maged.elnaggar@arm.com> Change-Id: Id4c6b86577bd509ec7bb5a946785dbe6642cfb1c
This commit is contained in:
parent
9296f8032e
commit
3ffd85a26d
4 changed files with 51 additions and 26 deletions
|
|
@ -530,14 +530,16 @@ wsi_layer_vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physical_device,
|
|||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, pFeatures->pNext);
|
||||
if (present_timing_features != nullptr)
|
||||
{
|
||||
VkPhysicalDeviceProperties physical_device_properties = {};
|
||||
instance.disp.GetPhysicalDeviceProperties(physical_device, &physical_device_properties);
|
||||
VkPhysicalDeviceProperties2KHR physical_device_properties{};
|
||||
physical_device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
|
||||
instance.disp.GetPhysicalDeviceProperties2KHR(physical_device, &physical_device_properties);
|
||||
/* The presentTimingSupported is set based on whether the device can support timestamp queries
|
||||
* and the graphics, compute pipelines can support time stamps. Only the graphics and compute pipelines
|
||||
* are checked here which means queue present if happens on a different queue family,
|
||||
* the time stamps might not be supported. */
|
||||
present_timing_features->presentTiming = ((physical_device_properties.limits.timestampPeriod != 0) &&
|
||||
physical_device_properties.limits.timestampComputeAndGraphics);
|
||||
present_timing_features->presentTiming =
|
||||
((physical_device_properties.properties.limits.timestampPeriod != 0) &&
|
||||
physical_device_properties.properties.limits.timestampComputeAndGraphics);
|
||||
present_timing_features->presentAtAbsoluteTime = VK_TRUE;
|
||||
present_timing_features->presentAtRelativeTime = VK_TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <wsi/swapchain_base.hpp>
|
||||
#include <util/helpers.hpp>
|
||||
|
||||
|
|
@ -59,7 +60,14 @@ wsi_ext_present_timing::wsi_ext_present_timing(const util::allocator &allocator,
|
|||
, m_queue(allocator)
|
||||
, m_num_images(num_images)
|
||||
, m_present_semaphore(allocator)
|
||||
, m_timestamp_period(0.f)
|
||||
{
|
||||
VkPhysicalDeviceProperties2KHR physical_device_properties{};
|
||||
physical_device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
|
||||
const auto &dev = layer::device_private_data::get(m_device);
|
||||
auto &inst = layer::instance_private_data::get(dev.physical_device);
|
||||
inst.disp.GetPhysicalDeviceProperties2KHR(dev.physical_device, &physical_device_properties);
|
||||
m_timestamp_period = physical_device_properties.properties.limits.timestampPeriod;
|
||||
}
|
||||
|
||||
wsi_ext_present_timing::~wsi_ext_present_timing()
|
||||
|
|
@ -143,6 +151,15 @@ VkResult wsi_ext_present_timing::init_timing_resources()
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static inline uint64_t ticks_to_ns(uint64_t ticks, const float ×tamp_period)
|
||||
{
|
||||
/* timestamp_period is float (ns per tick). Use double so we keep
|
||||
52-bit integer precision (≈4.5×10¹⁵ ticks) without overflow. */
|
||||
assert(std::isfinite(timestamp_period) && timestamp_period > 0.0f);
|
||||
double ns = static_cast<double>(ticks) * static_cast<double>(timestamp_period);
|
||||
return static_cast<uint64_t>(std::llround(ns));
|
||||
}
|
||||
|
||||
VkResult wsi_ext_present_timing::get_queue_end_timing_to_queue(uint32_t image_index)
|
||||
{
|
||||
for (auto &slot : m_queue)
|
||||
|
|
@ -154,7 +171,7 @@ VkResult wsi_ext_present_timing::get_queue_end_timing_to_queue(uint32_t image_in
|
|||
const layer::device_private_data &device_data = layer::device_private_data::get(m_device);
|
||||
TRY(device_data.disp.GetQueryPoolResults(m_device, m_query_pool, image_index, 1, sizeof(time), &time, 0,
|
||||
VK_QUERY_RESULT_64_BIT));
|
||||
stage_timing_optional->get().m_time.store(time);
|
||||
stage_timing_optional->get().m_time.store(ticks_to_ns(time, m_timestamp_period));
|
||||
stage_timing_optional->get().m_set.store(true, std::memory_order_release);
|
||||
/* For an image index, there can only be one entry in the internal queue with pending results. */
|
||||
break;
|
||||
|
|
@ -505,7 +522,7 @@ std::optional<std::reference_wrapper<swapchain_presentation_timing>> swapchain_p
|
|||
|
||||
void swapchain_presentation_entry::populate(VkPastPresentationTimingEXT &timing)
|
||||
{
|
||||
uint64_t stage_index = 0;
|
||||
uint32_t stage_index = 0;
|
||||
for (const auto &stage : g_present_stages)
|
||||
{
|
||||
auto stage_timing_optional = get_stage_timing(stage);
|
||||
|
|
@ -549,30 +566,30 @@ VkResult swapchain_time_domains::calibrate(VkPresentStageFlagBitsEXT present_sta
|
|||
VkResult swapchain_time_domains::get_swapchain_time_domain_properties(
|
||||
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties, uint64_t *pTimeDomainsCounter)
|
||||
{
|
||||
/* Since we only have a single time domain available we don't need to check
|
||||
* timeDomainCount since it can only be >= 1 */
|
||||
constexpr uint32_t available_domains_count = 1;
|
||||
|
||||
if (pTimeDomainsCounter != nullptr)
|
||||
{
|
||||
*pTimeDomainsCounter = 1;
|
||||
}
|
||||
|
||||
if (pSwapchainTimeDomainProperties != nullptr)
|
||||
if (pSwapchainTimeDomainProperties->pTimeDomains == nullptr &&
|
||||
pSwapchainTimeDomainProperties->pTimeDomainIds == nullptr)
|
||||
{
|
||||
if ((pSwapchainTimeDomainProperties->pTimeDomains == nullptr &&
|
||||
pSwapchainTimeDomainProperties->pTimeDomainIds == nullptr) ||
|
||||
pSwapchainTimeDomainProperties->timeDomainCount == 0)
|
||||
{
|
||||
pSwapchainTimeDomainProperties->timeDomainCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Since we only have a single time domain available we don't need to check
|
||||
* timeDomainCount since it can only be >= 1 */
|
||||
pSwapchainTimeDomainProperties->timeDomainCount = 1;
|
||||
pSwapchainTimeDomainProperties->pTimeDomains[0] = VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT;
|
||||
pSwapchainTimeDomainProperties->pTimeDomainIds[0] = 0;
|
||||
}
|
||||
pSwapchainTimeDomainProperties->timeDomainCount = available_domains_count;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
const uint32_t requested_domains_count = pSwapchainTimeDomainProperties->timeDomainCount;
|
||||
const uint32_t domains_count_to_write = std::min(requested_domains_count, available_domains_count);
|
||||
|
||||
pSwapchainTimeDomainProperties->pTimeDomains[0] = VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT;
|
||||
pSwapchainTimeDomainProperties->pTimeDomainIds[0] = 0;
|
||||
pSwapchainTimeDomainProperties->timeDomainCount = domains_count_to_write;
|
||||
|
||||
return (domains_count_to_write < available_domains_count) ? VK_INCOMPLETE : VK_SUCCESS;
|
||||
}
|
||||
|
||||
bool swapchain_time_domains::add_time_domain(util::unique_ptr<swapchain_time_domain> time_domain)
|
||||
|
|
|
|||
|
|
@ -455,6 +455,11 @@ private:
|
|||
*/
|
||||
util::vector<VkSemaphore> m_present_semaphore;
|
||||
|
||||
/**
|
||||
* @brief The timestamp period from the device properties.
|
||||
*/
|
||||
float m_timestamp_period;
|
||||
|
||||
/**
|
||||
* @brief Perform a queue submission for getting the queue end timing.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -104,11 +104,12 @@ void get_surface_capabilities_common(VkPhysicalDevice physical_device, VkSurface
|
|||
surface_capabilities->currentExtent = { 0xffffffff, 0xffffffff };
|
||||
surface_capabilities->minImageExtent = { 1, 1 };
|
||||
/* Ask the device for max */
|
||||
VkPhysicalDeviceProperties dev_props = {};
|
||||
layer::instance_private_data::get(physical_device).disp.GetPhysicalDeviceProperties(physical_device, &dev_props);
|
||||
VkPhysicalDeviceProperties2KHR dev_props{};
|
||||
dev_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
|
||||
layer::instance_private_data::get(physical_device).disp.GetPhysicalDeviceProperties2KHR(physical_device, &dev_props);
|
||||
|
||||
surface_capabilities->maxImageExtent = { dev_props.limits.maxImageDimension2D,
|
||||
dev_props.limits.maxImageDimension2D };
|
||||
surface_capabilities->maxImageExtent = { dev_props.properties.limits.maxImageDimension2D,
|
||||
dev_props.properties.limits.maxImageDimension2D };
|
||||
surface_capabilities->maxImageArrayLayers = 1;
|
||||
|
||||
/* Surface transforms */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue