Skip to content

Commit

Permalink
extensions/amd/shader_info: Replace unreachable ShaderInfoResult wi…
Browse files Browse the repository at this point in the history
…th 3 specialized functions (#901)

Since the extension modularization in #894 this `enum ShaderInfoResult`
is no longer reachable through the crate hierarchy, making it impossible
for callers to match on its variants.

Not that this type was ideal to begin with: the returned `enum`
variant depended purely on the `info_type` parameter, leading to ugly
`unreachable!()`-like unwraps in caller code when the variant should
always be of the type that a caller requested.

To solve both issues, create 3 instances of the `get_shader_info()`
function for each of the 3 `vk::ShaderInfoTypeAMD`s that a caller can
request.
  • Loading branch information
MarijnS95 authored Apr 1, 2024
1 parent 0c362c0 commit cd6e1ea
Showing 1 changed file with 46 additions and 38 deletions.
84 changes: 46 additions & 38 deletions ash/src/extensions/amd/shader_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,63 @@ use alloc::vec::Vec;
use core::mem;

impl crate::amd::shader_info::Device {
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetShaderInfoAMD.html>
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetShaderInfoAMD.html> with [`vk::ShaderInfoTypeAMD::STATISTICS`]
#[inline]
pub unsafe fn get_shader_info(
pub unsafe fn get_shader_info_statistics(
&self,
pipeline: vk::Pipeline,
shader_stage: vk::ShaderStageFlags,
info_type: vk::ShaderInfoTypeAMD,
) -> VkResult<ShaderInfoResult> {
let load_data = |count: &mut usize, data: *mut u8| {
) -> VkResult<vk::ShaderStatisticsInfoAMD> {
let mut info = mem::MaybeUninit::<vk::ShaderStatisticsInfoAMD>::uninit();
let mut size = mem::size_of_val(&info);
(self.fp.get_shader_info_amd)(
self.handle,
pipeline,
shader_stage,
vk::ShaderInfoTypeAMD::STATISTICS,
&mut size,
info.as_mut_ptr().cast(),
)
.result()?;
assert_eq!(size, mem::size_of_val(&info));
Ok(info.assume_init())
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetShaderInfoAMD.html> with [`vk::ShaderInfoTypeAMD::BINARY`]
#[inline]
pub unsafe fn get_shader_info_binary(
&self,
pipeline: vk::Pipeline,
shader_stage: vk::ShaderStageFlags,
) -> VkResult<Vec<u8>> {
read_into_uninitialized_vector(|count, data: *mut u8| {
(self.fp.get_shader_info_amd)(
self.handle,
pipeline,
shader_stage,
info_type,
vk::ShaderInfoTypeAMD::BINARY,
count,
data.cast(),
)
};

match info_type {
vk::ShaderInfoTypeAMD::STATISTICS => {
let mut statistics_info = mem::MaybeUninit::<vk::ShaderStatisticsInfoAMD>::uninit();
load_data(
&mut mem::size_of_val(&statistics_info),
statistics_info.as_mut_ptr().cast(),
)
.result()?;
Ok(ShaderInfoResult::StatisticsInfo(
statistics_info.assume_init(),
))
}
vk::ShaderInfoTypeAMD::BINARY => {
read_into_uninitialized_vector(load_data).map(ShaderInfoResult::Binary)
}
vk::ShaderInfoTypeAMD::DISASSEMBLY => {
read_into_uninitialized_vector(load_data).map(ShaderInfoResult::Disassembly)
}
#[cfg(feature = "debug")]
x => unimplemented!("ShaderInfoTypeAMD {:?}", x),
#[cfg(not(feature = "debug"))]
x => unimplemented!("ShaderInfoTypeAMD {}", x.0),
}
})
}
}

#[derive(Clone)]
#[cfg_attr(feature = "debug", derive(Debug))]
pub enum ShaderInfoResult {
StatisticsInfo(vk::ShaderStatisticsInfoAMD),
Binary(Vec<u8>),
Disassembly(Vec<u8>),
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetShaderInfoAMD.html> with [`vk::ShaderInfoTypeAMD::DISASSEMBLY`]
#[inline]
pub unsafe fn get_shader_info_disassembly(
&self,
pipeline: vk::Pipeline,
shader_stage: vk::ShaderStageFlags,
) -> VkResult<Vec<u8>> {
read_into_uninitialized_vector(|count, data: *mut u8| {
(self.fp.get_shader_info_amd)(
self.handle,
pipeline,
shader_stage,
vk::ShaderInfoTypeAMD::DISASSEMBLY,
count,
data.cast(),
)
})
}
}

0 comments on commit cd6e1ea

Please sign in to comment.