Skip to content

Commit

Permalink
Added support for MSAA(x2,x8) beyond WEBGPU restrictions for native a… (
Browse files Browse the repository at this point in the history
#3140)

Closes #2910
  • Loading branch information
39ali authored Nov 9, 2022
1 parent 04d12ba commit 3c82a4c
Show file tree
Hide file tree
Showing 16 changed files with 213 additions and 72 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Bottom level categories:
- New downlevel feature `UNRESTRICTED_INDEX_BUFFER` to indicate support for using `INDEX` together with other non-copy/map usages (unsupported on WebGL). By @Wumpf in [#3157](https://github.com/gfx-rs/wgpu/pull/3157)

#### WebGPU

- Implement `queue_validate_write_buffer` by @jinleili in [#3098](https://github.com/gfx-rs/wgpu/pull/3098)

#### GLES
Expand All @@ -64,12 +65,17 @@ Bottom level categories:
- Add the `"wgsl"` feature, to enable WGSL shaders in `wgpu-core` and `wgpu`. Enabled by default in `wgpu`. By @daxpedda in [#2890](https://github.com/gfx-rs/wgpu/pull/2890).
- Implement `Clone` for `ShaderSource` and `ShaderModuleDescriptor` in `wgpu`. By @daxpedda in [#3086](https://github.com/gfx-rs/wgpu/pull/3086).
- Add `get_default_config` for `Surface` to simplify user creation of `SurfaceConfiguration`. By @jinleili in [#3034](https://github.com/gfx-rs/wgpu/pull/3034)
- Native adapters can now use MSAA x2 and x8 if it's supported , previously only x1 and x4 were supported . By @39ali in [3140](https://github.com/gfx-rs/wgpu/pull/3140)

#### GLES

- Surfaces support now `TextureFormat::Rgba8Unorm` and (non-web only) `TextureFormat::Bgra8Unorm`. By @Wumpf in [#3070](https://github.com/gfx-rs/wgpu/pull/3070)
- Support alpha to coverage. By @Wumpf in [#3156](https://github.com/gfx-rs/wgpu/pull/3156)

#### WebGPU

- Add `MULTISAMPLE_X2`, `MULTISAMPLE_X4` and `MULTISAMPLE_X8` to `TextureFormatFeatureFlags`. By @39ali in [3140](https://github.com/gfx-rs/wgpu/pull/3140)

### Bug Fixes

#### General
Expand All @@ -81,6 +87,7 @@ Bottom level categories:
- Fix an integer overflow in `queue_write_texture` by @nical in (#3146)[https://github.com/gfx-rs/wgpu/pull/3146]

#### WebGPU

- Use `log` instead of `println` in hello example by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858)

#### GLES
Expand All @@ -95,6 +102,7 @@ Bottom level categories:
By @jimblandy in [#3171](https://github.com/gfx-rs/wgpu/pull/3171)

### Examples

- Log adapter info in hello example on wasm target by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858)

### Testing/Internal
Expand Down Expand Up @@ -204,6 +212,7 @@ both `raw_window_handle::HasRawWindowHandle` and `raw_window_handle::HasRawDispl
- Report Apple M2 gpu as integrated. By @i509VCB [#3036](https://github.com/gfx-rs/wgpu/pull/3036)

#### WebGPU

- When called in a web worker, `Context::init()` now uses `web_sys::WorkerGlobalContext` to create a `wgpu::Instance` instead of trying to access the unavailable `web_sys::Window` by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858)

### Changes
Expand Down Expand Up @@ -359,6 +368,7 @@ Added items to the public API
- Update present_mode docs as most of them don't automatically fall back to Fifo anymore. by @Elabajaba in [#2855](https://github.com/gfx-rs/wgpu/pull/2855)

#### Hal

- Document safety requirements for `Adapter::from_external` in gles hal by @i509VCB in [#2863](https://github.com/gfx-rs/wgpu/pull/2863)
- Make `AdapterContext` a publicly accessible type in the gles hal by @i509VCB in [#2870](https://github.com/gfx-rs/wgpu/pull/2870)

Expand Down
3 changes: 0 additions & 3 deletions wgpu-core/src/command/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,9 +732,6 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
expected: sample_count,
});
}
if sample_count != 1 && sample_count != 4 {
return Err(RenderPassErrorInner::InvalidSampleCount(sample_count));
}
attachment_type_name = type_name;
Ok(())
};
Expand Down
26 changes: 21 additions & 5 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,12 +811,23 @@ impl<A: HalApi> Device<A> {
return Err(CreateTextureError::MultisampledNotRenderAttachment);
}

if !format_features.flags.intersects(
wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4
| wgt::TextureFormatFeatureFlags::MULTISAMPLE_X2
| wgt::TextureFormatFeatureFlags::MULTISAMPLE_X8,
) {
return Err(CreateTextureError::InvalidMultisampledFormat(desc.format));
}

if !format_features
.flags
.contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE)
.sample_count_supported(desc.sample_count)
{
return Err(CreateTextureError::InvalidMultisampledFormat(desc.format));
}
return Err(CreateTextureError::InvalidSampleCount(
desc.sample_count,
desc.format,
));
};
}

let mips = desc.mip_level_count;
Expand Down Expand Up @@ -2665,7 +2676,9 @@ impl<A: HalApi> Device<A> {
break Some(pipeline::ColorStateError::FormatNotColor(cs.format));
}
if desc.multisample.count > 1
&& !format_features.flags.contains(Tfff::MULTISAMPLE)
&& !format_features
.flags
.sample_count_supported(desc.multisample.count)
{
break Some(pipeline::ColorStateError::FormatNotMultisampled(cs.format));
}
Expand Down Expand Up @@ -2699,7 +2712,10 @@ impl<A: HalApi> Device<A> {
ds.format,
));
}
if desc.multisample.count > 1 && !format_features.flags.contains(Tfff::MULTISAMPLE)
if desc.multisample.count > 1
&& !format_features
.flags
.sample_count_supported(desc.multisample.count)
{
break Some(pipeline::DepthStencilStateError::FormatNotMultisampled(
ds.format,
Expand Down
13 changes: 11 additions & 2 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,18 @@ impl<A: HalApi> Adapter<A> {
);

flags.set(
wgt::TextureFormatFeatureFlags::MULTISAMPLE,
caps.contains(Tfc::MULTISAMPLE),
wgt::TextureFormatFeatureFlags::MULTISAMPLE_X2,
caps.contains(Tfc::MULTISAMPLE_X2),
);
flags.set(
wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4,
caps.contains(Tfc::MULTISAMPLE_X4),
);
flags.set(
wgt::TextureFormatFeatureFlags::MULTISAMPLE_X8,
caps.contains(Tfc::MULTISAMPLE_X8),
);

flags.set(
wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE,
caps.contains(Tfc::MULTISAMPLE_RESOLVE),
Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/src/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
hal_usage: conv::map_texture_usage(config.usage, config.format.into()),
format_features: wgt::TextureFormatFeatures {
allowed_usages: wgt::TextureUsages::RENDER_ATTACHMENT,
flags: wgt::TextureFormatFeatureFlags::MULTISAMPLE
flags: wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4
| wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE,
},
initialization_status: TextureInitTracker::new(1, 1),
Expand Down
2 changes: 2 additions & 0 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,8 @@ pub enum CreateTextureError {
MultisampledNotRenderAttachment,
#[error("Texture format {0:?} can't be used due to missing features.")]
MissingFeatures(wgt::TextureFormat, #[source] MissingFeatures),
#[error("Sample count {0} is not supported by format {1:?} on this device. It may be supported by your adapter through the TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES feature.")]
InvalidSampleCount(u32, wgt::TextureFormat),
}

impl<A: hal::Api> Resource for Texture<A> {
Expand Down
27 changes: 26 additions & 1 deletion wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,12 +446,37 @@ impl crate::Adapter<super::Api> for super::Adapter {
| d3d12::D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL)
!= 0
&& data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RENDERTARGET == 0;
caps.set(Tfc::MULTISAMPLE, !no_msaa_load && !no_msaa_target);

caps.set(
Tfc::MULTISAMPLE_RESOLVE,
data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE != 0,
);

let mut ms_levels = d3d12::D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS {
Format: raw_format,
SampleCount: 0,
Flags: d3d12::D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE,
NumQualityLevels: 0,
};

let mut set_sample_count = |sc: u32, tfc: Tfc| {
ms_levels.SampleCount = sc;

if self.device.CheckFeatureSupport(
d3d12::D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
<*mut _>::cast(&mut ms_levels),
mem::size_of::<d3d12::D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS>() as _,
) == winerror::S_OK
&& ms_levels.NumQualityLevels != 0
{
caps.set(tfc, !no_msaa_load && !no_msaa_target);
}
};

set_sample_count(2, Tfc::MULTISAMPLE_X2);
set_sample_count(4, Tfc::MULTISAMPLE_X4);
set_sample_count(8, Tfc::MULTISAMPLE_X8);

caps
}

Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ impl crate::Adapter<Api> for Context {
) -> crate::TextureFormatCapabilities {
crate::TextureFormatCapabilities::empty()
}

unsafe fn surface_capabilities(&self, surface: &Context) -> Option<crate::SurfaceCapabilities> {
None
}
Expand Down
20 changes: 17 additions & 3 deletions wgpu-hal/src/gles/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ impl super::Adapter {
(vendor, renderer)
};
let version = gl.get_parameter_string(glow::VERSION);

log::info!("Vendor: {}", vendor);
log::info!("Renderer: {}", renderer);
log::info!("Version: {}", version);
Expand Down Expand Up @@ -664,17 +663,32 @@ impl crate::Adapter<super::Api> for super::Adapter {
use crate::TextureFormatCapabilities as Tfc;
use wgt::TextureFormat as Tf;

let sample_count = {
let max_samples = self
.shared
.context
.lock()
.get_parameter_i32(glow::MAX_SAMPLES);
if max_samples >= 8 {
Tfc::MULTISAMPLE_X2 | Tfc::MULTISAMPLE_X4 | Tfc::MULTISAMPLE_X8
} else if max_samples >= 4 {
Tfc::MULTISAMPLE_X2 | Tfc::MULTISAMPLE_X4
} else {
Tfc::MULTISAMPLE_X2
}
};

// Base types are pulled from the table in the OpenGLES 3.0 spec in section 3.8.
//
// The storage types are based on table 8.26, in section
// "TEXTURE IMAGE LOADS AND STORES" of OpenGLES-3.2 spec.
let empty = Tfc::empty();
let base = Tfc::COPY_SRC | Tfc::COPY_DST;
let unfilterable = base | Tfc::SAMPLED;
let depth = base | Tfc::SAMPLED | Tfc::MULTISAMPLE | Tfc::DEPTH_STENCIL_ATTACHMENT;
let depth = base | Tfc::SAMPLED | sample_count | Tfc::DEPTH_STENCIL_ATTACHMENT;
let filterable = unfilterable | Tfc::SAMPLED_LINEAR;
let renderable =
unfilterable | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE | Tfc::MULTISAMPLE_RESOLVE;
unfilterable | Tfc::COLOR_ATTACHMENT | sample_count | Tfc::MULTISAMPLE_RESOLVE;
let filterable_renderable = filterable | renderable | Tfc::COLOR_ATTACHMENT_BLEND;
let storage = base | Tfc::STORAGE | Tfc::STORAGE_READ_WRITE;

Expand Down
15 changes: 10 additions & 5 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,15 +582,20 @@ bitflags!(
/// Format can be used as depth-stencil and input attachment.
const DEPTH_STENCIL_ATTACHMENT = 1 << 8;

/// Format can be multisampled.
const MULTISAMPLE = 1 << 9;
/// Format can be multisampled by x2.
const MULTISAMPLE_X2 = 1 << 9;
/// Format can be multisampled by x4.
const MULTISAMPLE_X4 = 1 << 10;
/// Format can be multisampled by x8.
const MULTISAMPLE_X8 = 1 << 11;

/// Format can be used for render pass resolve targets.
const MULTISAMPLE_RESOLVE = 1 << 10;
const MULTISAMPLE_RESOLVE = 1 << 12;

/// Format can be copied from.
const COPY_SRC = 1 << 11;
const COPY_SRC = 1 << 13;
/// Format can be copied to.
const COPY_DST = 1 << 12;
const COPY_DST = 1 << 14;
}
);

Expand Down
Loading

0 comments on commit 3c82a4c

Please sign in to comment.