#![allow(unused_imports)]
use crate::{vk::Result as VkResult, vk::*, *};
use core::ffi::{CStr, c_char, c_int, c_void};
use core::mem::transmute;
use core::ptr;
pub const EXTENSION_NAME: &CStr = c"VK_AMD_shader_info";
pub(super) mod defs {
#![allow(non_camel_case_types, unused_imports)]
use crate::{vk::*, *};
use core::ffi::{CStr, c_char, c_int, c_void};
use core::fmt;
use core::marker::PhantomData;
use core::ptr;
#[repr(C)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[derive(Copy, Clone, Default)]
#[must_use]
pub struct ShaderResourceUsageAMD {
pub num_used_vgprs: u32,
pub num_used_sgprs: u32,
pub lds_size_per_local_work_group: u32,
pub lds_usage_size_in_bytes: usize,
pub scratch_mem_usage_in_bytes: usize,
}
impl ShaderResourceUsageAMD {
#[inline]
pub fn num_used_vgprs(mut self, num_used_vgprs: u32) -> Self {
self.num_used_vgprs = num_used_vgprs;
self
}
#[inline]
pub fn num_used_sgprs(mut self, num_used_sgprs: u32) -> Self {
self.num_used_sgprs = num_used_sgprs;
self
}
#[inline]
pub fn lds_size_per_local_work_group(mut self, lds_size_per_local_work_group: u32) -> Self {
self.lds_size_per_local_work_group = lds_size_per_local_work_group;
self
}
#[inline]
pub fn lds_usage_size_in_bytes(mut self, lds_usage_size_in_bytes: usize) -> Self {
self.lds_usage_size_in_bytes = lds_usage_size_in_bytes;
self
}
#[inline]
pub fn scratch_mem_usage_in_bytes(mut self, scratch_mem_usage_in_bytes: usize) -> Self {
self.scratch_mem_usage_in_bytes = scratch_mem_usage_in_bytes;
self
}
}
#[repr(C)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[derive(Copy, Clone)]
#[must_use]
pub struct ShaderStatisticsInfoAMD {
pub shader_stage_mask: ShaderStageFlags,
pub resource_usage: ShaderResourceUsageAMD,
pub num_physical_vgprs: u32,
pub num_physical_sgprs: u32,
pub num_available_vgprs: u32,
pub num_available_sgprs: u32,
pub compute_work_group_size: [u32; 3],
}
impl Default for ShaderStatisticsInfoAMD {
fn default() -> Self {
Self {
shader_stage_mask: Default::default(),
resource_usage: Default::default(),
num_physical_vgprs: Default::default(),
num_physical_sgprs: Default::default(),
num_available_vgprs: Default::default(),
num_available_sgprs: Default::default(),
compute_work_group_size: [Default::default(); _],
}
}
}
impl ShaderStatisticsInfoAMD {
#[inline]
pub fn shader_stage_mask(mut self, shader_stage_mask: ShaderStageFlags) -> Self {
self.shader_stage_mask = shader_stage_mask;
self
}
#[inline]
pub fn resource_usage(mut self, resource_usage: ShaderResourceUsageAMD) -> Self {
self.resource_usage = resource_usage;
self
}
#[inline]
pub fn num_physical_vgprs(mut self, num_physical_vgprs: u32) -> Self {
self.num_physical_vgprs = num_physical_vgprs;
self
}
#[inline]
pub fn num_physical_sgprs(mut self, num_physical_sgprs: u32) -> Self {
self.num_physical_sgprs = num_physical_sgprs;
self
}
#[inline]
pub fn num_available_vgprs(mut self, num_available_vgprs: u32) -> Self {
self.num_available_vgprs = num_available_vgprs;
self
}
#[inline]
pub fn num_available_sgprs(mut self, num_available_sgprs: u32) -> Self {
self.num_available_sgprs = num_available_sgprs;
self
}
#[inline]
pub fn compute_work_group_size(mut self, compute_work_group_size: [u32; 3]) -> Self {
self.compute_work_group_size = compute_work_group_size;
self
}
}
#[repr(transparent)]
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ShaderInfoTypeAMD(i32);
impl ShaderInfoTypeAMD {
#[inline]
pub const fn from_raw(x: i32) -> Self {
Self(x)
}
#[inline]
pub const fn as_raw(self) -> i32 {
self.0
}
pub const STATISTICS_AMD: Self = Self(0);
pub const BINARY_AMD: Self = Self(1);
pub const DISASSEMBLY_AMD: Self = Self(2);
}
impl fmt::Debug for ShaderInfoTypeAMD {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = match *self {
Self::STATISTICS_AMD => Some("STATISTICS_AMD"),
Self::BINARY_AMD => Some("BINARY_AMD"),
Self::DISASSEMBLY_AMD => Some("DISASSEMBLY_AMD"),
_ => None,
};
if let Some(name) = name {
f.write_str(name)
} else {
self.0.fmt(f)
}
}
}
pub type PFN_vkGetShaderInfoAMD = unsafe extern "system" fn(
device: Device,
pipeline: Pipeline,
shader_stage: ShaderStageFlagBits,
info_type: ShaderInfoTypeAMD,
p_info_size: *mut usize,
p_info: *mut c_void,
) -> vk::Result;
}
#[cfg(feature = "ffi")]
pub(super) mod ffi {
#![allow(non_camel_case_types)]
use super::defs::*;
pub type VkShaderResourceUsageAMD = ShaderResourceUsageAMD;
pub type VkShaderStatisticsInfoAMD = ShaderStatisticsInfoAMD;
pub type VkShaderInfoTypeAMD = ShaderInfoTypeAMD;
}
pub struct DeviceFn {
get_shader_info: PFN_vkGetShaderInfoAMD,
}
impl LoadDeviceFn for DeviceFn {
unsafe fn load_with(
load: impl Fn(&CStr) -> Option<PFN_vkVoidFunction>,
) -> core::result::Result<Self, MissingEntryPointError> {
unsafe {
Ok(Self {
get_shader_info: transmute(
load(c"vkGetShaderInfoAMD").ok_or(MissingEntryPointError)?,
),
})
}
}
}
impl DeviceFn {
#[inline]
pub unsafe fn get_shader_info(
&self,
device: Device,
pipeline: Pipeline,
shader_stage: ShaderStageFlagBits,
info_type: ShaderInfoTypeAMD,
mut info: impl EnumerateInto<u8>,
) -> crate::Result<()> {
unsafe {
let call = |info_size, info| {
let result = (self.get_shader_info)(
device,
pipeline,
shader_stage,
info_type,
info_size,
info as _,
);
match result {
VkResult::SUCCESS => Ok(()),
VkResult::INCOMPLETE => Ok(()),
err => Err(err),
}
};
let mut len = 0;
call(&mut len, std::ptr::null_mut())?;
let capacity = len.try_into().expect("failed to convert `N` to usize");
let info_buf = info.reserve(capacity);
len = info_buf.len().try_into().unwrap();
let result = call(&mut len, info_buf.as_mut_ptr() as *mut _)?;
info.set_len(len.try_into().unwrap());
Ok(result)
}
}
}