diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7d37b83708..24cfaf6633 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,166 +8,170 @@ on: branches-ignore: [staging.tmp] jobs: - ios_build: - name: iOS Stable - runs-on: macos-10.15 - env: - TARGET: aarch64-apple-ios - steps: - - uses: actions/checkout@v2 - - run: rustup component add clippy - - run: rustup target add ${{ env.TARGET }} - - run: cargo clippy --target ${{ env.TARGET }} - - android_build: - name: Android Stable - runs-on: ubuntu-latest - env: - TARGET: aarch64-linux-android - PKG_CONFIG_ALLOW_CROSS: 1 - steps: - - uses: actions/checkout@v2 - - run: echo "$ANDROID_HOME/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin" >> $GITHUB_PATH - - run: rustup component add clippy - - run: rustup target add ${{ env.TARGET }} - - run: cargo clippy --target ${{ env.TARGET }} - - name: Additional core features - run: cargo check --manifest-path wgpu-core/Cargo.toml --features trace --target ${{ env.TARGET }} - - wasm: - name: Web Assembly - runs-on: ubuntu-latest - env: - RUSTFLAGS: --cfg=web_sys_unstable_apis - steps: - - uses: actions/checkout@v2 - - run: rustup target add wasm32-unknown-unknown - - name: Check WebGPU - run: cargo check --package wgpu --examples --target=wasm32-unknown-unknown - # disable until hal/Gles backend is setup - # - name: Check WebGL - # run: cargo check --all-targets --target=wasm32-unknown-unknown --features webgl - build: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [macos-10.15, ubuntu-20.04, windows-2019] - channel: [stable, nightly] include: - - name: MacOS Stable - channel: stable - os: macos-10.15 - prepare_command: - clippy_params: - additional_core_features: - additional_player_features: winit - wrapper_features: trace - - name: MacOS Nightly - os: macos-10.15 - channel: nightly - prepare_command: - clippy_params: - additional_core_features: - additional_player_features: - wrapper_features: - - name: Ubuntu Stable - os: ubuntu-20.04 - channel: stable - prepare_command: - clippy_params: --examples --all - additional_core_features: trace,serial-pass - additional_player_features: winit - wrapper_features: spirv,replay - - name: Ubuntu Nightly - os: ubuntu-20.04 - channel: nightly - prepare_command: | - echo "Installing Vulkan" - sudo apt-get update -y -qq - sudo add-apt-repository ppa:ubuntu-x-swat/updates -y - sudo apt-get update - sudo apt install -y libxcb-xfixes0-dev mesa-vulkan-drivers - clippy_params: - additional_core_features: serial-pass - additional_player_features: - wrapper_features: - - name: Windows Stable + # Windows + - name: Windows x86_64 os: windows-2019 channel: stable - prepare_command: rustup default stable-msvc - clippy_params: - additional_core_features: - additional_player_features: - wrapper_features: - - name: Windows Nightly - os: windows-2019 + target: x86_64-pc-windows-msvc + kind: compile + + # MacOS + + # Mac has no software runners, so don't run tests + - name: MacOS x86_64 + os: macos-10.15 + channel: stable + target: x86_64-apple-darwin + kind: compile + + + # IOS + - name: IOS aarch64 + os: macos-10.15 + channel: stable + target: aarch64-apple-ios + kind: compile + + + # Linux + - name: Linux x86_64 + os: ubuntu-20.04 + channel: stable + target: x86_64-unknown-linux-gnu + kind: test + + - name: Linux Nightly x86_64 + os: ubuntu-20.04 channel: nightly - prepare_command: rustup default nightly-msvc - clippy_params: - additional_core_features: - additional_player_features: - wrapper_features: + target: x86_64-unknown-linux-gnu + kind: compile + + + # Android + - name: Android aarch64 + os: ubuntu-20.04 + channel: stable + target: aarch64-linux-android + kind: compile + + + # WebGPU/WebGL + - name: WebAssembly + os: ubuntu-20.04 + channel: stable + target: wasm32-unknown-unknown + kind: webgl + + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + + env: + PKG_CONFIG_ALLOW_CROSS: 1 # allow android to work + RUSTFLAGS: --cfg=web_sys_unstable_apis + steps: - - uses: actions/checkout@v2 - - if: matrix.channel == 'nightly' - name: Install latest nightly + - name: checkout repo + uses: actions/checkout@v2 + + - name: install rust uses: actions-rs/toolchain@v1 with: - toolchain: nightly + toolchain: ${{ matrix.channel }} + target: ${{ matrix.target }} override: true - - if: matrix.clippy_params != '' - run: rustup component add clippy - # prepare - - if: matrix.prepare_command != '' - run: ${{ matrix.prepare_command }} - # regular build - - if: matrix.additional_core_features != '' - run: cargo check --manifest-path wgpu-core/Cargo.toml --features ${{ matrix.additional_core_features }} - - if: matrix.additional_player_features != '' - run: cargo check --manifest-path player/Cargo.toml --features ${{ matrix.additional_player_features }} - - run: cargo check --manifest-path wgpu/Cargo.toml --examples --features ${{ matrix.wrapper_features }}, - # clippy - - if: matrix.clippy_params != '' - run: cargo clippy ${{ matrix.clippy_params }} - - if: matrix.channel == 'nightly' - run: cargo test -p wgpu-core -- --nocapture - # - if: matrix.channel == 'nightly' - # run: cargo run --bin wgpu-info -- cargo test -p wgpu -- --nocapture + profile: minimal + components: clippy + - name: add android apk to path + if: matrix.os == 'ubuntu-20.04' && matrix.target == 'aarch64-linux-android' + run: | + echo "$ANDROID_HOME/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin" >> $GITHUB_PATH - docs: - runs-on: [ubuntu-latest] - steps: - - uses: actions/checkout@v2 - - name: Install latest nightly - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - override: true - continue-on-error: true - - name: cargo doc - run: cargo --version; cargo doc --no-deps - continue-on-error: true + - name: install llvmpipe and lavapipe + if: matrix.os == 'ubuntu-20.04' && matrix.kind == 'test' + run: | + echo "Installing Vulkan" + sudo apt-get update -y -qq + sudo add-apt-repository ppa:ubuntu-x-swat/updates -y + sudo apt-get update + sudo apt install -y libxcb-xfixes0-dev mesa-vulkan-drivers - lint: - name: Clippy + - name: load cache + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ matrix.name }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ matrix.name }}-cargo- + + # This is separate for now because webgl isn't hooked up so we can't compile wgpu-core for wasm + - name: check web + if: matrix.kind == 'webgl' + run: | + cargo clippy --target ${{ matrix.target }} -p wgpu -- -D warnings + + - name: check native stable (fatal warnings) + if: (matrix.kind == 'compile' || matrix.kind == 'test') && matrix.channel == 'stable' + run: | + # check with no features + cargo clippy --target ${{ matrix.target }} -p wgpu -p wgpu-core -p wgpu-info -p player -- -D warnings + + # check with all features + # explicitly don't mention wgpu-hal so that --all-features don't apply to it + cargo clippy --target ${{ matrix.target }} -p wgpu -p wgpu-core -p wgpu-info -p player --examples --tests --all-features -- -D warnings + + - name: check native nightly (non-fatal warnings) + if: (matrix.kind == 'compile' || matrix.kind == 'test') && matrix.channel != 'stable' + run: | + # check with no features + cargo clippy --target ${{ matrix.target }} -p wgpu -p wgpu-core -p wgpu-info -p player + + # check with all features + # explicitly don't mention wgpu-hal so that --all-features don't apply to it + cargo clippy --target ${{ matrix.target }} -p wgpu -p wgpu-core -p wgpu-info -p player --examples --tests --all-features + + - name: build tests + if: matrix.kind == 'test' + run: | + cargo build --target ${{ matrix.target }} --bin wgpu-info + cargo build --target ${{ matrix.target }} --tests -p player + cargo build --target ${{ matrix.target }} --examples --tests -p wgpu + + # - name: tests + # if: matrix.kind == 'test' + # run: | + # # run wgpu-info + # cargo run --target ${{ matrix.target }} --bin wgpu-info + + # # run player tests + # cargo test --target ${{ matrix.target }} -p player -- --nocapture + + # # run coretests + # cargo run --target ${{ matrix.target }} --bin wgpu-info -- cargo test --target ${{ matrix.target }} -p wgpu -- --nocapture --test-threads=1 # GLES is currently non-multithreadable + + fmt: + name: Format runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - name: checkout repo + uses: actions/checkout@v2 + + - name: install rust + uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - - run: rustup component add clippy - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: -- -D warnings - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: -- --check + components: rustfmt + + - name: run rustfmt + run: | + cargo fmt -- --check diff --git a/bors.toml b/bors.toml index 729709bdf9..551880c346 100644 --- a/bors.toml +++ b/bors.toml @@ -1,12 +1,10 @@ status = [ - "iOS Stable", - "MacOS Stable", - "MacOS Nightly", - "Android Stable", - "Ubuntu Stable", - "Ubuntu Nightly", - "Windows Stable", - "Windows Nightly", - "Web Assembly", - #"Clippy", + "Windows x86_64", + "MacOS x86_64", + "IOS aarch64", + "Linux x86_64", + "Linux Nightly x86_64", + "Android aarch64", + "WebAssembly", + "Format", ] diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index a497288ed6..47be0230e8 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -980,6 +980,7 @@ impl Device { use wgt::BindingType as Bt; let mut required_features = wgt::Features::empty(); + let mut required_downlevel_flags = wgt::DownlevelFlags::empty(); let (array_feature, is_writable_storage) = match entry.ty { Bt::Buffer { ty: wgt::BufferBindingType::Uniform, @@ -1029,6 +1030,9 @@ impl Device { error, })?; } + if entry.visibility.contains(wgt::ShaderStages::VERTEX) { + required_downlevel_flags |= wgt::DownlevelFlags::VERTEX_ACCESSABLE_STORAGE_BUFFERS; + } if is_writable_storage && entry.visibility.contains(wgt::ShaderStages::VERTEX) { required_features |= wgt::Features::VERTEX_WRITABLE_STORAGE; } @@ -1047,6 +1051,13 @@ impl Device { binding: entry.binding, error, })?; + + self.require_downlevel_flags(required_downlevel_flags) + .map_err(binding_model::BindGroupLayoutEntryError::MissingDownlevelFlags) + .map_err(|error| binding_model::CreateBindGroupLayoutError::Entry { + binding: entry.binding, + error, + })?; } let mut hal_bindings = entry_map.values().cloned().collect::>(); diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 9b1e54cc0a..e237ccd719 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -60,6 +60,15 @@ fn check_limits(requested: &wgt::Limits, allowed: &wgt::Limits) -> Vec= (3, 1)); + let vertex_shader_storage_blocks = + gl.get_parameter_i32(glow::MAX_VERTEX_SHADER_STORAGE_BLOCKS); + let fragment_shader_storage_blocks = + gl.get_parameter_i32(glow::MAX_FRAGMENT_SHADER_STORAGE_BLOCKS); + let mut downlevel_flags = wgt::DownlevelFlags::empty() | wgt::DownlevelFlags::DEVICE_LOCAL_IMAGE_COPIES | wgt::DownlevelFlags::NON_POWER_OF_TWO_MIPMAPPED_TEXTURES @@ -202,6 +210,10 @@ impl super::Adapter { wgt::DownlevelFlags::INDEPENDENT_BLENDING, ver >= (3, 2) || extensions.contains("GL_EXT_draw_buffers_indexed"), ); + downlevel_flags.set( + wgt::DownlevelFlags::VERTEX_ACCESSABLE_STORAGE_BUFFERS, + vertex_shader_storage_blocks > 0, + ); let max_texture_size = gl.get_parameter_i32(glow::MAX_TEXTURE_SIZE) as u32; let max_texture_3d_size = gl.get_parameter_i32(glow::MAX_3D_TEXTURE_SIZE) as u32; @@ -216,10 +228,12 @@ impl super::Adapter { let max_uniform_buffers_per_shader_stage = gl.get_parameter_i32(glow::MAX_VERTEX_UNIFORM_BLOCKS) .min(gl.get_parameter_i32(glow::MAX_FRAGMENT_UNIFORM_BLOCKS)) as u32; - let max_storage_buffers_per_shader_stage = gl - .get_parameter_i32(glow::MAX_VERTEX_SHADER_STORAGE_BLOCKS) - .min(gl.get_parameter_i32(glow::MAX_FRAGMENT_SHADER_STORAGE_BLOCKS)) - as u32; + let max_storage_buffers_per_shader_stage = if vertex_shader_storage_blocks > 0 { + vertex_shader_storage_blocks.min(fragment_shader_storage_blocks) + } else { + fragment_shader_storage_blocks + } as u32; + let max_storage_textures_per_shader_stage = gl.get_parameter_i32(glow::MAX_FRAGMENT_IMAGE_UNIFORMS) as u32; @@ -239,10 +253,10 @@ impl super::Adapter { max_uniform_buffer_binding_size: gl.get_parameter_i32(glow::MAX_UNIFORM_BLOCK_SIZE) as u32, max_storage_buffer_binding_size: if ver >= (3, 1) { - gl.get_parameter_i32(glow::MAX_SHADER_STORAGE_BLOCK_SIZE) as u32 + gl.get_parameter_i32(glow::MAX_SHADER_STORAGE_BLOCK_SIZE) } else { 0 - }, + } as u32, max_vertex_buffers: gl.get_parameter_i32(glow::MAX_VERTEX_ATTRIB_BINDINGS) as u32, max_vertex_attributes: (gl.get_parameter_i32(glow::MAX_VERTEX_ATTRIBS) as u32) .min(super::MAX_VERTEX_ATTRIBUTES as u32), @@ -266,7 +280,7 @@ impl super::Adapter { ver >= (3, 1), ); - let downlevel_limits = wgt::DownlevelLimits {}; + let downlevel_defaults = wgt::DownlevelLimits {}; Some(crate::ExposedAdapter { adapter: super::Adapter { @@ -282,7 +296,7 @@ impl super::Adapter { limits, downlevel: wgt::DownlevelCapabilities { flags: downlevel_flags, - limits: downlevel_limits, + limits: downlevel_defaults, shader_model: wgt::ShaderModel::Sm5, }, alignments: crate::Alignments { diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index 0c5f9b2fa2..52adf2f800 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -460,7 +460,9 @@ impl crate::Instance for Instance { ) -> Result { use raw_window_handle::RawWindowHandle as Rwh; + #[cfg_attr(target_os = "android", allow(unused_mut))] let mut inner = self.inner.lock(); + #[cfg_attr(target_os = "android", allow(unused_mut))] let mut wl_window = None; #[cfg(not(any(target_os = "android", target_os = "macos")))] let (mut temp_xlib_handle, mut temp_xcb_handle); diff --git a/wgpu-hal/src/metal/surface.rs b/wgpu-hal/src/metal/surface.rs index 7f44c2823d..e66a536907 100644 --- a/wgpu-hal/src/metal/surface.rs +++ b/wgpu-hal/src/metal/surface.rs @@ -12,6 +12,7 @@ use objc::{ }; use parking_lot::Mutex; +#[cfg(target_os = "macos")] #[link(name = "QuartzCore", kind = "framework")] extern "C" { #[allow(non_upper_case_globals)] diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 44cb1e432d..6b9cfc9736 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -497,6 +497,20 @@ impl Features { /// Represents the sets of limits an adapter/device supports. /// +/// We provide two different defaults. +/// - [`Limits::downlevel_defaults()]. This is a set of limits that is guarenteed to +/// work on all backends, including "downlevel" backends such +/// as OpenGL and D3D11. For most applications we recommend using these +/// limits, assuming they are high enough for your application. +/// - [`Limits::default()`]. This is the set of limits that is guarenteed to +/// work on all modern backends and is guarenteed to be supported by WebGPU. +/// Applications needing more modern features can use this as a reasonable set of +/// limits if they are targetting only desktop and modern mobile devices. +/// +/// We recommend starting with the most restrictive limits you can and manually +/// increasing the limits you need boosted. This will let you stay running on +/// all hardware that supports the limits you need. +/// /// Limits "better" than the default must be supported by the adapter and requested when requesting /// a device. If limits "better" than the adapter supports are requested, requesting a device will panic. /// Once a device is requested, you may only use resources up to the limits requested _even_ if the @@ -593,6 +607,32 @@ impl Default for Limits { } } +impl Limits { + /// These default limits are guarenteed to be compatible with GLES3, WebGL, and D3D11 + pub fn downlevel_defaults() -> Self { + Self { + max_texture_dimension_1d: 2096, + max_texture_dimension_2d: 2096, + max_texture_dimension_3d: 256, + max_texture_array_layers: 256, + max_bind_groups: 4, + max_dynamic_uniform_buffers_per_pipeline_layout: 8, + max_dynamic_storage_buffers_per_pipeline_layout: 4, + max_sampled_textures_per_shader_stage: 16, + max_samplers_per_shader_stage: 16, + max_storage_buffers_per_shader_stage: 4, + max_storage_textures_per_shader_stage: 4, + max_uniform_buffers_per_shader_stage: 12, + max_uniform_buffer_binding_size: 16384, + max_storage_buffer_binding_size: 128 << 20, + max_vertex_buffers: 8, + max_vertex_attributes: 16, + max_vertex_buffer_array_stride: 2048, + max_push_constant_size: 0, + } + } +} + /// Represents the sets of additional limits on an adapter, /// which take place when running on downlevel backends. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -662,8 +702,15 @@ bitflags::bitflags! { const COMPARISON_SAMPLERS = 0x0000_0100; /// Supports different blending modes per color target. const INDEPENDENT_BLENDING = 0x0000_0200; - /// Supports samplers with anisotropic filtering - const ANISOTROPIC_FILTERING = 0x0001_0000; + /// Supports attaching storage buffers to vertex shaders. + const VERTEX_ACCESSABLE_STORAGE_BUFFERS = 0x0000_0400; + + + /// Supports samplers with anisotropic filtering. Note this isn't actually required by WebGPU, + /// the implementation is allowed to completely ignore aniso clamp. This flag is here for native backends + /// so they can comunicate to the user of aniso is enabled. + const ANISOTROPIC_FILTERING = 0x8000_0000; + } } diff --git a/wgpu/examples/boids/main.rs b/wgpu/examples/boids/main.rs index ce39549c67..8a022b9261 100644 --- a/wgpu/examples/boids/main.rs +++ b/wgpu/examples/boids/main.rs @@ -328,6 +328,6 @@ fn boids() { base_test_parameters: framework::test_common::TestParameters::default() .downlevel_flags(wgpu::DownlevelFlags::COMPUTE_SHADERS), tolerance: 0, - max_outliers: 600, // Currently bounded by rpi4 + max_outliers: 1000, // Currently bounded by rpi4 }); } diff --git a/wgpu/examples/capture/main.rs b/wgpu/examples/capture/main.rs index 5d64733f23..6df1fe70f7 100644 --- a/wgpu/examples/capture/main.rs +++ b/wgpu/examples/capture/main.rs @@ -38,7 +38,7 @@ async fn create_red_image_with_dimensions( &wgpu::DeviceDescriptor { label: None, features: wgpu::Features::empty(), - limits: wgpu::Limits::default(), + limits: wgpu::Limits::downlevel_defaults(), }, None, ) diff --git a/wgpu/examples/cube/main.rs b/wgpu/examples/cube/main.rs index d05e423cea..2bd815f6b2 100644 --- a/wgpu/examples/cube/main.rs +++ b/wgpu/examples/cube/main.rs @@ -402,6 +402,6 @@ fn cube_lines() { optional_features: wgpu::Features::NON_FILL_POLYGON_MODE, base_test_parameters: framework::test_common::TestParameters::default(), tolerance: 2, - max_outliers: 500, // Bounded by rpi4 & intel 620 on GL + max_outliers: 600, // Bounded by rpi4 on GL }); } diff --git a/wgpu/examples/framework.rs b/wgpu/examples/framework.rs index 2dc88baec8..f55d3b25e3 100644 --- a/wgpu/examples/framework.rs +++ b/wgpu/examples/framework.rs @@ -41,7 +41,7 @@ pub trait Example: 'static + Sized { wgpu::Features::empty() } fn required_limits() -> wgpu::Limits { - wgpu::Limits::default() + wgpu::Limits::downlevel_defaults() // These downlevel limits will allow the code to run on all possible hardware } fn init( sc_desc: &wgpu::SwapChainDescriptor, diff --git a/wgpu/examples/hello-compute/main.rs b/wgpu/examples/hello-compute/main.rs index bb10ecf260..21a596b1a8 100644 --- a/wgpu/examples/hello-compute/main.rs +++ b/wgpu/examples/hello-compute/main.rs @@ -47,7 +47,7 @@ async fn execute_gpu(numbers: &[u32]) -> Option> { &wgpu::DeviceDescriptor { label: None, features: wgpu::Features::empty(), - limits: wgpu::Limits::default(), + limits: wgpu::Limits::downlevel_defaults(), }, None, ) diff --git a/wgpu/examples/hello-compute/tests.rs b/wgpu/examples/hello-compute/tests.rs index 89fab4bacb..92e8a201a3 100644 --- a/wgpu/examples/hello-compute/tests.rs +++ b/wgpu/examples/hello-compute/tests.rs @@ -9,12 +9,7 @@ use common::{initialize_test, TestParameters}; #[test] fn test_compute_1() { initialize_test( - TestParameters::default().specific_failure( - Some(wgpu::Backends::GL), - None, - Some("V3D"), - false, - ), + TestParameters::default().specific_failure(None, None, Some("V3D"), false), |ctx| { let input = &[1, 2, 3, 4]; @@ -31,12 +26,7 @@ fn test_compute_1() { #[test] fn test_compute_2() { initialize_test( - TestParameters::default().specific_failure( - Some(wgpu::Backends::GL), - None, - Some("V3D"), - false, - ), + TestParameters::default().specific_failure(None, None, Some("V3D"), false), |ctx| { let input = &[5, 23, 10, 9]; @@ -53,12 +43,7 @@ fn test_compute_2() { #[test] fn test_compute_overflow() { initialize_test( - TestParameters::default().specific_failure( - Some(wgpu::Backends::GL), - None, - Some("V3D"), - false, - ), + TestParameters::default().specific_failure(None, None, Some("V3D"), false), |ctx| { let input = &[77031, 837799, 8400511, 63728127]; pollster::block_on(assert_execute_gpu( @@ -74,7 +59,9 @@ fn test_compute_overflow() { #[test] fn test_multithreaded_compute() { initialize_test( - TestParameters::default().backend_failure(wgpu::Backends::GL), + TestParameters::default() + .backend_failure(wgpu::Backends::GL) + .specific_failure(Some(wgpu::Backends::VULKAN), None, Some("V3D"), false), |ctx| { use std::{sync::mpsc, thread, time::Duration}; diff --git a/wgpu/examples/hello-triangle/main.rs b/wgpu/examples/hello-triangle/main.rs index 0335003ef7..8823138911 100644 --- a/wgpu/examples/hello-triangle/main.rs +++ b/wgpu/examples/hello-triangle/main.rs @@ -24,7 +24,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { &wgpu::DeviceDescriptor { label: None, features: wgpu::Features::empty(), - limits: wgpu::Limits::default(), + limits: wgpu::Limits::downlevel_defaults(), }, None, ) diff --git a/wgpu/examples/hello-windows/main.rs b/wgpu/examples/hello-windows/main.rs index cb3a9ef551..116cdd44de 100644 --- a/wgpu/examples/hello-windows/main.rs +++ b/wgpu/examples/hello-windows/main.rs @@ -85,7 +85,7 @@ async fn run(event_loop: EventLoop<()>, viewports: Vec<(Window, wgpu::Color)>) { &wgpu::DeviceDescriptor { label: None, features: wgpu::Features::empty(), - limits: wgpu::Limits::default(), + limits: wgpu::Limits::downlevel_defaults(), }, None, ) diff --git a/wgpu/examples/mipmap/main.rs b/wgpu/examples/mipmap/main.rs index d084344fad..06ccf8c778 100644 --- a/wgpu/examples/mipmap/main.rs +++ b/wgpu/examples/mipmap/main.rs @@ -484,7 +484,7 @@ fn mipmap() { optional_features: wgpu::Features::default(), base_test_parameters: framework::test_common::TestParameters::default() .backend_failure(wgpu::Backends::GL), - tolerance: 25, - max_outliers: 3000, // Mipmap sampling is highly variant between impls. This is currently bounded by AMD on mac + tolerance: 50, + max_outliers: 5000, // Mipmap sampling is highly variant between impls. This is currently bounded by lavapipe }); } diff --git a/wgpu/examples/shadow/main.rs b/wgpu/examples/shadow/main.rs index 959815d796..b78a6dee79 100644 --- a/wgpu/examples/shadow/main.rs +++ b/wgpu/examples/shadow/main.rs @@ -830,7 +830,8 @@ fn shadow() { height: 768, optional_features: wgpu::Features::default(), base_test_parameters: framework::test_common::TestParameters::default() - .downlevel_flags(wgpu::DownlevelFlags::COMPARISON_SAMPLERS), + .downlevel_flags(wgpu::DownlevelFlags::COMPARISON_SAMPLERS) + .specific_failure(Some(wgpu::Backends::VULKAN), None, Some("V3D"), false), // rpi4 on VK doesn't work: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3916 tolerance: 2, max_outliers: 500, // bounded by rpi4 }); diff --git a/wgpu/examples/skybox/main.rs b/wgpu/examples/skybox/main.rs index 98e02f4847..1ffe9d4b05 100644 --- a/wgpu/examples/skybox/main.rs +++ b/wgpu/examples/skybox/main.rs @@ -500,7 +500,7 @@ fn skybox_etc2() { optional_features: wgpu::Features::TEXTURE_COMPRESSION_ETC2, base_test_parameters: framework::test_common::TestParameters::default(), tolerance: 5, - max_outliers: 50, // Bounded by rpi4 + max_outliers: 100, // Bounded by llvmpipe }); } @@ -512,7 +512,7 @@ fn skybox_astc() { height: 768, optional_features: wgpu::Features::TEXTURE_COMPRESSION_ASTC_LDR, base_test_parameters: framework::test_common::TestParameters::default(), - tolerance: 5, // TODO - max_outliers: 10, // TODO + tolerance: 5, + max_outliers: 300, // Bounded by rp4 on vk }); } diff --git a/wgpu/examples/texture-arrays/main.rs b/wgpu/examples/texture-arrays/main.rs index 0b7e615c81..f8ebfa152d 100644 --- a/wgpu/examples/texture-arrays/main.rs +++ b/wgpu/examples/texture-arrays/main.rs @@ -49,14 +49,14 @@ fn create_indices() -> Vec { #[derive(Copy, Clone)] enum Color { - RED, - GREEN, + Red, + Green, } fn create_texture_data(color: Color) -> [u8; 4] { match color { - Color::RED => [255, 0, 0, 255], - Color::GREEN => [0, 255, 0, 255], + Color::Red => [255, 0, 0, 255], + Color::Green => [0, 255, 0, 255], } } @@ -122,8 +122,8 @@ impl framework::Example for Example { usage: wgpu::BufferUsages::INDEX, }); - let red_texture_data = create_texture_data(Color::RED); - let green_texture_data = create_texture_data(Color::GREEN); + let red_texture_data = create_texture_data(Color::Red); + let green_texture_data = create_texture_data(Color::Green); let texture_descriptor = wgpu::TextureDescriptor { size: wgpu::Extent3d::default(), @@ -253,11 +253,11 @@ impl framework::Example for Example { }); Self { + pipeline, + bind_group, vertex_buffer, index_buffer, index_format, - bind_group, - pipeline, uniform_workaround, } } @@ -340,8 +340,7 @@ fn texture_arrays_uniform() { image_path: "/examples/texture-arrays/screenshot.png", width: 1024, height: 768, - optional_features: wgpu::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING - | wgpu::Features::PUSH_CONSTANTS, + optional_features: wgpu::Features::TEXTURE_BINDING_ARRAY | wgpu::Features::PUSH_CONSTANTS, base_test_parameters: framework::test_common::TestParameters::default().failure(), tolerance: 0, max_outliers: 0, @@ -355,7 +354,8 @@ fn texture_arrays_non_uniform() { image_path: "/examples/texture-arrays/screenshot.png", width: 1024, height: 768, - optional_features: wgpu::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + optional_features: wgpu::Features::TEXTURE_BINDING_ARRAY + | wgpu::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, base_test_parameters: framework::test_common::TestParameters::default().failure(), tolerance: 0, max_outliers: 0, @@ -369,7 +369,8 @@ fn texture_arrays_unsized_non_uniform() { image_path: "/examples/texture-arrays/screenshot.png", width: 1024, height: 768, - optional_features: wgpu::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING + optional_features: wgpu::Features::TEXTURE_BINDING_ARRAY + | wgpu::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING | wgpu::Features::UNSIZED_BINDING_ARRAY, base_test_parameters: framework::test_common::TestParameters::default().failure(), tolerance: 0, diff --git a/wgpu/examples/water/main.rs b/wgpu/examples/water/main.rs index 16cadc8a4c..858cdbdb4d 100644 --- a/wgpu/examples/water/main.rs +++ b/wgpu/examples/water/main.rs @@ -800,6 +800,6 @@ fn water() { base_test_parameters: framework::test_common::TestParameters::default() .downlevel_flags(wgpu::DownlevelFlags::READ_ONLY_DEPTH_STENCIL), tolerance: 5, - max_outliers: 10, + max_outliers: 300, // bounded by rpi4 on vk }); } diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 59d939436e..232b794343 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1,3 +1,5 @@ +#![allow(clippy::type_complexity)] + use std::{ fmt, future::Future, @@ -1262,8 +1264,8 @@ impl crate::Context for Context { unsafe fn device_create_shader_module_spirv( &self, - device: &Self::DeviceId, - desc: &crate::ShaderModuleDescriptorSpirV, + _device: &Self::DeviceId, + _desc: &crate::ShaderModuleDescriptorSpirV, ) -> Self::ShaderModuleId { unreachable!("SPIRV_SHADER_PASSTHROUGH is not enabled for this backend") } @@ -1289,7 +1291,7 @@ impl crate::Context for Context { if let Some(s) = size { mapped_buffer_binding.size(s.get() as f64); } - JsValue::from(mapped_buffer_binding.clone()) + JsValue::from(mapped_buffer_binding) } crate::BindingResource::BufferArray(..) => { panic!("Web backend does not support arrays of buffers") @@ -1498,7 +1500,6 @@ impl crate::Context for Context { _device: &Self::DeviceId, _desc: &wgt::QuerySetDescriptor, ) -> Self::QuerySetId { - () } fn device_create_command_encoder( diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index f07d748fbe..3d06feae61 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -71,13 +71,20 @@ fn lowest_downlevel_properties() -> DownlevelCapabilities { } } +pub struct FailureCase { + backends: Option, + vendor: Option, + adapter: Option, + segfault: bool, +} + // This information determines if a test should run. pub struct TestParameters { pub required_features: Features, pub required_limits: Limits, pub required_downlevel_properties: DownlevelCapabilities, // Backends where test should fail. - pub failures: Vec<(Option, Option, Option, bool)>, + pub failures: Vec, } impl Default for TestParameters { @@ -126,13 +133,23 @@ impl TestParameters { /// Mark the test as always failing, equivilant to specific_failure(None, None, None) pub fn failure(mut self) -> Self { - self.failures.push((None, None, None, false)); + self.failures.push(FailureCase { + backends: None, + vendor: None, + adapter: None, + segfault: false, + }); self } /// Mark the test as always failing on a specific backend, equivilant to specific_failure(backend, None, None) pub fn backend_failure(mut self, backends: wgpu::Backends) -> Self { - self.failures.push((Some(backends), None, None, false)); + self.failures.push(FailureCase { + backends: Some(backends), + vendor: None, + adapter: None, + segfault: false, + }); self } @@ -150,12 +167,12 @@ impl TestParameters { device: Option<&'static str>, segfault: bool, ) -> Self { - self.failures.push(( + self.failures.push(FailureCase { backends, vendor, - device.as_ref().map(AsRef::as_ref).map(str::to_lowercase), + adapter: device.as_ref().map(AsRef::as_ref).map(str::to_lowercase), segfault, - )); + }); self } } @@ -222,45 +239,45 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te queue, }; - let failure_reason = parameters.failures.iter().find_map( - |(backend_failure, vendor_failure, adapter_failure, segfault)| { - let always = - backend_failure.is_none() && vendor_failure.is_none() && adapter_failure.is_none(); + let failure_reason = parameters.failures.iter().find_map(|failure| { + let always = + failure.backends.is_none() && failure.vendor.is_none() && failure.adapter.is_none(); - let expect_failure_backend = - backend_failure.map(|f| f.contains(wgpu::Backends::from(adapter_info.backend))); - let expect_failure_vendor = vendor_failure.map(|v| v == adapter_info.vendor); - let expect_failure_adapter = adapter_failure - .as_deref() - .map(|f| adapter_lowercase_name.contains(f)); + let expect_failure_backend = failure + .backends + .map(|f| f.contains(wgpu::Backends::from(adapter_info.backend))); + let expect_failure_vendor = failure.vendor.map(|v| v == adapter_info.vendor); + let expect_failure_adapter = failure + .adapter + .as_deref() + .map(|f| adapter_lowercase_name.contains(f)); - if expect_failure_backend.unwrap_or(true) - && expect_failure_vendor.unwrap_or(true) - && expect_failure_adapter.unwrap_or(true) - { - if always { - Some((FailureReasons::ALWAYS, *segfault)) - } else { - let mut reason = FailureReasons::empty(); - reason.set( - FailureReasons::BACKEND, - expect_failure_backend.unwrap_or(false), - ); - reason.set( - FailureReasons::VENDOR, - expect_failure_vendor.unwrap_or(false), - ); - reason.set( - FailureReasons::ADAPTER, - expect_failure_adapter.unwrap_or(false), - ); - Some((reason, *segfault)) - } + if expect_failure_backend.unwrap_or(true) + && expect_failure_vendor.unwrap_or(true) + && expect_failure_adapter.unwrap_or(true) + { + if always { + Some((FailureReasons::ALWAYS, failure.segfault)) } else { - None + let mut reason = FailureReasons::empty(); + reason.set( + FailureReasons::BACKEND, + expect_failure_backend.unwrap_or(false), + ); + reason.set( + FailureReasons::VENDOR, + expect_failure_vendor.unwrap_or(false), + ); + reason.set( + FailureReasons::ADAPTER, + expect_failure_adapter.unwrap_or(false), + ); + Some((reason, failure.segfault)) } - }, - ); + } else { + None + } + }); if let Some((reason, true)) = failure_reason { println!(