crystal_api/
shader.rs

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