panvk: Implement VK_KHR_calibrated_timestamps

Add entrypoints for calibrated timestamps.

Co-authored-by: Mary Guillemard <mary.guillemard@collabora.com>

Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35510>
This commit is contained in:
Christoph Pillmayer
2025-05-07 09:15:41 +00:00
committed by Marge Bot
parent fb38f10240
commit 4d5f0f6ee2
2 changed files with 100 additions and 0 deletions
@@ -1258,3 +1258,35 @@ panvk_GetPhysicalDeviceExternalBufferProperties(
.compatibleHandleTypes = handle_types,
};
}
static const VkTimeDomainKHR panvk_time_domains[] = {
VK_TIME_DOMAIN_DEVICE_KHR,
VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR,
#ifdef CLOCK_MONOTONIC_RAW
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR,
#endif
};
VKAPI_ATTR VkResult VKAPI_CALL
panvk_GetPhysicalDeviceCalibrateableTimeDomainsKHR(
VkPhysicalDevice physicalDevice, uint32_t *pTimeDomainCount,
VkTimeDomainKHR *pTimeDomains)
{
VK_FROM_HANDLE(panvk_physical_device, pdev, physicalDevice);
VK_OUTARRAY_MAKE_TYPED(VkTimeDomainKHR, out, pTimeDomains, pTimeDomainCount);
int d = 0;
/* If GPU query timestamp isn't supported, skip device domain */
if (!pdev->kmod.props.gpu_can_query_timestamp)
d++;
for (; d < ARRAY_SIZE(panvk_time_domains); d++) {
vk_outarray_append_typed(VkTimeDomainKHR, &out, i)
{
*i = panvk_time_domains[d];
}
}
return vk_outarray_status(&out);
}
+68
View File
@@ -609,3 +609,71 @@ panvk_per_arch(GetRenderingAreaGranularityKHR)(
{
*pGranularity = (VkExtent2D){32, 32};
}
VKAPI_ATTR VkResult VKAPI_CALL
panvk_per_arch(GetCalibratedTimestampsKHR)(
VkDevice _device, uint32_t timestampCount,
const VkCalibratedTimestampInfoKHR *pTimestampInfos, uint64_t *pTimestamps,
uint64_t *pMaxDeviation)
{
VK_FROM_HANDLE(panvk_device, device, _device);
struct panvk_physical_device *pdev =
to_panvk_physical_device(device->vk.physical);
bool requested_domain[] = {
[VK_TIME_DOMAIN_DEVICE_KHR] = false,
[VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR] = false,
[VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR] = false,
};
uint64_t timestamps[] = {
[VK_TIME_DOMAIN_DEVICE_KHR] = 0,
[VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR] = 0,
[VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR] = 0,
};
uint64_t max_period = 0;
for (uint32_t idx = 0; idx < timestampCount; ++idx)
requested_domain[pTimestampInfos[idx].timeDomain] |= true;
uint64_t begin, end;
#ifdef CLOCK_MONOTONIC_RAW
requested_domain[VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR] = true;
begin = vk_clock_gettime(CLOCK_MONOTONIC_RAW);
#else
requested_domain[VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR] = true;
begin = vk_clock_gettime(CLOCK_MONOTONIC);
#endif
if (requested_domain[VK_TIME_DOMAIN_DEVICE_KHR]) {
timestamps[VK_TIME_DOMAIN_DEVICE_KHR] =
pan_kmod_query_timestamp(pdev->kmod.dev);
max_period = MAX2(max_period, panvk_get_gpu_system_timestamp_period(pdev));
}
if (requested_domain[VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR]) {
timestamps[VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR] =
vk_clock_gettime(CLOCK_MONOTONIC);
max_period = MAX2(max_period, 1);
}
#ifdef CLOCK_MONOTONIC_RAW
if (requested_domain[VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR]) {
timestamps[VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR] =
vk_clock_gettime(CLOCK_MONOTONIC_RAW);
max_period = MAX2(max_period, 1);
}
#endif
#ifdef CLOCK_MONOTONIC_RAW
end = timestamps[VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR];
#else
end = timestamps[VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR];
#endif
for (uint32_t idx = 0; idx < timestampCount; ++idx)
pTimestamps[idx] = timestamps[pTimestampInfos[idx].timeDomain];
*pMaxDeviation = vk_time_max_deviation(begin, end, max_period);
return VK_SUCCESS;
}