1 use crate::prelude::*;
2 use crate::vk;
3 use crate::{Entry, Instance};
4 use std::ffi::CStr;
5 use std::mem;
6 use std::ptr;
7 
8 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_performance_query.html>
9 #[derive(Clone)]
10 pub struct PerformanceQuery {
11     handle: vk::Instance,
12     fp: vk::KhrPerformanceQueryFn,
13 }
14 
15 impl PerformanceQuery {
new(entry: &Entry, instance: &Instance) -> Self16     pub fn new(entry: &Entry, instance: &Instance) -> Self {
17         let handle = instance.handle();
18         let fp = vk::KhrPerformanceQueryFn::load(|name| unsafe {
19             mem::transmute(entry.get_instance_proc_addr(handle, name.as_ptr()))
20         });
21         Self { handle, fp }
22     }
23 
24     /// Retrieve the number of elements to pass to [`enumerate_physical_device_queue_family_performance_query_counters()`][Self::enumerate_physical_device_queue_family_performance_query_counters()]
25     #[inline]
enumerate_physical_device_queue_family_performance_query_counters_len( &self, physical_device: vk::PhysicalDevice, queue_family_index: u32, ) -> VkResult<usize>26     pub unsafe fn enumerate_physical_device_queue_family_performance_query_counters_len(
27         &self,
28         physical_device: vk::PhysicalDevice,
29         queue_family_index: u32,
30     ) -> VkResult<usize> {
31         let mut count = 0;
32         (self
33             .fp
34             .enumerate_physical_device_queue_family_performance_query_counters_khr)(
35             physical_device,
36             queue_family_index,
37             &mut count,
38             ptr::null_mut(),
39             ptr::null_mut(),
40         )
41         .result_with_success(count as usize)
42     }
43 
44     /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR.html>
45     ///
46     /// Call [`enumerate_physical_device_queue_family_performance_query_counters_len()`][Self::enumerate_physical_device_queue_family_performance_query_counters_len()] to query the number of elements to pass to `out_counters` and `out_counter_descriptions`.
47     /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer.
48     #[inline]
enumerate_physical_device_queue_family_performance_query_counters( &self, physical_device: vk::PhysicalDevice, queue_family_index: u32, out_counters: &mut [vk::PerformanceCounterKHR], out_counter_descriptions: &mut [vk::PerformanceCounterDescriptionKHR], ) -> VkResult<()>49     pub unsafe fn enumerate_physical_device_queue_family_performance_query_counters(
50         &self,
51         physical_device: vk::PhysicalDevice,
52         queue_family_index: u32,
53         out_counters: &mut [vk::PerformanceCounterKHR],
54         out_counter_descriptions: &mut [vk::PerformanceCounterDescriptionKHR],
55     ) -> VkResult<()> {
56         assert_eq!(out_counters.len(), out_counter_descriptions.len());
57         let mut count = out_counters.len() as u32;
58         (self
59             .fp
60             .enumerate_physical_device_queue_family_performance_query_counters_khr)(
61             physical_device,
62             queue_family_index,
63             &mut count,
64             out_counters.as_mut_ptr(),
65             out_counter_descriptions.as_mut_ptr(),
66         )
67         .result()?;
68         assert_eq!(count as usize, out_counters.len());
69         assert_eq!(count as usize, out_counter_descriptions.len());
70         Ok(())
71     }
72 
73     /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR.html>
74     #[inline]
get_physical_device_queue_family_performance_query_passes( &self, physical_device: vk::PhysicalDevice, performance_query_create_info: &vk::QueryPoolPerformanceCreateInfoKHR, ) -> u3275     pub unsafe fn get_physical_device_queue_family_performance_query_passes(
76         &self,
77         physical_device: vk::PhysicalDevice,
78         performance_query_create_info: &vk::QueryPoolPerformanceCreateInfoKHR,
79     ) -> u32 {
80         let mut num_passes = 0;
81         (self
82             .fp
83             .get_physical_device_queue_family_performance_query_passes_khr)(
84             physical_device,
85             performance_query_create_info,
86             &mut num_passes,
87         );
88         num_passes
89     }
90 
91     /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkAcquireProfilingLockKHR.html>
92     #[inline]
acquire_profiling_lock( &self, device: vk::Device, info: &vk::AcquireProfilingLockInfoKHR, ) -> VkResult<()>93     pub unsafe fn acquire_profiling_lock(
94         &self,
95         device: vk::Device,
96         info: &vk::AcquireProfilingLockInfoKHR,
97     ) -> VkResult<()> {
98         (self.fp.acquire_profiling_lock_khr)(device, info).result()
99     }
100 
101     /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkReleaseProfilingLockKHR.html>
102     #[inline]
release_profiling_lock(&self, device: vk::Device)103     pub unsafe fn release_profiling_lock(&self, device: vk::Device) {
104         (self.fp.release_profiling_lock_khr)(device)
105     }
106 
107     #[inline]
name() -> &'static CStr108     pub const fn name() -> &'static CStr {
109         vk::KhrPerformanceQueryFn::name()
110     }
111 
112     #[inline]
fp(&self) -> &vk::KhrPerformanceQueryFn113     pub fn fp(&self) -> &vk::KhrPerformanceQueryFn {
114         &self.fp
115     }
116 
117     #[inline]
instance(&self) -> vk::Instance118     pub fn instance(&self) -> vk::Instance {
119         self.handle
120     }
121 }
122