Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
375cf49
Exposed new limits for multiview
inner-daemons Sep 10, 2025
88fcb2f
Added multiview view count checks
inner-daemons Sep 10, 2025
9e20b55
Added check for instance limit
inner-daemons Sep 10, 2025
f8ab779
Added multiview test
inner-daemons Sep 10, 2025
56f8fc1
Fixed various compile issues
inner-daemons Sep 10, 2025
c103f42
Updated multiview test (idk what I'm doing)
inner-daemons Sep 10, 2025
06ce95c
Updated test again
inner-daemons Sep 10, 2025
d456310
Fixed shader hopefully
inner-daemons Sep 10, 2025
de5b1be
Added some of the functionality to dx12
inner-daemons Sep 11, 2025
263aa77
Added multiview mask parameter (didn't update all code to use this pa…
inner-daemons Sep 11, 2025
eca707f
Added multiview to HLSL writer
inner-daemons Sep 11, 2025
84334ba
Merge branch 'trunk' into multiview-tests-limits
inner-daemons Sep 15, 2025
1860e5f
Other merge commit
inner-daemons Sep 15, 2025
ac82457
Added changelog entry which assumes the view bitmask is allowed
inner-daemons Sep 15, 2025
3083f16
Merge branch 'trunk' into multiview-tests-limits
inner-daemons Sep 19, 2025
424f31e
Updated changelog
inner-daemons Sep 22, 2025
f933d2c
Exposed feature on metal, commented dx12, restricted vulkan to <=64 d…
inner-daemons Sep 22, 2025
13b012f
Updated multiview for metal
inner-daemons Sep 22, 2025
0cff8c5
Added view index thing to msl writer
inner-daemons Sep 22, 2025
bf9775a
Finalized MSL writer changes
inner-daemons Sep 22, 2025
4ba4759
Removed nonsense multiview mask from boids example, fixed wgpu-hal ex…
inner-daemons Sep 22, 2025
863283f
Mopped up miscellaneous crates, going to work on tests & examples now
inner-daemons Sep 22, 2025
ccec13b
Fixed examples
inner-daemons Sep 22, 2025
c6da54a
Fixed every test
inner-daemons Sep 22, 2025
e465389
Updated changelog entry
inner-daemons Sep 22, 2025
30438b3
Made multiview use 32bit integer
inner-daemons Sep 22, 2025
2a29de8
Merge branch 'trunk' into multiview-tests-limits
inner-daemons Sep 22, 2025
f20eaac
Made the default multiview mask 0
inner-daemons Sep 22, 2025
1528421
Fixed snapshots, final changelog update hopefully
inner-daemons Sep 22, 2025
81b681f
Reformatted multiview.toml
inner-daemons Sep 22, 2025
b04c75b
Fixed GLSL writer
inner-daemons Sep 22, 2025
d0ab6d4
Attempted to fix temporarily the HLSL stuff
inner-daemons Sep 22, 2025
63ce399
Made HLSL writer throw error if shader model is unsupported
inner-daemons Sep 22, 2025
11203bb
Fixed webgl writing
inner-daemons Sep 22, 2025
dbe1400
Fixed typos and hopefully also glsl (non-webgl) validation
inner-daemons Sep 22, 2025
7f8542d
Actually updated fixed snapshots
inner-daemons Sep 22, 2025
7d66fec
I think we're doing illegal shit in metal and somehow the second text…
inner-daemons Sep 23, 2025
5e3e662
Fixed illegal behavior in shader that naga currently allows
inner-daemons Sep 23, 2025
69120f3
Merge branch 'trunk' into multiview-tests-limits
inner-daemons Oct 1, 2025
f612d0f
Fixed compiles
inner-daemons Oct 1, 2025
988bc37
Tried to fix windows compiles
inner-daemons Oct 1, 2025
bd696d4
Updated multiview test to provide more information
inner-daemons Oct 1, 2025
15da620
ChatGPT thinks it fixed the vulkan backend (lets see!)
inner-daemons Oct 1, 2025
27035dd
ChatGPT also failed to fix metal backend lmao
inner-daemons Oct 1, 2025
e8b7452
Undid fake fix for metal
inner-daemons Oct 1, 2025
b4ce29b
Tried to fix again (still broken on metal but maybe this'll fix vulka…
inner-daemons Oct 1, 2025
a799a24
I'm not having fun :(
inner-daemons Oct 1, 2025
35536f9
Merge remote-tracking branch 'upstream/trunk' into multiview-tests-li…
inner-daemons Oct 2, 2025
9093910
Updated test to rely on new poll syntax
inner-daemons Oct 2, 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
28 changes: 27 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,33 @@ Bottom level categories:

## Unreleased

### Major Changes

#### Multiview on all major platforms and support for multiview bitmasks

Multiview has been reworked, adding support for DX12 and Metal, and adding testing and validation to wgpu itself.
This change also introduces a view bitmask, a new field in `RenderPassDescriptor` that allows a render pass to render multiple to non-adjacent layers. Note that this also influences apps that don't use multiview, as they have to set this field to `None`.
```diff
- wgpu::RenderPassDescriptor {
- label: None,
- color_attachments: &color_attachments,
- depth_stencil_attachment: None,
- timestamp_writes: None,
- occlusion_query_set: None,
- }
+ wgpu::RenderPassDescriptor {
+ label: None,
+ color_attachments: &color_attachments,
+ depth_stencil_attachment: None,
+ timestamp_writes: None,
+ occlusion_query_set: None,
+ multiview_mask: NonZero::new(3),
+ }
```
One other breaking change worth noting is that `@builtin(view_index)` now requires a type of `u32`, where previously it required `i32`.

By @SupaMaggie70Incorporated in [#8206](https://github.com/gfx-rs/wgpu/pull/8206).

## v27.0.0 (2025-10-01)

### Major Changes
Expand Down Expand Up @@ -161,7 +188,6 @@ by if the `Feature::MULTI_DRAW_INDIRECT_COUNT` feature is available on the devic

By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162).


#### `wgpu::PollType::Wait` has now an optional timeout

We removed `wgpu::PollType::WaitForSubmissionIndex` and added fields to `wgpu::PollType::Wait` in order to express timeouts.
Expand Down
2 changes: 2 additions & 0 deletions benches/benches/wgpu-benchmark/renderpass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ impl RenderpassState {
occlusion_query_set: None,
timestamp_writes: None,
depth_stencil_attachment: None,
multiview_mask: None,
});

let start_idx = pass_number * draws_per_pass;
Expand Down Expand Up @@ -417,6 +418,7 @@ impl RenderpassState {
occlusion_query_set: None,
timestamp_writes: None,
depth_stencil_attachment: None,
multiview_mask: None,
});

render_pass.set_pipeline(self.bindless_pipeline.as_ref().unwrap());
Expand Down
2 changes: 2 additions & 0 deletions deno_webgpu/command_encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::borrow::Cow;
use std::cell::RefCell;
use std::num::NonZero;

use deno_core::cppgc::Ptr;
use deno_core::op2;
Expand Down Expand Up @@ -142,6 +143,7 @@ impl GPUCommandEncoder {
occlusion_query_set: descriptor
.occlusion_query_set
.map(|query_set| query_set.id),
multiview_mask: NonZero::new(descriptor.multiview_mask),
};

let (render_pass, err) = self
Expand Down
3 changes: 3 additions & 0 deletions deno_webgpu/render_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,9 @@ pub(crate) struct GPURenderPassDescriptor {
/*#[webidl(default = 50000000)]
#[options(enforce_range = true)]
pub max_draw_count: u64,*/
#[webidl(default = 0)]
#[options(enforce_range = true)]
pub multiview_mask: u32,
}

#[derive(WebIDL)]
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/boids/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
};

// get command encoder
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/bunnymark/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ impl Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.set_pipeline(&self.pipeline);
rpass.set_bind_group(0, &self.global_group, &[]);
Expand Down
2 changes: 2 additions & 0 deletions examples/features/src/conservative_raster/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.pipeline_triangle_conservative);
Expand All @@ -295,6 +296,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.pipeline_upscale);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/cube/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.push_debug_group("Prepare data for draw.");
rpass.set_pipeline(&self.pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/hello_triangle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.set_pipeline(&render_pipeline);
rpass.draw(0..3, 0..1);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/hello_windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ async fn run(event_loop: EventLoop<()>, viewports: Vec<(Arc<Window>, wgpu::Color
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
}

Expand Down
1 change: 1 addition & 0 deletions examples/features/src/mesh_shader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.push_debug_group("Prepare data for draw.");
rpass.set_pipeline(&self.pipeline);
Expand Down
2 changes: 2 additions & 0 deletions examples/features/src/mipmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ impl Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
if let Some(ref query_sets) = query_sets {
rpass.write_timestamp(&query_sets.timestamp, timestamp_query_index_base);
Expand Down Expand Up @@ -492,6 +493,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.set_pipeline(&self.draw_pipeline);
rpass.set_bind_group(0, &self.bind_group, &[]);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/msaa_line/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
})
.execute_bundles(iter::once(&self.bundle));
}
Expand Down
2 changes: 2 additions & 0 deletions examples/features/src/multiple_render_targets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ impl MultiTargetRenderer {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.set_pipeline(&self.pipeline);
rpass.set_bind_group(0, &self.bindgroup, &[]);
Expand Down Expand Up @@ -339,6 +340,7 @@ impl TargetRenderer {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.set_pipeline(&self.pipeline);
rpass.set_bind_group(0, &self.bindgroup_left, &[]);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/ray_cube_compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.blit_pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/ray_cube_fragment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/ray_cube_normals/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.blit_pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/ray_scene/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/ray_shadows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/ray_traced_triangle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.blit_pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/render_to_texture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ async fn run(_path: Option<String>) {
depth_stencil_attachment: None,
occlusion_query_set: None,
timestamp_writes: None,
multiview_mask: None,
});
render_pass.set_pipeline(&pipeline);
render_pass.draw(0..3, 0..1);
Expand Down
2 changes: 2 additions & 0 deletions examples/features/src/shadow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ impl crate::framework::Example for Example {
}),
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
pass.set_pipeline(&self.shadow_pass.pipeline);
pass.set_bind_group(0, &self.shadow_pass.bind_group, &[]);
Expand Down Expand Up @@ -816,6 +817,7 @@ impl crate::framework::Example for Example {
}),
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
pass.set_pipeline(&self.forward_pass.pipeline);
pass.set_bind_group(0, &self.forward_pass.bind_group, &[]);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/skybox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ impl crate::framework::Example for Example {
}),
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_bind_group(0, &self.bind_group, &[]);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/srgb_blend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ impl<const SRGB: bool> crate::framework::Example for Example<SRGB> {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.push_debug_group("Prepare data for draw.");
rpass.set_pipeline(&self.pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/stencil_triangles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ impl crate::framework::Example for Example {
}),
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_stencil_reference(1);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/texture_arrays/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ impl crate::framework::Example for Example {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/features/src/timestamp_queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ fn render_pass(
end_of_pass_write_index: Some(*next_unused_query + 1),
}),
occlusion_query_set: None,
multiview_mask: None,
});
*next_unused_query += 2;

Expand Down
1 change: 1 addition & 0 deletions examples/features/src/uniform_values/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ async fn run(event_loop: EventLoop<()>, window: Arc<Window>) {
depth_stencil_attachment: None,
occlusion_query_set: None,
timestamp_writes: None,
multiview_mask: None,
});
render_pass.set_pipeline(&wgpu_context_ref.pipeline);
// (9)
Expand Down
3 changes: 3 additions & 0 deletions examples/features/src/water/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,7 @@ impl crate::framework::Example for Example {
}),
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.execute_bundles([&self.terrain_bundle]);
Expand Down Expand Up @@ -778,6 +779,7 @@ impl crate::framework::Example for Example {
}),
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
rpass.set_pipeline(&self.terrain_pipeline);
rpass.set_bind_group(0, &self.terrain_normal_bind_group, &[]);
Expand Down Expand Up @@ -805,6 +807,7 @@ impl crate::framework::Example for Example {
}),
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

rpass.set_pipeline(&self.water_pipeline);
Expand Down
1 change: 1 addition & 0 deletions examples/standalone/02_hello_window/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl State {
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});

// If you wanted to call any drawing commands, they would go here.
Expand Down
9 changes: 7 additions & 2 deletions naga/src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5204,8 +5204,13 @@ const fn glsl_built_in(built_in: crate::BuiltIn, options: VaryingOptions) -> &'s
"gl_FragCoord"
}
}
Bi::ViewIndex if options.targeting_webgl => "int(gl_ViewID_OVR)",
Bi::ViewIndex => "gl_ViewIndex",
Bi::ViewIndex => {
if options.targeting_webgl {
"gl_ViewID_OVR"
} else {
"uint(gl_ViewIndex)"
}
}
// vertex
Bi::BaseInstance => "uint(gl_BaseInstance)",
Bi::BaseVertex => "uint(gl_BaseVertex)",
Expand Down
3 changes: 2 additions & 1 deletion naga/src/back/hlsl/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ impl crate::BuiltIn {
// to this field will get replaced with references to `SPECIAL_CBUF_VAR`
// in `Writer::write_expr`.
Self::NumWorkGroups => "SV_GroupID",
Self::ViewIndex => "SV_ViewID",
// These builtins map to functions
Self::SubgroupSize
| Self::SubgroupInvocationId
Expand All @@ -180,7 +181,7 @@ impl crate::BuiltIn {
Self::BaseInstance | Self::BaseVertex | Self::WorkGroupSize => {
return Err(Error::Unimplemented(format!("builtin {self:?}")))
}
Self::PointSize | Self::ViewIndex | Self::PointCoord | Self::DrawID => {
Self::PointSize | Self::PointCoord | Self::DrawID => {
return Err(Error::Custom(format!("Unsupported builtin {self:?}")))
}
})
Expand Down
2 changes: 2 additions & 0 deletions naga/src/back/hlsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,8 @@ pub enum Error {
ResolveArraySizeError(#[from] proc::ResolveArraySizeError),
#[error("entry point with stage {0:?} and name '{1}' not found")]
EntryPointNotFound(ir::ShaderStage, String),
#[error("requires shader model {1:?} for reason: {0}")]
ShaderModelTooLow(String, ShaderModel),
}

#[derive(PartialEq, Eq, Hash)]
Expand Down
8 changes: 8 additions & 0 deletions naga/src/back/hlsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
) -> BackendResult {
match *binding {
Some(crate::Binding::BuiltIn(builtin)) if !is_subgroup_builtin_binding(binding) => {
if builtin == crate::BuiltIn::ViewIndex
&& self.options.shader_model < ShaderModel::V6_1
{
return Err(Error::ShaderModelTooLow(
"used @builtin(view_index) or SV_ViewID".to_string(),
ShaderModel::V6_1,
));
}
let builtin_str = builtin.to_hlsl_str()?;
write!(self.out, " : {builtin_str}")?;
}
Expand Down
Loading
Loading