mepeyew 0.3.5

mepeyew - Small But Powerful Graphics Library
Documentation
use super::*;

pub struct VkShader {
    pub module: vk::ShaderModule,
    pub shader_ty: ShaderType,

    drop_queue_ref: VkDropQueueRef,
}

impl VkShader {
    pub fn new(
        dev: &Device,
        drop_queue_ref: &VkDropQueueRef,
        shader_ty: &ShaderType,
        code: &[u8],
    ) -> GResult<Self> {
        let shader_create = vk::ShaderModuleCreateInfo::builder()
            .code(unsafe {
                std::slice::from_raw_parts(code.as_ptr() as *const u32, code.len() / (32 / 8))
            })
            .build();
        let module = unsafe { dev.create_shader_module(&shader_create, None) }
            .map_err(|e| gpu_api_err!("vulkan shader init {}", e))?;

        Ok(VkShader {
            module,
            shader_ty: shader_ty.clone(),

            drop_queue_ref: Arc::clone(drop_queue_ref),
        })
    }

    pub fn get_vertex_inputs(
        vertex_inputs: &VertexBufferInput,
    ) -> (
        Vec<vk::VertexInputAttributeDescription>,
        vk::VertexInputBindingDescription,
    ) {
        let mut current_offset = 0;
        (
            vertex_inputs
                .args
                .iter()
                .enumerate()
                .map(|(location, count)| {
                    let ret = vk::VertexInputAttributeDescription::builder()
                        .binding(0)
                        .location(location as u32)
                        .format(stride_count_to_vulkan_format(*count))
                        .offset(current_offset as u32)
                        .build();
                    current_offset += count * std::mem::size_of::<VertexBufferElement>();
                    ret
                })
                .collect::<Vec<_>>(),
            vk::VertexInputBindingDescription::builder()
                .binding(0)
                .stride(current_offset as u32)
                .input_rate(vk::VertexInputRate::VERTEX)
                .build(),
        )
    }
}

impl Drop for VkShader {
    fn drop(&mut self) {
        unsafe {
            let module = self.module;
            self.drop_queue_ref
                .lock()
                .unwrap()
                .push(Box::new(move |dev, _| {
                    dev.destroy_shader_module(module, None);
                }))
        }
    }
}

fn stride_count_to_vulkan_format(count: usize) -> vk::Format {
    match count {
        1 => vk::Format::R32_SFLOAT,
        2 => vk::Format::R32G32_SFLOAT,
        3 => vk::Format::R32G32B32_SFLOAT,
        4 => vk::Format::R32G32B32A32_SFLOAT,
        _ => unimplemented!("vulkan shader exceeded count limit"),
    }
}