use super::device::DeviceInner;
use super::{Device, Error, Result, check};
use crate::raw::bindings::*;
use std::sync::Arc;
pub struct ShaderModule {
pub(crate) handle: VkShaderModule,
pub(crate) device: Arc<DeviceInner>,
}
impl ShaderModule {
pub fn from_spirv(device: &Device, code: &[u32]) -> Result<Self> {
let create = device
.inner
.dispatch
.vkCreateShaderModule
.ok_or(Error::MissingFunction("vkCreateShaderModule"))?;
let info = VkShaderModuleCreateInfo {
sType: VkStructureType::STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
codeSize: std::mem::size_of_val(code),
pCode: code.as_ptr(),
..Default::default()
};
let mut handle: VkShaderModule = 0;
check(unsafe { create(device.inner.handle, &info, std::ptr::null(), &mut handle) })?;
Ok(Self {
handle,
device: Arc::clone(&device.inner),
})
}
pub fn from_spirv_bytes(device: &Device, bytes: &[u8]) -> Result<Self> {
if bytes.len() % 4 != 0 {
return Err(Error::Vk(VkResult::ERROR_INITIALIZATION_FAILED));
}
let words: Vec<u32> = bytes
.chunks_exact(4)
.map(|c| u32::from_le_bytes([c[0], c[1], c[2], c[3]]))
.collect();
Self::from_spirv(device, &words)
}
pub fn raw(&self) -> VkShaderModule {
self.handle
}
}
impl Drop for ShaderModule {
fn drop(&mut self) {
if let Some(destroy) = self.device.dispatch.vkDestroyShaderModule {
unsafe { destroy(self.device.handle, self.handle, std::ptr::null()) };
}
}
}