ash/extensions/experimental/
amd.rs

1#![allow(clippy::unreadable_literal)]
2
3/*
4 ***********************************************************************************************************************
5 *
6 *  Copyright (c) 2014-2019 Advanced Micro Devices, Inc. All Rights Reserved.
7 *
8 *  Permission is hereby granted, free of charge, to any person obtaining a copy
9 *  of this software and associated documentation files (the "Software"), to deal
10 *  in the Software without restriction, including without limitation the rights
11 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 *  copies of the Software, and to permit persons to whom the Software is
13 *  furnished to do so, subject to the following conditions:
14 *
15 *  The above copyright notice and this permission notice shall be included in all
16 *  copies or substantial portions of the Software.
17 *
18 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 *  SOFTWARE.
25 *
26 **********************************************************************************************************************/
27
28#[cfg(feature = "debug")]
29use crate::prelude::debug_flags;
30use crate::vk::*;
31
32use std::fmt;
33use std::os::raw::*;
34
35// Extension: `VK_AMD_gpa_interface`
36
37#[repr(transparent)]
38#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct GpaSqShaderStageFlags(pub(crate) Flags);
40vk_bitflags_wrapped!(GpaSqShaderStageFlags, Flags);
41#[cfg(feature = "debug")]
42impl fmt::Debug for GpaSqShaderStageFlags {
43    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44        const KNOWN: &[(Flags, &str)] = &[
45            (GpaSqShaderStageFlags::PS.0, "PS"),
46            (GpaSqShaderStageFlags::VS.0, "VS"),
47            (GpaSqShaderStageFlags::GS.0, "GS"),
48            (GpaSqShaderStageFlags::ES.0, "ES"),
49            (GpaSqShaderStageFlags::HS.0, "HS"),
50            (GpaSqShaderStageFlags::LS.0, "LS"),
51            (GpaSqShaderStageFlags::CS.0, "CS"),
52        ];
53        debug_flags(f, KNOWN, self.0)
54    }
55}
56impl GpaSqShaderStageFlags {
57    pub const PS: Self = Self(0b1);
58    pub const VS: Self = Self(0b10);
59    pub const GS: Self = Self(0b100);
60    pub const ES: Self = Self(0b1000);
61    pub const HS: Self = Self(0b10000);
62    pub const LS: Self = Self(0b100000);
63    pub const CS: Self = Self(0b1000000);
64}
65
66impl StructureType {
67    pub const PHYSICAL_DEVICE_GPA_FEATURES_AMD: Self = Self(1000133000);
68    pub const PHYSICAL_DEVICE_GPA_PROPERTIES_AMD: Self = Self(1000133001);
69    pub const GPA_SAMPLE_BEGIN_INFO_AMD: Self = Self(1000133002);
70    pub const GPA_SESSION_CREATE_INFO_AMD: Self = Self(1000133003);
71    pub const GPA_DEVICE_CLOCK_MODE_INFO_AMD: Self = Self(1000133004);
72}
73
74#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
75#[cfg_attr(feature = "debug", derive(Debug))]
76#[repr(transparent)]
77pub struct GpaDeviceClockModeAmd(pub(crate) i32);
78impl GpaDeviceClockModeAmd {
79    pub fn from_raw(x: i32) -> Self {
80        Self(x)
81    }
82    pub fn as_raw(self) -> i32 {
83        self.0
84    }
85}
86impl GpaDeviceClockModeAmd {
87    pub const DEFAULT: Self = Self(0);
88    pub const QUERY: Self = Self(1);
89    pub const PROFILING: Self = Self(2);
90    pub const MIN_MEMORY: Self = Self(3);
91    pub const MIN_ENGINE: Self = Self(4);
92    pub const PEAK: Self = Self(5);
93}
94
95#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
96#[cfg_attr(feature = "debug", derive(Debug))]
97#[repr(transparent)]
98pub struct GpaPerfBlockAmd(pub(crate) i32);
99impl GpaPerfBlockAmd {
100    pub fn from_raw(x: i32) -> Self {
101        Self(x)
102    }
103    pub fn as_raw(self) -> i32 {
104        self.0
105    }
106}
107impl GpaPerfBlockAmd {
108    pub const CPF: Self = Self(0);
109    pub const IA: Self = Self(1);
110    pub const VGT: Self = Self(2);
111    pub const PA: Self = Self(3);
112    pub const SC: Self = Self(4);
113    pub const SPI: Self = Self(5);
114    pub const SQ: Self = Self(6);
115    pub const SX: Self = Self(7);
116    pub const TA: Self = Self(8);
117    pub const TD: Self = Self(9);
118    pub const TCP: Self = Self(10);
119    pub const TCC: Self = Self(11);
120    pub const TCA: Self = Self(12);
121    pub const DB: Self = Self(13);
122    pub const CB: Self = Self(14);
123    pub const GDS: Self = Self(15);
124    pub const SRBM: Self = Self(16);
125    pub const GRBM: Self = Self(17);
126    pub const GRBM_SE: Self = Self(18);
127    pub const RLC: Self = Self(19);
128    pub const DMA: Self = Self(20);
129    pub const MC: Self = Self(21);
130    pub const CPG: Self = Self(22);
131    pub const CPC: Self = Self(23);
132    pub const WD: Self = Self(24);
133    pub const TCS: Self = Self(25);
134    pub const ATC: Self = Self(26);
135    pub const ATC_L2: Self = Self(27);
136    pub const MC_VM_L2: Self = Self(28);
137    pub const EA: Self = Self(29);
138    pub const RPB: Self = Self(30);
139    pub const RMI: Self = Self(31);
140}
141
142#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
143#[cfg_attr(feature = "debug", derive(Debug))]
144#[repr(transparent)]
145pub struct GpaSampleTypeAmd(pub(crate) i32);
146impl GpaSampleTypeAmd {
147    pub fn from_raw(x: i32) -> Self {
148        Self(x)
149    }
150    pub fn as_raw(self) -> i32 {
151        self.0
152    }
153}
154impl GpaSampleTypeAmd {
155    pub const CUMULATIVE: Self = Self(0);
156    pub const TRACE: Self = Self(1);
157    pub const TIMING: Self = Self(2);
158}
159
160handle_nondispatchable!(GpaSessionAmd, UNKNOWN);
161
162#[repr(C)]
163#[derive(Copy, Clone)]
164#[cfg_attr(feature = "debug", derive(Debug))]
165pub struct GpaSessionCreateInfoAmd {
166    pub s_type: StructureType,
167    pub p_next: *const c_void,
168    pub secondary_copy_source: GpaSessionAmd,
169}
170
171#[repr(C)]
172#[derive(Copy, Clone)]
173#[cfg_attr(feature = "debug", derive(Debug))]
174pub struct GpaPerfBlockPropertiesAmd {
175    pub block_type: GpaPerfBlockAmd,
176    pub flags: Flags,
177    pub instance_count: u32,
178    pub max_event_id: u32,
179    pub max_global_only_counters: u32,
180    pub max_global_shared_counters: u32,
181    pub max_streaming_counters: u32,
182}
183
184#[repr(C)]
185#[derive(Copy, Clone)]
186#[cfg_attr(feature = "debug", derive(Debug))]
187pub struct PhysicalDeviceGpaFeaturesAmd {
188    pub s_type: StructureType,
189    pub p_next: *const c_void,
190    pub perf_counters: Bool32,
191    pub streaming_perf_counters: Bool32,
192    pub sq_thread_tracing: Bool32,
193    pub clock_modes: Bool32,
194}
195
196#[repr(C)]
197#[derive(Copy, Clone)]
198#[cfg_attr(feature = "debug", derive(Debug))]
199pub struct PhysicalDeviceGpaPropertiesAmd {
200    pub s_type: StructureType,
201    pub p_next: *const c_void,
202    pub flags: Flags,
203    pub max_sqtt_se_buffer_size: DeviceSize,
204    pub shader_engine_count: u32,
205    pub perf_block_count: u32,
206    pub p_perf_block_properties: *mut GpaPerfBlockPropertiesAmd,
207}
208
209impl ::std::default::Default for PhysicalDeviceGpaPropertiesAmd {
210    fn default() -> Self {
211        Self {
212            s_type: StructureType::PHYSICAL_DEVICE_GPA_PROPERTIES_AMD,
213            p_next: ::std::ptr::null_mut(),
214            flags: Flags::default(),
215            max_sqtt_se_buffer_size: DeviceSize::default(),
216            shader_engine_count: u32::default(),
217            perf_block_count: u32::default(),
218            p_perf_block_properties: ::std::ptr::null_mut(),
219        }
220    }
221}
222impl PhysicalDeviceGpaPropertiesAmd {
223    pub fn builder<'a>() -> PhysicalDeviceGpaPropertiesAmdBuilder<'a> {
224        PhysicalDeviceGpaPropertiesAmdBuilder {
225            inner: Self::default(),
226            marker: ::std::marker::PhantomData,
227        }
228    }
229}
230pub struct PhysicalDeviceGpaPropertiesAmdBuilder<'a> {
231    inner: PhysicalDeviceGpaPropertiesAmd,
232    marker: ::std::marker::PhantomData<&'a ()>,
233}
234pub unsafe trait ExtendsPhysicalDeviceGpaPropertiesAmd {}
235unsafe impl ExtendsPhysicalDeviceProperties2 for PhysicalDeviceGpaPropertiesAmd {}
236impl<'a> ::std::ops::Deref for PhysicalDeviceGpaPropertiesAmdBuilder<'a> {
237    type Target = PhysicalDeviceGpaPropertiesAmd;
238    fn deref(&self) -> &Self::Target {
239        &self.inner
240    }
241}
242impl<'a> PhysicalDeviceGpaPropertiesAmdBuilder<'a> {
243    pub fn push_next<T>(mut self, next: &'a mut T) -> PhysicalDeviceGpaPropertiesAmdBuilder<'a>
244    where
245        T: ExtendsPhysicalDeviceGpaPropertiesAmd,
246    {
247        unsafe {
248            let next_ptr = <*const T>::cast(next);
249            let last_next = ptr_chain_iter(next).last().unwrap();
250            (*last_next).p_next = self.inner.p_next as _;
251            self.inner.p_next = next_ptr;
252        }
253        self
254    }
255    pub fn build(self) -> PhysicalDeviceGpaPropertiesAmd {
256        self.inner
257    }
258}
259
260#[repr(C)]
261#[derive(Copy, Clone)]
262#[cfg_attr(feature = "debug", derive(Debug))]
263pub struct GpaPerfCounterAmd {
264    pub block_type: GpaPerfBlockAmd,
265    pub block_instance: u32,
266    pub event_id: u32,
267}
268
269#[repr(C)]
270#[derive(Copy, Clone)]
271#[cfg_attr(feature = "debug", derive(Debug))]
272pub struct GpaSampleBeginInfoAmd {
273    pub s_type: StructureType,
274    pub p_next: *const c_void,
275    pub sample_type: GpaSampleTypeAmd,
276    pub sample_internal_operations: Bool32,
277    pub cache_flush_on_counter_collection: Bool32,
278    pub sq_shader_mask_enable: Bool32,
279    pub sq_shader_mask: GpaSqShaderStageFlags,
280    pub perf_counter_count: u32,
281    pub p_perf_counters: *const GpaPerfCounterAmd,
282    pub streaming_perf_trace_sample_interval: u32,
283    pub perf_counter_device_memory_limit: DeviceSize,
284    pub sq_thread_trace_enable: Bool32,
285    pub sq_thread_trace_suppress_instruction_tokens: Bool32,
286    pub sq_thread_trace_device_memory_limit: DeviceSize,
287    pub timing_pre_sample: PipelineStageFlags,
288    pub timing_post_sample: PipelineStageFlags,
289}
290
291#[repr(C)]
292#[derive(Copy, Clone)]
293#[cfg_attr(feature = "debug", derive(Debug))]
294pub struct GpaDeviceClockModeInfoAmd {
295    pub s_type: StructureType,
296    pub p_next: *const c_void,
297    pub clock_mode: GpaDeviceClockModeAmd,
298    pub memory_clock_ratio_to_peak: f32,
299    pub engine_clock_ratio_to_peak: f32,
300}
301
302#[allow(non_camel_case_types)]
303pub type PFN_vkCreateGpaSessionAMD = extern "system" fn(
304    device: Device,
305    p_create_info: *const GpaSessionCreateInfoAmd,
306    p_allocator: *const AllocationCallbacks,
307    p_gpa_session: *mut GpaSessionAmd,
308) -> Result;
309
310#[allow(non_camel_case_types)]
311pub type PFN_vkDestroyGpaSessionAMD = extern "system" fn(
312    device: Device,
313    gpa_session: GpaSessionAmd,
314    p_allocator: *const AllocationCallbacks,
315) -> c_void;
316
317#[allow(non_camel_case_types)]
318pub type PFN_vkSetGpaDeviceClockModeAMD =
319    extern "system" fn(device: Device, p_info: *mut GpaDeviceClockModeInfoAmd) -> Result;
320
321#[allow(non_camel_case_types)]
322pub type PFN_vkCmdBeginGpaSessionAMD =
323    extern "system" fn(commandBuffer: CommandBuffer, gpa_session: GpaSessionAmd) -> Result;
324
325#[allow(non_camel_case_types)]
326pub type PFN_vkCmdEndGpaSessionAMD =
327    extern "system" fn(commandBuffer: CommandBuffer, gpa_session: GpaSessionAmd) -> Result;
328
329#[allow(non_camel_case_types)]
330pub type PFN_vkCmdBeginGpaSampleAMD = extern "system" fn(
331    commandBuffer: CommandBuffer,
332    gpa_session: GpaSessionAmd,
333    p_gpa_sample_begin_info: *const GpaSampleBeginInfoAmd,
334    p_sample_id: *mut u32,
335) -> Result;
336
337#[allow(non_camel_case_types)]
338pub type PFN_vkCmdEndGpaSampleAMD = extern "system" fn(
339    commandBuffer: CommandBuffer,
340    gpa_session: GpaSessionAmd,
341    sample_id: u32,
342) -> c_void;
343
344#[allow(non_camel_case_types)]
345pub type PFN_vkGetGpaSessionStatusAMD =
346    extern "system" fn(device: Device, gpaSession: GpaSessionAmd) -> Result;
347
348#[allow(non_camel_case_types)]
349pub type PFN_vkGetGpaSessionResultsAMD = extern "system" fn(
350    device: Device,
351    gpaSession: GpaSessionAmd,
352    sample_id: u32,
353    p_size_in_bytes: *mut usize,
354    p_data: *mut c_void,
355) -> Result;
356
357#[allow(non_camel_case_types)]
358pub type PFN_vkResetGpaSessionAMD =
359    extern "system" fn(device: Device, gpaSession: GpaSessionAmd) -> Result;
360
361#[allow(non_camel_case_types)]
362pub type PFN_vkCmdCopyGpaSessionResultsAMD =
363    extern "system" fn(commandBuffer: CommandBuffer, gpaSession: GpaSessionAmd) -> c_void;
364
365pub struct AmdGpaInterfaceFn {
366    pub create_gpa_session: PFN_vkCreateGpaSessionAMD,
367    pub destroy_gpa_session: PFN_vkDestroyGpaSessionAMD,
368    pub set_gpa_device_clock_mode: PFN_vkSetGpaDeviceClockModeAMD,
369    pub cmd_begin_gpa_session: PFN_vkCmdBeginGpaSessionAMD,
370    pub cmd_end_gpa_session: PFN_vkCmdEndGpaSessionAMD,
371    pub cmd_begin_gpa_sample: PFN_vkCmdBeginGpaSampleAMD,
372    pub cmd_end_gpa_sample: PFN_vkCmdEndGpaSampleAMD,
373    pub get_gpa_session_status: PFN_vkGetGpaSessionStatusAMD,
374    pub get_gpa_session_results: PFN_vkGetGpaSessionResultsAMD,
375    pub reset_gpa_session: PFN_vkResetGpaSessionAMD,
376    pub cmd_copy_gpa_session_results: PFN_vkCmdCopyGpaSessionResultsAMD,
377}
378unsafe impl Send for AmdGpaInterfaceFn {}
379unsafe impl Sync for AmdGpaInterfaceFn {}
380
381impl ::std::clone::Clone for AmdGpaInterfaceFn {
382    fn clone(&self) -> Self {
383        Self {
384            create_gpa_session: self.create_gpa_session,
385            destroy_gpa_session: self.destroy_gpa_session,
386            set_gpa_device_clock_mode: self.set_gpa_device_clock_mode,
387            cmd_begin_gpa_session: self.cmd_begin_gpa_session,
388            cmd_end_gpa_session: self.cmd_end_gpa_session,
389            cmd_begin_gpa_sample: self.cmd_begin_gpa_sample,
390            cmd_end_gpa_sample: self.cmd_end_gpa_sample,
391            get_gpa_session_status: self.get_gpa_session_status,
392            get_gpa_session_results: self.get_gpa_session_results,
393            reset_gpa_session: self.reset_gpa_session,
394            cmd_copy_gpa_session_results: self.cmd_copy_gpa_session_results,
395        }
396    }
397}
398
399impl AmdGpaInterfaceFn {
400    pub fn load<F>(mut _f: F) -> Self
401    where
402        F: FnMut(&::std::ffi::CStr) -> *const c_void,
403    {
404        Self {
405            create_gpa_session: unsafe {
406                extern "system" fn create_gpa_session_amd(
407                    _device: Device,
408                    _p_create_info: *const GpaSessionCreateInfoAmd,
409                    _p_allocator: *const AllocationCallbacks,
410                    _p_gpa_session: *mut GpaSessionAmd,
411                ) -> Result {
412                    panic!(concat!(
413                        "Unable to load ",
414                        stringify!(create_gpa_session_amd)
415                    ))
416                }
417                let cname =
418                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkCreateGpaSessionAMD\0");
419                let val = _f(cname);
420                if val.is_null() {
421                    create_gpa_session_amd
422                } else {
423                    ::std::mem::transmute(val)
424                }
425            },
426            destroy_gpa_session: unsafe {
427                extern "system" fn destroy_gpa_session_amd(
428                    _device: Device,
429                    _gpa_session: GpaSessionAmd,
430                    _p_allocator: *const AllocationCallbacks,
431                ) -> c_void {
432                    panic!(concat!(
433                        "Unable to load ",
434                        stringify!(destroy_gpa_session_amd)
435                    ))
436                }
437                let cname =
438                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkDestroyGpaSessionAMD\0");
439                let val = _f(cname);
440                if val.is_null() {
441                    destroy_gpa_session_amd
442                } else {
443                    ::std::mem::transmute(val)
444                }
445            },
446            set_gpa_device_clock_mode: unsafe {
447                extern "system" fn set_gpa_device_clock_mode_amd(
448                    _device: Device,
449                    _p_info: *mut GpaDeviceClockModeInfoAmd,
450                ) -> Result {
451                    panic!(concat!(
452                        "Unable to load ",
453                        stringify!(set_gpa_device_clock_mode_amd)
454                    ))
455                }
456                let cname = ::std::ffi::CStr::from_bytes_with_nul_unchecked(
457                    b"vkSetGpaDeviceClockModeAMD\0",
458                );
459                let val = _f(cname);
460                if val.is_null() {
461                    set_gpa_device_clock_mode_amd
462                } else {
463                    ::std::mem::transmute(val)
464                }
465            },
466            cmd_begin_gpa_session: unsafe {
467                extern "system" fn cmd_begin_gpa_session_amd(
468                    _command_buffer: CommandBuffer,
469                    _gpa_session: GpaSessionAmd,
470                ) -> Result {
471                    panic!(concat!(
472                        "Unable to load ",
473                        stringify!(cmd_begin_gpa_session_amd)
474                    ))
475                }
476                let cname =
477                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkCmdBeginGpaSessionAMD\0");
478                let val = _f(cname);
479                if val.is_null() {
480                    cmd_begin_gpa_session_amd
481                } else {
482                    ::std::mem::transmute(val)
483                }
484            },
485            cmd_end_gpa_session: unsafe {
486                extern "system" fn cmd_end_gpa_session_amd(
487                    _command_buffer: CommandBuffer,
488                    _gpa_session: GpaSessionAmd,
489                ) -> Result {
490                    panic!(concat!(
491                        "Unable to load ",
492                        stringify!(cmd_end_gpa_session_amd)
493                    ))
494                }
495                let cname =
496                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkCmdEndGpaSessionAMD\0");
497                let val = _f(cname);
498                if val.is_null() {
499                    cmd_end_gpa_session_amd
500                } else {
501                    ::std::mem::transmute(val)
502                }
503            },
504            cmd_begin_gpa_sample: unsafe {
505                extern "system" fn cmd_begin_gpa_sample_amd(
506                    _command_buffer: CommandBuffer,
507                    _gpa_session: GpaSessionAmd,
508                    _p_gpa_sample_begin_info: *const GpaSampleBeginInfoAmd,
509                    _p_sample_id: *mut u32,
510                ) -> Result {
511                    panic!(concat!(
512                        "Unable to load ",
513                        stringify!(cmd_begin_gpa_sample_amd)
514                    ))
515                }
516                let cname =
517                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkCmdBeginGpaSampleAMD\0");
518                let val = _f(cname);
519                if val.is_null() {
520                    cmd_begin_gpa_sample_amd
521                } else {
522                    ::std::mem::transmute(val)
523                }
524            },
525            cmd_end_gpa_sample: unsafe {
526                extern "system" fn cmd_end_gpa_sample_amd(
527                    _command_buffer: CommandBuffer,
528                    _gpa_session: GpaSessionAmd,
529                    _sample_id: u32,
530                ) -> c_void {
531                    panic!(concat!(
532                        "Unable to load ",
533                        stringify!(cmd_end_gpa_sample_amd)
534                    ))
535                }
536                let cname =
537                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkCmdEndGpaSampleAMD\0");
538                let val = _f(cname);
539                if val.is_null() {
540                    cmd_end_gpa_sample_amd
541                } else {
542                    ::std::mem::transmute(val)
543                }
544            },
545            get_gpa_session_status: unsafe {
546                extern "system" fn get_gpa_session_status_amd(
547                    _device: Device,
548                    _gpa_session: GpaSessionAmd,
549                ) -> Result {
550                    panic!(concat!(
551                        "Unable to load ",
552                        stringify!(get_gpa_session_status_amd)
553                    ))
554                }
555                let cname =
556                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkGetGpaSessionStatusAMD\0");
557                let val = _f(cname);
558                if val.is_null() {
559                    get_gpa_session_status_amd
560                } else {
561                    ::std::mem::transmute(val)
562                }
563            },
564            get_gpa_session_results: unsafe {
565                extern "system" fn get_gpa_session_results_amd(
566                    _device: Device,
567                    _gpa_session: GpaSessionAmd,
568                    _sample_id: u32,
569                    _p_size_in_bytes: *mut usize,
570                    _p_data: *mut c_void,
571                ) -> Result {
572                    panic!(concat!(
573                        "Unable to load ",
574                        stringify!(get_gpa_session_results_amd)
575                    ))
576                }
577                let cname =
578                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkGetGpaSessionResultsAMD\0");
579                let val = _f(cname);
580                if val.is_null() {
581                    get_gpa_session_results_amd
582                } else {
583                    ::std::mem::transmute(val)
584                }
585            },
586            reset_gpa_session: unsafe {
587                extern "system" fn reset_gpa_session_amd(
588                    _device: Device,
589                    _gpa_session: GpaSessionAmd,
590                ) -> Result {
591                    panic!(concat!(
592                        "Unable to load ",
593                        stringify!(reset_gpa_session_amd)
594                    ))
595                }
596                let cname =
597                    ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkCmdEndGpaSampleAMD\0");
598                let val = _f(cname);
599                if val.is_null() {
600                    reset_gpa_session_amd
601                } else {
602                    ::std::mem::transmute(val)
603                }
604            },
605            cmd_copy_gpa_session_results: unsafe {
606                extern "system" fn cmd_copy_gpa_session_results_amd(
607                    _command_buffer: CommandBuffer,
608                    _gpa_session: GpaSessionAmd,
609                ) -> c_void {
610                    panic!(concat!(
611                        "Unable to load ",
612                        stringify!(cmd_copy_gpa_session_results_amd)
613                    ))
614                }
615                let cname = ::std::ffi::CStr::from_bytes_with_nul_unchecked(
616                    b"vkCmdCopyGpaSessionResultsAMD\0",
617                );
618                let val = _f(cname);
619                if val.is_null() {
620                    cmd_copy_gpa_session_results_amd
621                } else {
622                    ::std::mem::transmute(val)
623                }
624            },
625        }
626    }
627    pub unsafe fn create_gpa_session(
628        &self,
629        device: Device,
630        create_info: *const GpaSessionCreateInfoAmd,
631        allocator: *const AllocationCallbacks,
632        gpa_session: *mut GpaSessionAmd,
633    ) -> Result {
634        (self.create_gpa_session)(device, create_info, allocator, gpa_session)
635    }
636    pub unsafe fn destroy_gpa_session(
637        &self,
638        device: Device,
639        gpa_session: GpaSessionAmd,
640        allocator: *const AllocationCallbacks,
641    ) -> c_void {
642        (self.destroy_gpa_session)(device, gpa_session, allocator)
643    }
644}
645
646// Extension: `VK_AMD_wave_limits`
647
648impl StructureType {
649    pub const WAVE_LIMIT_AMD: Self = Self(1000045000);
650    pub const PHYSICAL_DEVICE_WAVE_LIMIT_PROPERTIES_AMD: Self = Self(1000045001);
651}
652
653#[repr(C)]
654#[derive(Copy, Clone)]
655#[cfg_attr(feature = "debug", derive(Debug))]
656pub struct PhysicalDeviceWaveLimitPropertiesAmd {
657    pub s_type: StructureType,
658    pub p_next: *const c_void,
659    pub cu_count: u32,
660    pub max_waves_per_cu: u32,
661}
662
663impl ::std::default::Default for PhysicalDeviceWaveLimitPropertiesAmd {
664    fn default() -> Self {
665        Self {
666            s_type: StructureType::PHYSICAL_DEVICE_WAVE_LIMIT_PROPERTIES_AMD,
667            p_next: ::std::ptr::null_mut(),
668            cu_count: u32::default(),
669            max_waves_per_cu: u32::default(),
670        }
671    }
672}
673impl PhysicalDeviceWaveLimitPropertiesAmd {
674    pub fn builder<'a>() -> PhysicalDeviceWaveLimitPropertiesAmdBuilder<'a> {
675        PhysicalDeviceWaveLimitPropertiesAmdBuilder {
676            inner: Self::default(),
677            marker: ::std::marker::PhantomData,
678        }
679    }
680}
681pub struct PhysicalDeviceWaveLimitPropertiesAmdBuilder<'a> {
682    inner: PhysicalDeviceWaveLimitPropertiesAmd,
683    marker: ::std::marker::PhantomData<&'a ()>,
684}
685pub unsafe trait ExtendsPhysicalDeviceWaveLimitPropertiesAmd {}
686unsafe impl ExtendsPhysicalDeviceProperties2 for PhysicalDeviceWaveLimitPropertiesAmd {}
687impl<'a> ::std::ops::Deref for PhysicalDeviceWaveLimitPropertiesAmdBuilder<'a> {
688    type Target = PhysicalDeviceWaveLimitPropertiesAmd;
689    fn deref(&self) -> &Self::Target {
690        &self.inner
691    }
692}
693impl<'a> PhysicalDeviceWaveLimitPropertiesAmdBuilder<'a> {
694    pub fn push_next<T>(
695        mut self,
696        next: &'a mut T,
697    ) -> PhysicalDeviceWaveLimitPropertiesAmdBuilder<'a>
698    where
699        T: ExtendsPhysicalDeviceWaveLimitPropertiesAmd,
700    {
701        unsafe {
702            let next_ptr = <*const T>::cast(next);
703            let last_next = ptr_chain_iter(next).last().unwrap();
704            (*last_next).p_next = self.inner.p_next as _;
705            self.inner.p_next = next_ptr;
706        }
707        self
708    }
709    pub fn build(self) -> PhysicalDeviceWaveLimitPropertiesAmd {
710        self.inner
711    }
712}
713
714#[repr(C)]
715#[derive(Copy, Clone)]
716#[cfg_attr(feature = "debug", derive(Debug))]
717pub struct PipelineShaderStageCreateInfoWaveLimitAmd {
718    pub s_type: StructureType,
719    pub p_next: *const c_void,
720    pub waves_per_cu: f32,
721    pub cu_enable_mask: *mut u32,
722}