nvk: Implement calibrated timestamps

This implementation is mostly a copy-paste from RADV

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28274>
This commit is contained in:
Echo J 2024-03-19 16:57:08 +02:00 committed by Marge Bot
parent 4b0ad410d0
commit 16753bc2f1
5 changed files with 93 additions and 2 deletions

View file

@ -503,7 +503,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_KHR_acceleration_structure DONE (anv/gfx12.5+, lvp, radv/gfx10.3+)
VK_KHR_android_surface not started
VK_KHR_calibrated_timestamps DONE (anv, radv)
VK_KHR_calibrated_timestamps DONE (anv, nvk, radv)
VK_KHR_cooperative_matrix DONE (anv, radv/gfx11+)
VK_KHR_deferred_host_operations DONE (anv, hasvk, lvp, radv)
VK_KHR_display DONE (anv, nvk, pvr, radv, tu, v3dv)
@ -558,7 +558,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_EXT_attachment_feedback_loop_layout DONE (anv, lvp, nvk, radv, tu, v3dv, vn)
VK_EXT_border_color_swizzle DONE (anv, hasvk, lvp, nvk, radv/gfx10+, tu, v3dv, vn)
VK_EXT_buffer_device_address DONE (anv, hasvk, nvk, radv)
VK_EXT_calibrated_timestamps DONE (anv, hasvk, lvp, radv, vn)
VK_EXT_calibrated_timestamps DONE (anv, hasvk, nvk, lvp, radv, vn)
VK_EXT_color_write_enable DONE (anv, hasvk, lvp, nvk, radv, tu, v3dv, vn)
VK_EXT_conditional_rendering DONE (anv, hasvk, lvp, nvk, radv, tu, vn)
VK_EXT_conservative_rasterization DONE (anv, radv, vn)

View file

@ -322,6 +322,58 @@ nvk_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
vk_free(&dev->vk.alloc, dev);
}
VKAPI_ATTR VkResult VKAPI_CALL
nvk_GetCalibratedTimestampsKHR(VkDevice _device,
uint32_t timestampCount,
const VkCalibratedTimestampInfoKHR *pTimestampInfos,
uint64_t *pTimestamps,
uint64_t *pMaxDeviation)
{
VK_FROM_HANDLE(nvk_device, dev, _device);
struct nvk_physical_device *pdev = nvk_device_physical(dev);
uint64_t max_clock_period = 0;
uint64_t begin, end;
int d;
#ifdef CLOCK_MONOTONIC_RAW
begin = vk_clock_gettime(CLOCK_MONOTONIC_RAW);
#else
begin = vk_clock_gettime(CLOCK_MONOTONIC);
#endif
for (d = 0; d < timestampCount; d++) {
switch (pTimestampInfos[d].timeDomain) {
case VK_TIME_DOMAIN_DEVICE_KHR:
pTimestamps[d] = nouveau_ws_device_timestamp(pdev->ws_dev);
max_clock_period = MAX2(max_clock_period, 1); /* FIXME: Is timestamp period actually 1? */
break;
case VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR:
pTimestamps[d] = vk_clock_gettime(CLOCK_MONOTONIC);
max_clock_period = MAX2(max_clock_period, 1);
break;
#ifdef CLOCK_MONOTONIC_RAW
case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR:
pTimestamps[d] = begin;
break;
#endif
default:
pTimestamps[d] = 0;
break;
}
}
#ifdef CLOCK_MONOTONIC_RAW
end = vk_clock_gettime(CLOCK_MONOTONIC_RAW);
#else
end = vk_clock_gettime(CLOCK_MONOTONIC);
#endif
*pMaxDeviation = vk_time_max_deviation(begin, end, max_clock_period);
return VK_SUCCESS;
}
VkResult
nvk_device_ensure_slm(struct nvk_device *dev,
uint32_t bytes_per_thread)

View file

@ -83,6 +83,7 @@ nvk_get_device_extensions(const struct nvk_instance *instance,
.KHR_16bit_storage = true,
.KHR_bind_memory2 = true,
.KHR_buffer_device_address = true,
.KHR_calibrated_timestamps = true,
.KHR_copy_commands2 = true,
.KHR_create_renderpass2 = true,
.KHR_dedicated_allocation = true,
@ -167,6 +168,7 @@ nvk_get_device_extensions(const struct nvk_instance *instance,
.EXT_attachment_feedback_loop_layout = true,
.EXT_border_color_swizzle = true,
.EXT_buffer_device_address = true,
.EXT_calibrated_timestamps = true,
.EXT_conditional_rendering = true,
.EXT_color_write_enable = true,
.EXT_custom_border_color = true,
@ -1412,6 +1414,32 @@ nvk_GetPhysicalDeviceQueueFamilyProperties2(
}
}
static const VkTimeDomainKHR nvk_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
nvk_GetPhysicalDeviceCalibrateableTimeDomainsKHR(
VkPhysicalDevice physicalDevice,
uint32_t *pTimeDomainCount,
VkTimeDomainKHR *pTimeDomains)
{
VK_OUTARRAY_MAKE_TYPED(VkTimeDomainKHR, out, pTimeDomains, pTimeDomainCount);
for (int d = 0; d < ARRAY_SIZE(nvk_time_domains); d++) {
vk_outarray_append_typed(VkTimeDomainKHR, &out, i) {
*i = nvk_time_domains[d];
}
}
return vk_outarray_status(&out);
}
VKAPI_ATTR void VKAPI_CALL
nvk_GetPhysicalDeviceMultisamplePropertiesEXT(
VkPhysicalDevice physicalDevice,

View file

@ -445,3 +445,13 @@ nouveau_ws_device_vram_used(struct nouveau_ws_device *device)
return used;
}
uint64_t
nouveau_ws_device_timestamp(struct nouveau_ws_device *device)
{
uint64_t timestamp = 0;
if (nouveau_ws_param(device->fd, NOUVEAU_GETPARAM_PTIMER_TIME, &timestamp))
return 0;
return timestamp;
}

View file

@ -65,6 +65,7 @@ struct nouveau_ws_device *nouveau_ws_device_new(struct _drmDevice *drm_device);
void nouveau_ws_device_destroy(struct nouveau_ws_device *);
uint64_t nouveau_ws_device_vram_used(struct nouveau_ws_device *);
uint64_t nouveau_ws_device_timestamp(struct nouveau_ws_device *device);
#ifdef __cplusplus
}