Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPU spec compliant dual source blending #7144

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 39 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,45 @@ Bottom level categories:

## Unreleased

### Major changes

#### Split up `Features` internally

Internally split up the `Features` struct and recombine them internally using a macro. There should be no breaking
changes from this. This means there are also namespaces (as well as the old `Features::*`) for all wgpu specific
features and webgpu feature (`FeaturesWGPU` and `FeaturesWebGPU` respectively) and `Features::from_internal_flags` which
allow you to be explicit about whether features you need are available on the web too.

By @Vecvec in [#6905](https://github.com/gfx-rs/wgpu/pull/6905), [#7086](https://github.com/gfx-rs/wgpu/pull/7086)

#### Refactored internal trace path parameter

Refactored some functions to handle the internal trace path as a string to avoid possible issues with `no_std` support.

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

#### WebGPU compliant dual source blending feature

Previously, dual source blending was implemented with a `wgpu` native only feature flag and used a custom syntax in wgpu.
By now, dual source blending was added to the [WebGPU spec as an extension](https://www.w3.org/TR/webgpu/#dom-gpufeaturename-dual-source-blending).
We're now following suite and implement the official syntax.

Existing shaders using dual source blending need to be updated:

```diff
struct FragmentOutput{
- @location(0) source0: vec4<f32>,
- @location(0) @second_blend_source source1: vec4<f32>,
+ @location(0) @blend_src(0) source0: vec4<f32>,
+ @location(0) @blend_src(1) source1: vec4<f32>,
}

```

With that `wgpu::Features::DUAL_SOURCE_BLENDING` is now available on WebGPU.

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

### New Features

#### Naga
Expand All @@ -56,20 +95,6 @@ Bottom level categories:
- Rename `instance_id` and `instance_custom_index` to `instance_index` and `instance_custom_data` by @Vecvec in
[#6780](https://github.com/gfx-rs/wgpu/pull/6780)

##### Split up `Features` internally

Internally split up the `Features` struct and recombine them internally using a macro. There should be no breaking
changes from this. This means there are also namespaces (as well as the old `Features::*`) for all wgpu specific
features and webgpu feature (`FeaturesWGPU` and `FeaturesWebGPU` respectively) and `Features::from_internal_flags` which
allow you to be explicit about whether features you need are available on the web too.

By @Vecvec in [#6905](https://github.com/gfx-rs/wgpu/pull/6905), [#7086](https://github.com/gfx-rs/wgpu/pull/7086)

##### Refactored internal trace path parameter

Refactored some functions to handle the internal trace path as a string to avoid possible issues with `no_std` support.

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

#### Vulkan

Expand Down
4 changes: 2 additions & 2 deletions naga/src/back/glsl/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,15 +604,15 @@ impl<W> Writer<'_, W> {
location: _,
interpolation,
sampling,
second_blend_source,
blend_src,
} => {
if interpolation == Some(Interpolation::Linear) {
self.features.request(Features::NOPERSPECTIVE_QUALIFIER);
}
if sampling == Some(Sampling::Sample) {
self.features.request(Features::SAMPLE_QUALIFIER);
}
if second_blend_source {
if blend_src.is_some() {
self.features.request(Features::DUAL_SOURCE_BLENDING);
}
}
Expand Down
20 changes: 11 additions & 9 deletions naga/src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,7 @@ impl fmt::Display for VaryingName<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self.binding {
crate::Binding::Location {
second_blend_source: true,
..
blend_src: Some(1), ..
} => {
write!(f, "_fs2p_location1",)
}
Expand Down Expand Up @@ -1465,13 +1464,13 @@ impl<'a, W: Write> Writer<'a, W> {
Some(binding) => binding,
};

let (location, interpolation, sampling, second_blend_source) = match *binding {
let (location, interpolation, sampling, blend_src) = match *binding {
crate::Binding::Location {
location,
interpolation,
sampling,
second_blend_source,
} => (location, interpolation, sampling, second_blend_source),
blend_src,
} => (location, interpolation, sampling, blend_src),
crate::Binding::BuiltIn(built_in) => {
if let crate::BuiltIn::Position { invariant: true } = built_in {
match (self.options.version, self.entry_point.stage) {
Expand Down Expand Up @@ -1518,16 +1517,19 @@ impl<'a, W: Write> Writer<'a, W> {
|| !emit_interpolation_and_auxiliary
{
if self.options.version.supports_io_locations() {
if second_blend_source {
write!(self.out, "layout(location = {location}, index = 1) ")?;
if let Some(blend_src) = blend_src {
write!(
self.out,
"layout(location = {location}, index = {blend_src}) "
)?;
} else {
write!(self.out, "layout(location = {location}) ")?;
}
None
} else {
Some(VaryingLocation {
location,
index: second_blend_source as u32,
index: blend_src.unwrap_or(0),
})
}
} else {
Expand Down Expand Up @@ -1568,7 +1570,7 @@ impl<'a, W: Write> Writer<'a, W> {
location,
interpolation: None,
sampling: None,
second_blend_source,
blend_src,
},
stage: self.entry_point.stage,
options: VaryingOptions::from_writer_options(self.options, output),
Expand Down
9 changes: 2 additions & 7 deletions naga/src/back/hlsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,16 +523,11 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
write!(self.out, " : {builtin_str}")?;
}
Some(crate::Binding::Location {
second_blend_source: true,
..
blend_src: Some(1), ..
}) => {
write!(self.out, " : SV_Target1")?;
}
Some(crate::Binding::Location {
location,
second_blend_source: false,
..
}) => {
Some(crate::Binding::Location { location, .. }) => {
if stage == Some((ShaderStage::Fragment, Io::Output)) {
write!(self.out, " : SV_Target{location}")?;
} else {
Expand Down
18 changes: 8 additions & 10 deletions naga/src/back/msl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ enum ResolvedBinding {
Attribute(u32),
Color {
location: u32,
second_blend_source: bool,
blend_src: Option<u32>,
},
User {
prefix: &'static str,
Expand Down Expand Up @@ -433,18 +433,16 @@ impl Options {
location,
interpolation,
sampling,
second_blend_source,
blend_src,
} => match mode {
LocationMode::VertexInput => Ok(ResolvedBinding::Attribute(location)),
LocationMode::FragmentOutput => {
if second_blend_source && self.lang_version < (1, 2) {
return Err(Error::UnsupportedAttribute(
"second_blend_source".to_string(),
));
if blend_src.is_some() && self.lang_version < (1, 2) {
return Err(Error::UnsupportedAttribute("blend_src".to_string()));
}
Ok(ResolvedBinding::Color {
location,
second_blend_source,
blend_src,
})
}
LocationMode::VertexOutput | LocationMode::FragmentInput => {
Expand Down Expand Up @@ -606,10 +604,10 @@ impl ResolvedBinding {
Self::Attribute(index) => write!(out, "attribute({index})")?,
Self::Color {
location,
second_blend_source,
blend_src,
} => {
if second_blend_source {
write!(out, "color({location}) index(1)")?
if let Some(blend_src) = blend_src {
write!(out, "color({location}) index({blend_src})")?
} else {
write!(out, "color({location})")?
}
Expand Down
6 changes: 3 additions & 3 deletions naga/src/back/spv/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,7 @@ impl Writer {
location,
interpolation,
sampling,
second_blend_source,
blend_src,
} => {
self.decorate(id, Decoration::Location, &[location]);

Expand Down Expand Up @@ -1509,8 +1509,8 @@ impl Writer {
}
}
}
if second_blend_source {
self.decorate(id, Decoration::Index, &[1]);
if let Some(blend_src) = blend_src {
self.decorate(id, Decoration::Index, &[blend_src]);
}
}
crate::Binding::BuiltIn(built_in) => {
Expand Down
10 changes: 5 additions & 5 deletions naga/src/back/wgsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ enum Attribute {
Invariant,
Interpolate(Option<crate::Interpolation>, Option<crate::Sampling>),
Location(u32),
SecondBlendSource,
BlendSrc(u32),
Stage(ShaderStage),
WorkGroupSize([u32; 3]),
}
Expand Down Expand Up @@ -340,7 +340,7 @@ impl<W: Write> Writer<W> {
for attribute in attributes {
match *attribute {
Attribute::Location(id) => write!(self.out, "@location({id}) ")?,
Attribute::SecondBlendSource => write!(self.out, "@second_blend_source ")?,
Attribute::BlendSrc(blend_src) => write!(self.out, "@blend_src({blend_src}) ")?,
Attribute::BuiltIn(builtin_attrib) => {
let builtin = builtin_str(builtin_attrib)?;
write!(self.out, "@builtin({builtin}) ")?;
Expand Down Expand Up @@ -2162,7 +2162,7 @@ fn map_binding_to_attribute(binding: &crate::Binding) -> Vec<Attribute> {
location,
interpolation,
sampling,
second_blend_source: false,
blend_src: None,
} => vec![
Attribute::Location(location),
Attribute::Interpolate(interpolation, sampling),
Expand All @@ -2171,10 +2171,10 @@ fn map_binding_to_attribute(binding: &crate::Binding) -> Vec<Attribute> {
location,
interpolation,
sampling,
second_blend_source: true,
blend_src: Some(blend_src),
} => vec![
Attribute::Location(location),
Attribute::SecondBlendSource,
Attribute::BlendSrc(blend_src),
Attribute::Interpolate(interpolation, sampling),
],
}
Expand Down
4 changes: 2 additions & 2 deletions naga/src/front/glsl/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,7 @@ impl Context<'_> {
location,
interpolation,
sampling: None,
second_blend_source: false,
blend_src: None,
};
location += 1;

Expand Down Expand Up @@ -1478,7 +1478,7 @@ impl Context<'_> {
location,
interpolation,
sampling: None,
second_blend_source: false,
blend_src: None,
};
location += 1;
binding
Expand Down
2 changes: 1 addition & 1 deletion naga/src/front/glsl/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ impl Frontend {
location,
interpolation,
sampling,
second_blend_source: false,
blend_src: None,
},
handle,
storage,
Expand Down
2 changes: 1 addition & 1 deletion naga/src/front/interpolator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl crate::Binding {
location: _,
interpolation: ref mut interpolation @ None,
ref mut sampling,
second_blend_source: _,
blend_src: _,
} = *self
{
match ty.scalar_kind() {
Expand Down
2 changes: 1 addition & 1 deletion naga/src/front/spv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ impl Decoration {
location,
interpolation,
sampling,
second_blend_source: false,
blend_src: None,
}),
_ => Err(Error::MissingDecoration(spirv::Decoration::Location)),
}
Expand Down
10 changes: 8 additions & 2 deletions naga/src/front/wgsl/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3317,15 +3317,21 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
Some(ast::Binding::BuiltIn(b)) => Some(crate::Binding::BuiltIn(b)),
Some(ast::Binding::Location {
location,
second_blend_source,
interpolation,
sampling,
blend_src,
}) => {
let blend_src = if let Some(blend_src) = blend_src {
Some(self.const_u32(blend_src, &mut ctx.as_const())?.0)
} else {
None
};

let mut binding = crate::Binding::Location {
location: self.const_u32(location, &mut ctx.as_const())?.0,
second_blend_source,
interpolation,
sampling,
blend_src,
};
binding.apply_default_interpolation(&ctx.module.types[ty].inner);
Some(binding)
Expand Down
2 changes: 1 addition & 1 deletion naga/src/front/wgsl/parse/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ pub enum Binding<'a> {
BuiltIn(crate::BuiltIn),
Location {
location: Handle<Expression<'a>>,
second_blend_source: bool,
interpolation: Option<crate::Interpolation>,
sampling: Option<crate::Sampling>,
blend_src: Option<Handle<Expression<'a>>>,
},
}

Expand Down
Loading
Loading