Skip to main content

wgpu/api/
shader_module.rs

1use core::{future::Future, marker::PhantomData};
2pub use wgt::{CompilationInfo, CompilationMessage, CompilationMessageType, SourceLocation};
3
4use crate::*;
5
6/// Handle to a compiled shader module.
7///
8/// A `ShaderModule` represents a compiled shader module on the GPU. It can be created by passing
9/// source code to [`Device::create_shader_module`]. MSL shader or SPIR-V binary can also be passed
10/// directly using [`Device::create_shader_module_passthrough`]. Shader modules are used to define
11/// programmable stages of a pipeline.
12///
13/// Corresponds to [WebGPU `GPUShaderModule`](https://gpuweb.github.io/gpuweb/#shader-module).
14#[derive(Debug, Clone)]
15pub struct ShaderModule {
16    pub(crate) inner: dispatch::DispatchShaderModule,
17}
18#[cfg(send_sync)]
19static_assertions::assert_impl_all!(ShaderModule: Send, Sync);
20
21crate::cmp::impl_eq_ord_hash_proxy!(ShaderModule => .inner);
22
23impl ShaderModule {
24    /// Get the compilation info for the shader module.
25    pub fn get_compilation_info(&self) -> impl Future<Output = CompilationInfo> + WasmNotSend {
26        self.inner.get_compilation_info()
27    }
28
29    #[cfg(custom)]
30    /// Returns custom implementation of ShaderModule (if custom backend and is internally T)
31    pub fn as_custom<T: custom::ShaderModuleInterface>(&self) -> Option<&T> {
32        self.inner.as_custom()
33    }
34}
35
36#[cfg(wgpu_core)]
37impl ShaderModule {
38    /// Create a new shader module of wgpu from a wgpu-core shader module.
39    ///
40    /// # Arguments
41    ///
42    /// - `core_shader_module` - wgpu-core shader module.
43    pub fn from_core(core_shader_module: alloc::sync::Arc<wgc::pipeline::ShaderModule>) -> Self {
44        Self {
45            inner: crate::backend::wgpu_core::CoreShaderModule::from_core(core_shader_module)
46                .into(),
47        }
48    }
49
50    /// Returns the underlying wgpu-core shader module if this `ShaderModule` is on the wgpu-core backend, otherwise `None`.
51    pub fn as_core(&self) -> Option<alloc::sync::Arc<wgc::pipeline::ShaderModule>> {
52        self.inner.as_core_opt().map(|sm| sm.as_core())
53    }
54}
55
56/// Source of a shader module.
57///
58/// The source will be parsed and validated.
59///
60/// Any necessary shader translation (e.g. from WGSL to SPIR-V or vice versa)
61/// will be done internally by wgpu.
62///
63/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification,
64/// only WGSL source code strings are accepted.
65#[cfg_attr(feature = "naga-ir", expect(clippy::large_enum_variant))]
66#[derive(Clone, Debug)]
67#[non_exhaustive]
68pub enum ShaderSource<'a> {
69    /// SPIR-V module represented as a slice of words.
70    ///
71    /// See also: [`util::make_spirv`], [`include_spirv`]
72    #[cfg(feature = "spirv")]
73    SpirV(alloc::borrow::Cow<'a, [u32]>),
74    /// GLSL module as a string slice.
75    ///
76    /// Note: GLSL is not yet fully supported and must be a specific ShaderStage.
77    #[cfg(feature = "glsl")]
78    Glsl {
79        /// The source code of the shader.
80        shader: alloc::borrow::Cow<'a, str>,
81        /// The shader stage that the shader targets. For example, `naga::ShaderStage::Vertex`
82        stage: naga::ShaderStage,
83        /// Key-value pairs to represent defines sent to the glsl preprocessor.
84        ///
85        /// If the same name is defined multiple times, the last value is used.
86        defines: &'a [(&'a str, &'a str)],
87    },
88    /// WGSL module as a string slice.
89    #[cfg(feature = "wgsl")]
90    Wgsl(alloc::borrow::Cow<'a, str>),
91    /// Naga module.
92    #[cfg(feature = "naga-ir")]
93    Naga(alloc::borrow::Cow<'static, naga::Module>),
94    /// Dummy variant because `Naga` doesn't have a lifetime and without enough active features it
95    /// could be the last one active.
96    #[doc(hidden)]
97    Dummy(PhantomData<&'a ()>),
98}
99static_assertions::assert_impl_all!(ShaderSource<'_>: Send, Sync);
100
101/// Descriptor for use with [`Device::create_shader_module`].
102///
103/// Corresponds to [WebGPU `GPUShaderModuleDescriptor`](
104/// https://gpuweb.github.io/gpuweb/#dictdef-gpushadermoduledescriptor).
105#[derive(Clone, Debug)]
106pub struct ShaderModuleDescriptor<'a> {
107    /// Debug label of the shader module. This will show up in graphics debuggers for easy identification.
108    pub label: Label<'a>,
109    /// Source code for the shader.
110    pub source: ShaderSource<'a>,
111}
112static_assertions::assert_impl_all!(ShaderModuleDescriptor<'_>: Send, Sync);
113
114/// Descriptor for a shader module given by any of several sources.
115/// At least one of the shader types that may be used by the backend must be `Some`
116///
117/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification,
118/// only WGSL source code strings are accepted.
119pub type ShaderModuleDescriptorPassthrough<'a> =
120    wgt::CreateShaderModuleDescriptorPassthrough<'a, Label<'a>>;