1#![warn(clippy::all)]
132#![deny(clippy::unwrap_used)]
133#![deny(clippy::panic)]
134#![allow(missing_docs)]
136#![allow(dead_code)]
138#![allow(clippy::manual_div_ceil)]
140#![allow(clippy::should_implement_trait)]
142#![allow(private_interfaces)]
144#![allow(unused_must_use)]
146#![allow(clippy::type_complexity)]
148#![allow(clippy::expect_used)]
150#![allow(clippy::manual_clamp)]
152#![allow(clippy::get_first)]
154#![allow(clippy::collapsible_match)]
156#![allow(clippy::redundant_closure)]
158#![allow(clippy::vec_init_then_push)]
160#![allow(clippy::iter_kv_map)]
162#![allow(clippy::needless_question_mark)]
164#![allow(clippy::needless_lifetimes)]
166#![allow(clippy::for_kv_map)]
168#![allow(elided_lifetimes_in_associated_constant)]
170
171pub mod algebra;
172pub mod backends;
173pub mod band_math;
174pub mod buffer;
175pub mod compositing;
176pub mod compute;
177pub mod context;
178pub mod convolution_fft;
179pub mod cooperative_matrix;
180pub mod cpu_fallback;
181pub mod device_lost_test;
182pub mod error;
183pub mod fft;
184pub mod indirect_dispatch;
185pub mod kernels;
186pub mod memory;
187pub mod multi_gpu;
188pub mod pipeline_cache;
189pub mod profiling;
190pub mod push_constants;
191pub mod ray_march;
192pub mod reprojection;
193pub mod shader_helpers;
194pub mod shader_reload;
195#[cfg(feature = "shader-hot-reload")]
196pub mod shader_reload_native;
197pub mod shaders;
198pub mod storage_texture;
199pub mod texture_compress;
200pub mod texture_resample;
201pub mod tiled;
202pub mod webgpu_compat;
203pub mod workgroup_tuner;
204
205pub use algebra::{AlgebraOp, BandExpression, GpuAlgebra};
207pub use band_math::{BandMathError, band_expression_to_wgsl, parse_band_expression};
208pub use buffer::{
209 BufferElementType, GpuBuffer, GpuRasterBuffer, f16_to_f32_slice, f32_to_f16_slice,
210 from_f16_slice_native, from_f16_slice_widening, read_f16_from_f32_buffer,
211};
212pub use compute::{ComputePipeline, MultibandPipeline};
213pub use context::{BackendPreference, GpuContext, GpuContextConfig, GpuPowerPreference};
214pub use convolution_fft::{
215 FftConvolution, MAX_FFT_CONVOLUTION_SIZE, complex_multiply, convolve_reference,
216};
217pub use cooperative_matrix::{
218 CoopMatrixComponentType, CoopMatrixDescriptor, CoopMatrixDim, CoopMatrixGemmConfig,
219 CoopMatrixUse, build_cooperative_matrix_gemm_pipeline, dispatch_cooperative_gemm,
220 make_gemm_wgsl, make_gemm_wgsl_fallback, max_cooperative_matrix_dim,
221 supports_cooperative_matrix,
222};
223pub use cpu_fallback::cpu;
224pub use cpu_fallback::{
225 ExecutionPath, FallbackConfig, FallbackContext, FallbackResult, execute_with_fallback,
226 execute_with_fallback_timed,
227};
228pub use error::{GpuError, GpuResult};
229pub use fft::{Fft1d, bit_reverse, make_fft_shader_source, twiddle_factor, validate_size};
230pub use half;
233pub use indirect_dispatch::{
234 DispatchIndirectArgs, IndirectDispatchBuffer, args_for_elements, dispatch_indirect_on_pass,
235 workgroup_count_1d, workgroup_count_2d, workgroup_count_3d,
236};
237pub use kernels::{
238 convolution::{Filters, gaussian_blur},
239 raster::{ElementWiseOp, RasterKernel, ScalarOp, UnaryOp},
240 resampling::{ResamplingMethod, resize},
241 statistics::{HistogramParams, ReductionOp, Statistics, compute_statistics},
242};
243pub use memory::{MemoryPool, MemoryPoolConfig, StagingBufferManager, VramBudgetManager};
244pub use multi_gpu::{
245 DistributionStrategy, InterGpuTransfer, MultiGpuConfig, MultiGpuManager, WorkDistributor,
246};
247pub use pipeline_cache::{
248 PipelineCache, PipelineCacheKey, SharedPipelineCache, fnv1a_64, new_shared_pipeline_cache,
249};
250pub use profiling::{GpuTimestampProfiler, PassTiming};
251pub use push_constants::{
252 MAX_PUSH_CONSTANTS_SIZE_BYTES, PushConstantRange, PushConstantRangeDesc, PushConstantsBuffer,
253 PushConstantsLayout, build_push_constants_pipeline, dispatch_with_push_constants,
254 make_push_constants_shader_source, max_push_constants_size, supports_push_constants,
255};
256pub use ray_march::{
257 DemRayMarcher, RayMarchConfig, RayMarchResult, make_ray_march_shader_source, normalize3,
258 ray_march_cpu, sample_dem_bilinear,
259};
260pub use reprojection::{GpuReprojector, ReprojectionConfig, ResampleMethod};
261pub use shader_helpers::make_element_wise_shader_source;
262pub use storage_texture::{
263 StorageTextureBinding, StorageTextureKernel, build_storage_texture_kernel,
264 is_supported_storage_format, make_storage_texture_shader_source, new_storage_texture,
265 read_texture_to_vec_f32,
266};
267pub use texture_compress::{
268 TextureCompressor, TextureFormat, compress_bc1_block_cpu, compress_bc4_block_cpu,
269 dequantize_rgb565, nearest_index_4, quantize_rgb565, validate_texture_dimensions,
270};
271pub use texture_resample::{
272 TextureFilterMethod, TextureResampler, make_texture_resample_shader_source,
273 new_input_texture_r32float, texture_filter_for_resampling,
274};
275pub use tiled::{
276 RasterTile, TiledConfig, auto_tile_size, execute_tiled, split_into_tiles, stitch_tiles,
277 vram_per_tile,
278};
279pub use webgpu_compat::{GpuCapabilities, ShaderRegistry};
280pub use workgroup_tuner::WorkgroupTuner;
281
282#[cfg(feature = "shader-hot-reload")]
283pub use shader_reload_native::{
284 FilesystemPoller, PolledChange, PolledChangeKind, read_shader_source,
285};
286
287pub const VERSION: &str = env!("CARGO_PKG_VERSION");
289
290pub async fn is_gpu_available() -> bool {
309 GpuContext::new().await.is_ok()
310}
311
312pub async fn get_available_adapters() -> Vec<(String, String)> {
329 use wgpu::{Backends, Instance, InstanceDescriptor, RequestAdapterOptions};
330
331 let _instance = Instance::new(InstanceDescriptor {
332 backends: Backends::all(),
333 ..InstanceDescriptor::new_without_display_handle()
334 });
335
336 let mut adapters = Vec::new();
337
338 for backend in &[
340 Backends::VULKAN,
341 Backends::METAL,
342 Backends::DX12,
343 Backends::BROWSER_WEBGPU,
344 ] {
345 let instance = Instance::new(InstanceDescriptor {
346 backends: *backend,
347 ..InstanceDescriptor::new_without_display_handle()
348 });
349
350 if let Ok(adapter) = instance
351 .request_adapter(&RequestAdapterOptions::default())
352 .await
353 {
354 let info = adapter.get_info();
355 adapters.push((info.name, format!("{:?}", info.backend)));
356 }
357 }
358
359 adapters
360}
361
362#[cfg(test)]
363mod tests {
364 use super::*;
365
366 #[test]
367 fn test_version() {
368 assert!(!VERSION.is_empty());
369 }
370
371 #[tokio::test]
372 async fn test_gpu_availability() {
373 let available = is_gpu_available().await;
374 println!("GPU available: {}", available);
375 }
376
377 #[tokio::test]
378 async fn test_get_adapters() {
379 let adapters = get_available_adapters().await;
380 println!("Available adapters:");
381 for (name, backend) in adapters {
382 println!(" - {} ({:?})", name, backend);
383 }
384 }
385}