11use ash:: vk;
2+ use ash:: vk:: PhysicalDeviceProperties2 ;
3+ use ash:: vk:: PhysicalDeviceShaderCoreProperties2AMD ;
4+ use ash:: vk:: PhysicalDeviceShaderCorePropertiesAMD ;
5+ use ash:: vk:: PhysicalDeviceShaderSMBuiltinsPropertiesNV ;
26use ash:: Instance ;
37use std:: ffi:: CStr ;
48
@@ -39,10 +43,14 @@ pub struct GPUCharacteristics {
3943 // NVIDIA-specific properties.
4044 pub streaming_multiprocessors : Option < u32 > ,
4145 pub warps_per_sm : Option < u32 > ,
42- // General device limits (useful for performance and capability queries) .
46+ // General device limits.
4347 pub max_image_dimension_2d : u32 ,
4448 pub max_compute_shared_memory_size : u32 ,
4549 pub max_compute_work_group_invocations : u32 ,
50+ // New feature flags.
51+ pub dedicated_transfer_queue : bool ,
52+ pub dedicated_async_compute_queue : bool ,
53+ pub supports_ray_tracing : bool ,
4654}
4755
4856impl PhysicalDevice {
@@ -56,8 +64,8 @@ impl PhysicalDevice {
5664 // Query additional driver properties.
5765 let mut driver_properties: vk:: PhysicalDeviceDriverProperties =
5866 vk:: PhysicalDeviceDriverProperties :: default ( ) ;
59- let mut properties2: vk :: PhysicalDeviceProperties2 =
60- vk :: PhysicalDeviceProperties2 :: default ( ) . push_next ( & mut driver_properties) ;
67+ let mut properties2: PhysicalDeviceProperties2 =
68+ PhysicalDeviceProperties2 :: default ( ) . push_next ( & mut driver_properties) ;
6169 unsafe {
6270 instance. get_physical_device_properties2 ( physical_device, & mut properties2) ;
6371 }
@@ -111,6 +119,37 @@ impl PhysicalDevice {
111119 f32:: NAN
112120 } ;
113121
122+ // Query queue family properties.
123+ let queue_families =
124+ unsafe { instance. get_physical_device_queue_family_properties ( physical_device) } ;
125+ let mut dedicated_transfer_queue = false ;
126+ let mut dedicated_async_compute_queue = false ;
127+ for qf in queue_families. iter ( ) {
128+ let flags = qf. queue_flags ;
129+ if flags. contains ( vk:: QueueFlags :: TRANSFER )
130+ && !( flags. contains ( vk:: QueueFlags :: GRAPHICS )
131+ || flags. contains ( vk:: QueueFlags :: COMPUTE ) )
132+ {
133+ dedicated_transfer_queue = true ;
134+ }
135+ if flags. contains ( vk:: QueueFlags :: COMPUTE ) && !flags. contains ( vk:: QueueFlags :: GRAPHICS )
136+ {
137+ dedicated_async_compute_queue = true ;
138+ }
139+ }
140+
141+ // Check for ray tracing support via device extensions.
142+ let extensions = unsafe {
143+ instance
144+ . enumerate_device_extension_properties ( physical_device)
145+ . unwrap_or_default ( )
146+ } ;
147+ let supports_ray_tracing = extensions. iter ( ) . any ( |ext| {
148+ let ext_name = unsafe { CStr :: from_ptr ( ext. extension_name . as_ptr ( ) ) } ;
149+ ext_name. to_str ( ) . unwrap_or ( "" ) == "VK_KHR_ray_tracing_pipeline"
150+ || ext_name. to_str ( ) . unwrap_or ( "" ) == "VK_NV_ray_tracing"
151+ } ) ;
152+
114153 let mut characteristics = GPUCharacteristics {
115154 memory_pressure,
116155 // Vendor-specific fields start as None.
@@ -127,16 +166,18 @@ impl PhysicalDevice {
127166 max_image_dimension_2d : limits. max_image_dimension2_d ,
128167 max_compute_shared_memory_size : limits. max_compute_shared_memory_size ,
129168 max_compute_work_group_invocations : limits. max_compute_work_group_invocations ,
169+ // New features:
170+ dedicated_transfer_queue,
171+ dedicated_async_compute_queue,
172+ supports_ray_tracing,
130173 } ;
131174
132175 // Query vendor-specific properties.
133176 match vendor {
134177 Vendor :: AMD => {
135- let mut shader_core_properties =
136- vk:: PhysicalDeviceShaderCorePropertiesAMD :: default ( ) ;
137- let mut shader_core_properties2 =
138- vk:: PhysicalDeviceShaderCoreProperties2AMD :: default ( ) ;
139- let mut amd_properties2 = vk:: PhysicalDeviceProperties2 :: default ( )
178+ let mut shader_core_properties = PhysicalDeviceShaderCorePropertiesAMD :: default ( ) ;
179+ let mut shader_core_properties2 = PhysicalDeviceShaderCoreProperties2AMD :: default ( ) ;
180+ let mut amd_properties2 = PhysicalDeviceProperties2 :: default ( )
140181 . push_next ( & mut shader_core_properties)
141182 . push_next ( & mut shader_core_properties2) ;
142183 unsafe {
@@ -159,9 +200,9 @@ impl PhysicalDevice {
159200 characteristics. wavefront_size = Some ( shader_core_properties. wavefront_size ) ;
160201 }
161202 Vendor :: Nvidia => {
162- let mut sm_builtins = vk :: PhysicalDeviceShaderSMBuiltinsPropertiesNV :: default ( ) ;
203+ let mut sm_builtins = PhysicalDeviceShaderSMBuiltinsPropertiesNV :: default ( ) ;
163204 let mut nv_properties2 =
164- vk :: PhysicalDeviceProperties2 :: default ( ) . push_next ( & mut sm_builtins) ;
205+ PhysicalDeviceProperties2 :: default ( ) . push_next ( & mut sm_builtins) ;
165206 unsafe {
166207 instance. get_physical_device_properties2 ( physical_device, & mut nv_properties2) ;
167208 }
@@ -284,7 +325,6 @@ mod tests {
284325 max_image_dimension2_d : 8192 ,
285326 max_compute_shared_memory_size : 16384 ,
286327 max_compute_work_group_invocations : 1024 ,
287- // Other fields can use defaults.
288328 ..Default :: default ( )
289329 } ;
290330
@@ -303,6 +343,9 @@ mod tests {
303343 max_image_dimension_2d : limits. max_image_dimension2_d ,
304344 max_compute_shared_memory_size : limits. max_compute_shared_memory_size ,
305345 max_compute_work_group_invocations : limits. max_compute_work_group_invocations ,
346+ dedicated_transfer_queue : false ,
347+ dedicated_async_compute_queue : false ,
348+ supports_ray_tracing : false ,
306349 } ;
307350
308351 assert_eq ! ( characteristics. max_image_dimension_2d, 8192 ) ;
0 commit comments