pub struct ShaderRegistry;
impl ShaderRegistry {
pub fn get(name: &str) -> Option<&'static str> {
match name {
"reproject" => Some(include_str!("shaders/reproject.wgsl")),
"raster_algebra" => Some(include_str!("shaders/raster_algebra.wgsl")),
"hillshade" => Some(include_str!("shaders/hillshade.wgsl")),
_ => None,
}
}
pub fn list() -> &'static [&'static str] {
&["reproject", "raster_algebra", "hillshade"]
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct GpuCapabilities {
pub has_compute: bool,
pub has_texture_float: bool,
pub max_workgroup_size: u32,
pub max_buffer_size: u64,
}
impl Default for GpuCapabilities {
fn default() -> Self {
Self {
has_compute: true,
has_texture_float: true,
max_workgroup_size: 256,
max_buffer_size: 256 * 1024 * 1024, }
}
}
impl GpuCapabilities {
pub fn webgpu_conservative() -> Self {
Self {
has_compute: true,
has_texture_float: true,
max_workgroup_size: 256,
max_buffer_size: 128 * 1024 * 1024, }
}
pub fn validate_buffer_size(&self, size: u64) -> bool {
size <= self.max_buffer_size
}
pub fn validate_workgroup(&self, size: u32) -> bool {
size <= self.max_workgroup_size
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_shader_registry_known_names() {
for name in ShaderRegistry::list() {
assert!(
ShaderRegistry::get(name).is_some(),
"expected shader '{}' to be registered",
name
);
}
}
#[test]
fn test_shader_registry_unknown() {
assert!(ShaderRegistry::get("nonexistent_shader").is_none());
}
#[test]
fn test_capabilities_default() {
let caps = GpuCapabilities::default();
assert!(caps.has_compute);
assert_eq!(caps.max_workgroup_size, 256);
assert_eq!(caps.max_buffer_size, 256 * 1024 * 1024);
}
#[test]
fn test_capabilities_webgpu() {
let caps = GpuCapabilities::webgpu_conservative();
assert_eq!(caps.max_buffer_size, 128 * 1024 * 1024);
}
}