Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
ce14ac3
Initial work for macro
SupaMaggie70Incorporated Sep 12, 2025
d974548
More work for macro that wasn't commited?
SupaMaggie70Incorporated Sep 12, 2025
c1f9549
Worked on macro a lot
SupaMaggie70Incorporated Sep 12, 2025
95491ce
Removed shader stage parameter from the thing
SupaMaggie70Incorporated Sep 12, 2025
9d52aca
Updated macro slightly
SupaMaggie70Incorporated Sep 12, 2025
80509c6
Updated some stuff
SupaMaggie70Incorporated Sep 12, 2025
59db4c7
Made more stuff build properly
SupaMaggie70Incorporated Sep 12, 2025
1dfc2b2
Refactored slightly
SupaMaggie70Incorporated Sep 12, 2025
f7ecc4c
Tried to fix a compile fail
SupaMaggie70Incorporated Sep 12, 2025
930b35b
Merge branch 'trunk' into precompiled-shaders-macro
SupaMaggie70Incorporated Sep 12, 2025
309919a
Added precompile test
SupaMaggie70Incorporated Sep 12, 2025
bac4a48
Added more related macros
SupaMaggie70Incorporated Sep 12, 2025
12d5e26
Worked more on the testing and such. Currently glsl include is broken…
SupaMaggie70Incorporated Sep 12, 2025
a28790d
Added comment explaining why compiled spv is in tree
SupaMaggie70Incorporated Sep 12, 2025
1a1d563
Made entry point specific to each backend in passthrough
SupaMaggie70Incorporated Sep 12, 2025
2f0293d
Enhanced macro slightly
SupaMaggie70Incorporated Sep 12, 2025
2229f05
Worked a little more
SupaMaggie70Incorporated Sep 12, 2025
11c9bca
Fixed vulkan backend y flip
SupaMaggie70Incorporated Sep 12, 2025
662c76c
Allowed precompiling dxil (will break everything again)
SupaMaggie70Incorporated Sep 12, 2025
9d45fd9
Added a comment explaining why entry point name differs by shader lan…
SupaMaggie70Incorporated Sep 12, 2025
78250d3
Tried to fix various compile errors/typos
SupaMaggie70Incorporated Sep 12, 2025
9c8988e
Added changelog entry
SupaMaggie70Incorporated Sep 15, 2025
f12f60f
Updated changelog entry again for the spirv passthrough change
SupaMaggie70Incorporated Sep 15, 2025
d1f1675
Refactored to allow compilation guards
SupaMaggie70Incorporated Sep 15, 2025
ed9934b
Reformatted cargo.toml
SupaMaggie70Incorporated Sep 15, 2025
be1504d
Tried updating syn and quote to see if it fixes anything
SupaMaggie70Incorporated Sep 15, 2025
038fb11
Merge branch 'trunk' into precompiled-shaders-macro
SupaMaggie70Incorporated Sep 15, 2025
b66e991
Attempted to fix windows compilation
SupaMaggie70Incorporated Sep 15, 2025
5c03032
This time I think DXC compilation should work, as I actually tested it
SupaMaggie70Incorporated Sep 15, 2025
6b34506
Fixed stupid typo that would've broken it
SupaMaggie70Incorporated Sep 15, 2025
0915522
Added typo to ignore list
SupaMaggie70Incorporated Sep 15, 2025
fdfa221
Updated Fo typo thing
SupaMaggie70Incorporated Sep 15, 2025
cf98e44
Actually fixed typos this time
SupaMaggie70Incorporated Sep 15, 2025
507f3d4
Undid bump to syn/quote that didn't fix MSRV test
SupaMaggie70Incorporated Sep 15, 2025
d954714
Tried to fix MSRV test
SupaMaggie70Incorporated Sep 15, 2025
f586710
Removed dxil compilation from example so that clippy won't complain w…
SupaMaggie70Incorporated Sep 15, 2025
10f31e0
Tried to make clippy happy
SupaMaggie70Incorporated Sep 15, 2025
9281184
Fixed dependency tests
SupaMaggie70Incorporated Sep 15, 2025
9e41b07
Updated deps to reflect #8246
SupaMaggie70Incorporated Sep 21, 2025
f2a3620
Merge branch 'trunk' into precompiled-shaders-macro
SupaMaggie70Incorporated Sep 22, 2025
113a75e
Update wgpu-precompile-macro/src/lib.rs
SupaMaggie70Incorporated Sep 24, 2025
c860d50
Merge branch 'trunk' into precompiled-shaders-macro
SupaMaggie70Incorporated Sep 24, 2025
5b9616e
Merge branch 'trunk' into precompiled-shaders-macro
SupaMaggie70Incorporated Sep 24, 2025
6ea7ea7
I don't even understand what happened here
SupaMaggie70Incorporated Sep 25, 2025
a0f613b
Now removes temporary folder regardless of crashing/etc
SupaMaggie70Incorporated Sep 25, 2025
c01e505
Update wgpu-precompile-macro/src/lib.rs
SupaMaggie70Incorporated Sep 25, 2025
fc4e1c7
Merge branch 'trunk' into precompiled-shaders-macro
SupaMaggie70Incorporated Sep 25, 2025
bedc327
Updated to latest dx12 mesh shader changes
SupaMaggie70Incorporated Sep 25, 2025
dff0697
Tried to improve error messages for dxc precompiling
SupaMaggie70Incorporated Sep 25, 2025
8344a81
Made dependency tests also check build deps
SupaMaggie70Incorporated Sep 25, 2025
537b32e
Fixed tests sorta (broke mesh shader test most likely due to requirin…
SupaMaggie70Incorporated Sep 25, 2025
b06ce5e
Other part to last commit
SupaMaggie70Incorporated Sep 25, 2025
1675170
Initial work on new shaders crate that will be used by wgpu-hal, the …
SupaMaggie70Incorporated Sep 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,30 @@ Difference for SPIR-V passthrough:
- },
- ))
+ device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough {
+ entry_point: "main".into(),
+ label: None,
+ spirv: Some(spirv_code),
+ spirv: Some(wgpu::SpirvPassthroughDescriptor {
+ code: spirv_code
+ }),
+ ..Default::default()
})
```
This allows using precompiled shaders without manually checking which backend's code to pass, for example if you have shaders precompiled for both DXIL and SPIR-V.

This comes along with an optional wgpu feature, `precompiled`, which provides a macro for precompiling shaders. For example, the following code is used in a test to precompile the `vs_main` entry point of `shader.wgsl` for all shader backends, excluding DXIL.
```rust
ctx
.device
.create_shader_module_passthrough(wgpu::include_precompiled_wgsl!(
// Shader source file
"shader.wgsl",
// Shader entry point
"vs_main",
// Target formats: a space separated list of backends, for example "all" or "hlsl glsl spirv"
all
))
```
You can also precompile SPIR-V and GLSL, and you can precompile raw shader code (code that lives in the rust file) using `precompile_wgsl` instead of `include_precompiled_wgsl`, and the analogous functions for GLSL.

#### Buffer mapping apis no longer have lifetimes

`Buffer::get_mapped_range()`, `Buffer::get_mapped_range_mut()`, and `Queue::write_buffer_with()` now return guard objects without any lifetimes. This
Expand Down
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ members = [
"wgpu-macros",
"wgpu-types",
"wgpu",
"wgpu-precompile-macro",
"xtask",
"wgpu-shaders",
]
exclude = []
default-members = [
Expand All @@ -47,6 +49,7 @@ default-members = [
"wgpu-macros",
"wgpu-types",
"wgpu",
"wgpu-precompile-macro",
"xtask",
]

Expand Down Expand Up @@ -80,6 +83,7 @@ wgpu = { version = "26.0.0", path = "./wgpu", default-features = false, features
wgpu-core = { version = "26.0.0", path = "./wgpu-core" }
wgpu-hal = { version = "26.0.0", path = "./wgpu-hal" }
wgpu-macros = { version = "26.0.0", path = "./wgpu-macros" }
wgpu-precompile-macro = { version = "26.0.0", path = "./wgpu-precompile-macro" }
wgpu-test = { version = "26.0.0", path = "./tests" }
wgpu-types = { version = "26.0.0", path = "./wgpu-types", default-features = false }

Expand Down Expand Up @@ -166,6 +170,7 @@ pollster = "0.4"
portable-atomic = "1.8"
portable-atomic-util = "0.2.4"
pp-rs = "0.2.1"
proc-macro2 = "1.0.101"
profiling = { version = "1.0.1", default-features = false }
quote = "1.0.38"
raw-window-handle = { version = "0.6.2", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ These examples use a common framework to handle wgpu init, window creation, and
#### Graphics

- `hello_triangle` - Provides an example of a bare-bones wgpu workflow using the Winit crate that simply renders a red triangle on a green background.
- `precompiled_shader` - Essentially `hello_triangle` except that the shaders are compiled at compile-time instead of runtime
- `uniform_values` - Demonstrates the basics of enabling shaders and the GPU, in general, to access app state through uniform variables. `uniform_values` also serves as an example of rudimentary app building as the app stores state and takes window-captured keyboard events. The app displays the Mandelbrot Set in grayscale (similar to `storage_texture`) but allows the user to navigate and explore it using their arrow keys and scroll wheel.
- `cube` - Introduces the user to slightly more advanced models. The example creates a set of triangles to form a cube on the CPU and then uses a vertex and index buffer to send the generated model to the GPU for usage in rendering. It also uses a texture generated on the CPU to shade the sides of the cube and a uniform variable to apply a transformation matrix to the cube in the shader.
- `bunnymark` - Demonstrates many things, but chief among them is performing numerous draw calls with different bind groups in one render pass. The example also uses textures for the icon and uniform buffers to transfer both global and per-particle states.
Expand Down
3 changes: 2 additions & 1 deletion examples/features/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ wgpu-test.workspace = true

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
env_logger.workspace = true
wgpu.workspace = true
wgpu = { workspace = true, features = ["precompile-macro"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook.workspace = true
Expand All @@ -67,6 +67,7 @@ wasm-bindgen-futures.workspace = true
wgpu = { path = "../../wgpu", default-features = false, features = [
"wgsl",
"std",
"precompile-macro",
] }
# We need these features in the framework examples and tests
web-sys = { workspace = true, features = [
Expand Down
2 changes: 2 additions & 0 deletions examples/features/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod mesh_shader;
pub mod mipmap;
pub mod msaa_line;
pub mod multiple_render_targets;
pub mod precompiled_shader;
pub mod ray_cube_compute;
pub mod ray_cube_fragment;
pub mod ray_cube_normals;
Expand Down Expand Up @@ -52,6 +53,7 @@ fn all_tests() -> Vec<wgpu_test::GpuTestInitializer> {
mipmap::TEST_QUERY,
msaa_line::TEST,
multiple_render_targets::TEST,
precompiled_shader::TEST,
ray_cube_compute::TEST,
ray_cube_fragment::TEST,
ray_cube_normals::TEST,
Expand Down
18 changes: 12 additions & 6 deletions examples/features/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ const EXAMPLES: &[ExampleDesc] = &[
webgl: false,
webgpu: true,
},
ExampleDesc {
name: "mesh_shader",
function: wgpu_examples::mesh_shader::main,
webgl: false,
webgpu: false,
},
ExampleDesc {
name: "mipmap",
function: wgpu_examples::mipmap::main,
Expand All @@ -80,6 +86,12 @@ const EXAMPLES: &[ExampleDesc] = &[
webgl: false,
webgpu: true,
},
ExampleDesc {
name: "precompiled_shader",
function: wgpu_examples::precompiled_shader::main,
webgl: true,
webgpu: true,
},
ExampleDesc {
name: "render_to_texture",
function: wgpu_examples::render_to_texture::main,
Expand Down Expand Up @@ -182,12 +194,6 @@ const EXAMPLES: &[ExampleDesc] = &[
webgl: false, // No Ray-tracing extensions
webgpu: false, // No Ray-tracing extensions (yet)
},
ExampleDesc {
name: "mesh_shader",
function: wgpu_examples::mesh_shader::main,
webgl: false,
webgpu: false,
},
];

fn get_example_name() -> Option<String> {
Expand Down
30 changes: 26 additions & 4 deletions examples/features/src/mesh_shader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ fn compile_glsl(device: &wgpu::Device, shader_stage: &'static str) -> wgpu::Shad
assert!(output.status.success());
unsafe {
device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough {
entry_point: "main".into(),
label: None,
spirv: Some(wgpu::util::make_spirv_raw(&output.stdout)),
spirv: Some(wgpu::SpirvPassthroughDescriptor {
code: wgpu::util::make_spirv_raw(&output.stdout),
}),
..Default::default()
})
}
Expand Down Expand Up @@ -52,10 +53,12 @@ fn compile_hlsl(device: &wgpu::Device, entry: &str, stage_str: &str) -> wgpu::Sh
std::fs::remove_file(out_path).unwrap();
unsafe {
device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough {
entry_point: entry.to_owned(),
label: None,
num_workgroups: (1, 1, 1),
dxil: Some(std::borrow::Cow::Owned(file)),
dxil: Some(wgpu::DxilPassthroughDescriptor {
entry_point: entry.to_owned(),
code: std::borrow::Cow::Owned(file),
}),
..Default::default()
})
}
Expand Down Expand Up @@ -178,3 +181,22 @@ impl crate::framework::Example for Example {
pub fn main() {
crate::framework::run::<Example>("mesh_shader");
}

#[cfg(test)]
#[wgpu_test::gpu_test]
pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams {
name: "mesh_shader",
image_path: "/examples/features/src/mesh_shader/screenshot.png",
width: 1024,
height: 768,
optional_features: wgpu::Features::default(),
base_test_parameters: wgpu_test::TestParameters::default()
.test_features_limits()
.features(
wgpu::Features::EXPERIMENTAL_MESH_SHADER
| wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS,
)
.limits(wgpu::Limits::default().using_recommended_minimum_mesh_shader_values()),
comparisons: &[wgpu_test::ComparisonType::Mean(0.02)],
_phantom: std::marker::PhantomData::<Example>,
};
Binary file added examples/features/src/mesh_shader/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
117 changes: 117 additions & 0 deletions examples/features/src/precompiled_shader/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use crate::framework;

pub struct Example {
pipeline: wgpu::RenderPipeline,
}
impl framework::Example for Example {
fn init(
config: &wgpu::SurfaceConfiguration,
_adapter: &wgpu::Adapter,
device: &wgpu::Device,
_queue: &wgpu::Queue,
) -> Self {
let vs_shader = unsafe {
device.create_shader_module_passthrough(wgpu::include_precompiled_wgsl!(
"src/hello_triangle/shader.wgsl",
"vs_main",
all
))
};
let fs_shader = unsafe {
device.create_shader_module_passthrough(wgpu::include_precompiled_wgsl!(
"src/hello_triangle/shader.wgsl",
"fs_main",
all
))
};

let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: &[],
push_constant_ranges: &[],
});
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: &vs_shader,
entry_point: Some("vs_main"),
buffers: &[],
compilation_options: Default::default(),
},
fragment: Some(wgpu::FragmentState {
module: &fs_shader,
entry_point: Some("fs_main"),
compilation_options: Default::default(),
targets: &[Some(config.format.into())],
}),
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
multiview: None,
cache: None,
});
Self { pipeline }
}
fn render(&mut self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue) {
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
{
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: None,
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view,
depth_slice: None,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
rpass.set_pipeline(&self.pipeline);
rpass.draw(0..3, 0..1);
}

queue.submit(Some(encoder.finish()));
}
fn update(&mut self, _event: winit::event::WindowEvent) {}
fn resize(
&mut self,
_config: &wgpu::SurfaceConfiguration,
_device: &wgpu::Device,
_queue: &wgpu::Queue,
) {
}
fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities {
wgpu::DownlevelCapabilities::default()
}
fn required_features() -> wgpu::Features {
wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS
}
fn required_limits() -> wgpu::Limits {
wgpu::Limits::defaults()
}
}

pub fn main() {
crate::framework::run::<Example>("precompiled_shader");
}

#[cfg(test)]
#[wgpu_test::gpu_test]
pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams {
name: "precompiled_shader",
image_path: "/examples/features/src/mesh_shader/screenshot.png",
width: 1024,
height: 768,
optional_features: wgpu::Features::default(),
base_test_parameters: wgpu_test::TestParameters::default()
.test_features_limits()
.features(wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS),
comparisons: &[wgpu_test::ComparisonType::Mean(0.02)],
_phantom: std::marker::PhantomData::<Example>,
};
Loading
Loading