crystal_api/
shader.rs

1use crate::errors::GraphicsResult;
2
3#[allow(missing_docs)]
4#[derive(Debug)]
5pub enum ShaderStage {
6    Vertex,
7    Fragment,
8    Geometry,
9    Tesselate,
10    Compute,
11}
12
13#[allow(missing_docs)]
14pub struct Shader {
15    pub(crate) stage: ShaderStage,
16    pub(crate) code: Vec<u32>,
17}
18
19impl Shader {
20    /// Creates new shader from words and specified stage
21    /// ```rust
22    /// let shader = Shader::from_words(words, ShaderStage::Vertex).unwrap()
23    /// ```
24    pub fn from_words(words: &[u32], stage: ShaderStage) -> GraphicsResult<Self> {
25        Ok(Shader {
26            stage,
27            code: words.to_vec(),
28        })
29    }
30
31    /// Creates new shader from bytes and specified stage
32    /// ```rust
33    /// let shader = Shader::from_bytes(bytes, ShaderStage::Vertex).unwrap()
34    /// ```
35    pub fn from_bytes(bytes: &[u8], stage: ShaderStage) -> GraphicsResult<Self> {
36        let shader_code = unsafe {
37            let ptr = std::alloc::alloc(std::alloc::Layout::from_size_align_unchecked(
38                bytes.len(),
39                0x10,
40            )) as *mut u8;
41
42            if ptr.is_null() {
43                panic!("Failed to allocate memory");
44            }
45
46            std::slice::from_raw_parts_mut(ptr, bytes.len())
47                .copy_from_slice(std::slice::from_raw_parts(bytes.as_ptr(), bytes.len()));
48
49            let len = bytes.len() / 4;
50
51            Vec::from_raw_parts(ptr as *mut u32, len, len)
52        };
53
54        Ok(Shader {
55            stage,
56            code: shader_code,
57        })
58    }
59}