use crate::{GpuContextHandle, GpuError};
use super::{Access, BindingKind, BufferOut, SamplerDesc, ShaderSpec, Uniform, UniformBytes};
pub enum BufferInit<'a> {
Empty(u64),
Zeroed(u64),
Bytes(&'a [u8]),
}
pub enum BindingData<'a> {
Buffer(BufferInit<'a>),
BufferDevice {
buffer: std::sync::Arc<wgpu::Buffer>,
size: u64,
device_key: usize,
},
TextureRgba8 {
width: u32,
height: u32,
bytes: std::borrow::Cow<'a, [u8]>,
},
TextureAlloc {
width: u32,
height: u32,
},
TextureHandle {
handle: crate::GpuImageHandle,
},
Sampler(SamplerDesc),
}
pub struct ShaderBinding<'a> {
pub binding: u32,
pub kind: BindingKind,
pub access: Access,
pub data: BindingData<'a>,
pub readback: bool,
}
pub trait GpuBindings<'a> {
fn spec() -> &'static ShaderSpec;
fn bindings(
&'a self,
gpu: Option<&GpuContextHandle>,
) -> Result<Vec<ShaderBinding<'a>>, GpuError>;
fn invocation_hint(&'a self) -> Option<[u32; 3]> {
None
}
}
pub trait BindingBytes {
fn as_bytes(&self) -> &[u8];
}
impl BindingBytes for &[u8] {
fn as_bytes(&self) -> &[u8] {
self
}
}
impl BindingBytes for &[f32] {
fn as_bytes(&self) -> &[u8] {
bytemuck::cast_slice(self)
}
}
impl<'a> BindingBytes for UniformBytes<'a> {
fn as_bytes(&self) -> &[u8] {
self.0
}
}
impl<T: bytemuck::Pod> BindingBytes for Uniform<T> {
fn as_bytes(&self) -> &[u8] {
&self.bytes
}
}
pub fn as_bytes<T: BindingBytes + ?Sized>(value: &T) -> &[u8] {
value.as_bytes()
}
pub fn buffer_len(value: &BufferOut) -> u64 {
value.len
}