use ash::vk::ShaderStageFlags;
use ash::{
util::read_spv,
vk::{ShaderModule, ShaderModuleCreateInfo},
};
use std::io::{Cursor, Read};
use crate::{Destroy, Device, Instance, NxError, NxResult};
pub struct Spirv {
pub(crate) data: Vec<u32>,
}
impl Spirv {
pub fn new(file: &str) -> NxResult<Self> {
let mut file = std::fs::File::open(file).expect("file open failed");
let mut buf = Vec::new();
match file.read_to_end(&mut buf) {
Ok(_) => {}
Err(e) => return Err(NxError::IoError(e.to_string())),
}
let mut spirv_file = Cursor::new(&buf);
let spirv = match read_spv(&mut spirv_file) {
Ok(x) => x,
Err(e) => return Err(NxError::IoError(e.to_string())),
};
Ok(Self { data: spirv })
}
pub fn from_raw(data: &[u8]) -> NxResult<Self> {
let mut spirv_file = Cursor::new(data);
let spirv = match read_spv(&mut spirv_file) {
Ok(x) => x,
Err(e) => return Err(NxError::IoError(e.to_string())),
};
Ok(Self { data: spirv })
}
}
#[derive(Clone, Copy, Debug)]
pub struct Shader {
pub(crate) inner: ShaderModule,
}
impl Shader {
pub fn new(device: &Device, spirv: &Spirv) -> Shader {
let shader_create_info = ShaderModuleCreateInfo::builder().code(&spirv.data).build();
let shader = unsafe {
device
.device
.create_shader_module(&shader_create_info, None)
}
.unwrap();
Shader { inner: shader }
}
}
impl Destroy for Shader {
fn instance(&self, _: &Instance) {}
fn device(&self, device: &Device) {
unsafe {
device.device.destroy_shader_module(self.inner, None);
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ShaderStage {
Vertex,
Fragment,
}
impl From<ShaderStage> for ShaderStageFlags {
fn from(value: ShaderStage) -> Self {
match value {
ShaderStage::Vertex => ShaderStageFlags::VERTEX,
ShaderStage::Fragment => ShaderStageFlags::FRAGMENT,
}
}
}
pub struct ShaderStageDescriptor<'a> {
#[doc(hidden)]
pub(crate) shaders: Option<&'a Shader>,
#[doc(hidden)]
pub(crate) entry_point: &'a str,
#[doc(hidden)]
pub(crate) stage: ShaderStage,
}
impl<'a> ShaderStageDescriptor<'a> {
pub fn empty() -> Self {
Self {
shaders: None,
entry_point: "main",
stage: ShaderStage::Vertex,
}
}
pub fn shaders(mut self, shaders: &'a Shader) -> Self {
self.shaders = Some(shaders);
self
}
pub fn entry_point(mut self, entry_point: &'a str) -> Self {
self.entry_point = entry_point;
self
}
pub fn stage(mut self, stage: ShaderStage) -> Self {
self.stage = stage;
self
}
}