diff --git a/CHANGELOG.md b/CHANGELOG.md index 1877157d53..3748688989 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,6 @@ Bottom level categories: - DX12 - Vulkan - Metal -- DX11 - GLES - WebGPU - Emscripten @@ -40,6 +39,10 @@ Bottom level categories: ## Unreleased +### Direct3D 11 backend removal + +This backend had no functionality, and with the recent support for GL on Desktop, which allows wgpu to run on older devices, there is no need to keep the backend. + ### `WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER` environment variable This adds a way to allow a Vulkan driver which is non-compliant per VK_KHR_driver_properties to be enumerated. This is intended for testing new Vulkan drivers which are not Vulkan compliant yet. @@ -53,6 +56,7 @@ Previously, `DeviceExt::create_texture_with_data` only allowed data to be provid #### General - Added `DownlevelFlags::VERTEX_AND_INSTANCE_INDEX_RESPECTS_RESPECTIVE_FIRST_VALUE_IN_INDIRECT_DRAW` to know if `@builtin(vertex_index)` and `@builtin(instance_index)` will respect the `first_vertex` / `first_instance` in indirect calls. If this is not present, both will always start counting from 0. Currently enabled on all backends except DX12. By @cwfitzgerald in [#4722](https://github.com/gfx-rs/wgpu/pull/4722) - No longer validate surfaces against their allowed extent range on configure. This caused warnings that were almost impossible to avoid. As before, the resulting behavior depends on the compositor. By @wumpf in [#????](https://github.com/gfx-rs/wgpu/pull/????) +- Added support for the float32-filterable feature. By @almarklein in [#4759](https://github.com/gfx-rs/wgpu/pull/4759) #### OpenGL - `@builtin(instance_index)` now properly reflects the range provided in the draw call instead of always counting from 0. By @cwfitzgerald in [#4722](https://github.com/gfx-rs/wgpu/pull/4722). @@ -103,7 +107,7 @@ Passing an owned value `window` to `Surface` will return a `Surface<'static>`. S - Introduce a new `Scalar` struct type for use in Naga's IR, and update all frontend, middle, and backend code appropriately. By @jimblandy in [#4673](https://github.com/gfx-rs/wgpu/pull/4673). - Add more metal keywords. By @fornwall in [#4707](https://github.com/gfx-rs/wgpu/pull/4707). -- Add partial support for WGSL abstract types (@jimblandy in [#4743](https://github.com/gfx-rs/wgpu/pull/4743)). +- Add partial support for WGSL abstract types (@jimblandy in [#4743](https://github.com/gfx-rs/wgpu/pull/4743), [#4755](https://github.com/gfx-rs/wgpu/pull/4755)). Abstract types make numeric literals easier to use, by automatically converting literals and other constant expressions @@ -120,9 +124,10 @@ Passing an owned value `window` to `Surface` will return a `Surface<'static>`. S Even though the literals are abstract integers, Naga recognizes that it is safe and necessary to convert them to `f32` values in order to build the vector. You can also use abstract values as - initializers for global constants, like this: + initializers for global constants and global and local variables, + like this: - const unit_x: vec2 = vec2(1, 0); + var unit_x: vec2 = vec2(1, 0); The literals `1` and `0` are abstract integers, and the expression `vec2(1, 0)` is an abstract vector. However, Naga recognizes that diff --git a/Cargo.lock b/Cargo.lock index b557867719..cd1a52f2ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -685,9 +685,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -695,9 +695,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics" @@ -727,9 +727,9 @@ dependencies = [ [[package]] name = "core-graphics-types" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -3754,9 +3754,9 @@ checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-bindgen-test" -version = "0.3.38" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6433b7c56db97397842c46b67e11873eda263170afeb3a2dc74a7cb370fee0d" +checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403" dependencies = [ "console_error_panic_hook", "js-sys", @@ -3768,9 +3768,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.38" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "493fcbab756bb764fa37e6bee8cec2dd709eb4273d06d0c282a5e74275ded735" +checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89" dependencies = [ "proc-macro2", "quote", diff --git a/README.md b/README.md index 62596b4634..711f3c395c 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ [![Build Status](https://github.com/gfx-rs/wgpu/workflows/CI/badge.svg)](https://github.com/gfx-rs/wgpu/actions) [![codecov.io](https://codecov.io/gh/gfx-rs/wgpu/branch/trunk/graph/badge.svg?token=84qJTesmeS)](https://codecov.io/gh/gfx-rs/wgpu) -`wgpu` is a cross-platform, safe, pure-rust graphics api. It runs natively on Vulkan, Metal, D3D12, and OpenGL; and on top of WebGL2 and WebGPU on wasm. +`wgpu` is a cross-platform, safe, pure-rust graphics API. It runs natively on Vulkan, Metal, D3D12, and OpenGL; and on top of WebGL2 and WebGPU on wasm. -The api is based on the [WebGPU standard](https://gpuweb.github.io/gpuweb/). It serves as the core of the WebGPU integration in Firefox and Deno. +The API is based on the [WebGPU standard](https://gpuweb.github.io/gpuweb/). It serves as the core of the WebGPU integration in Firefox and Deno. ## Repo Overview @@ -26,7 +26,7 @@ The repository hosts the following libraries: The following binaries: -- [![Crates.io](https://img.shields.io/crates/v/naga-cli.svg?label=naga-cli)](https://crates.io/crates/naga-cli) - Tool for translating shaders between different languages using naga. +- [![Crates.io](https://img.shields.io/crates/v/naga-cli.svg?label=naga-cli)](https://crates.io/crates/naga-cli) - Tool for translating shaders between different languages using `naga`. - [![Crates.io](https://img.shields.io/crates/v/wgpu-info.svg?label=wgpu-info)](https://crates.io/crates/wgpu-info) - Tool for getting information on GPUs in the system. - `cts_runner` - WebGPU Conformance Test Suite runner using `deno_webgpu`. - `player` - standalone application for replaying the API traces. @@ -39,9 +39,9 @@ For an overview of all the components in the gfx-rs ecosystem, see [the big pict Rust examples can be found at [wgpu/examples](examples). You can run the examples on native with `cargo run --bin wgpu-examples `. See the [list of examples](examples). -To run the examples on WebGPU on wasm, run `cargo xtask run-wasm --bin wgpu-example`. Then connect to `http://localhost:8000` in your WebGPU enabled browser, and you can choose an example to run. +To run the examples on WebGPU on wasm, run `cargo xtask run-wasm --bin wgpu-example`. Then connect to `http://localhost:8000` in your WebGPU-enabled browser, and you can choose an example to run. -To run the examples on WebGL on wasm, run `cargo xtask run-wasm --bin wgpu-example --features webgl`. Then connect to `http://localhost:8000` in your WebGL enabled browser, and you can choose an example to run. +To run the examples on WebGL on wasm, run `cargo xtask run-wasm --bin wgpu-example --features webgl`. Then connect to `http://localhost:8000` in your WebGL-enabled browser, and you can choose an example to run. If you are looking for a wgpu tutorial, look at the following: @@ -78,8 +78,7 @@ We have a [wiki](https://github.com/gfx-rs/wgpu/wiki) that serves as a knowledge | ----------- | ------------------------------ | ------------------ | ------------------------- | ------------------------- | | Vulkan | :white_check_mark: | :white_check_mark: | :volcano: | | | Metal | | | :white_check_mark: | | -| DX12 | :white_check_mark: | | | | -| DX11 | :hammer_and_wrench: | | | | +| DX12 | :white_check_mark: | | | | | OpenGL | :ok: (GL 3.3+) | :ok: (GL ES 3.0+) | :triangular_ruler: | :ok: (WebGL2) | | WebGPU | | | | :white_check_mark: | @@ -93,8 +92,7 @@ We have a [wiki](https://github.com/gfx-rs/wgpu/wiki) that serves as a knowledge wgpu supports shaders in [WGSL](https://gpuweb.github.io/gpuweb/wgsl/), SPIR-V, and GLSL. Both [HLSL](https://github.com/Microsoft/DirectXShaderCompiler) and [GLSL](https://github.com/KhronosGroup/glslang) -have compilers to target SPIR-V. All of these shader languages can be used with any backend, we -will handle all of the conversion. Additionally, support for these shader inputs is not going away. +have compilers to target SPIR-V. All of these shader languages can be used with any backend as we handle all of the conversions. Additionally, support for these shader inputs is not going away. While WebGPU does not support any shading language other than WGSL, we will automatically convert your non-WGSL shaders if you're running on WebGPU. @@ -110,9 +108,9 @@ To enable GLSL shaders, enable the `glsl` feature of wgpu. ### Angle -[Angle](http://angleproject.org) is a translation layer from GLES to other backends, developed by Google. +[Angle](http://angleproject.org) is a translation layer from GLES to other backends developed by Google. We support running our GLES3 backend over it in order to reach platforms DX11 support, which aren't accessible otherwise. -In order to run with Angle, "angle" feature has to be enabled, and Angle libraries placed in a location visible to the application. +In order to run with Angle, the "angle" feature has to be enabled, and Angle libraries placed in a location visible to the application. These binaries can be downloaded from [gfbuild-angle](https://github.com/DileSoft/gfbuild-angle) artifacts, [manual compilation](https://github.com/google/angle/blob/main/doc/DevSetup.md) may be required on Macs with Apple silicon. On Windows, you generally need to copy them into the working directory, in the same directory as the executable, or somewhere in your path. @@ -122,10 +120,10 @@ On Linux, you can point to them using `LD_LIBRARY_PATH` environment. Due to complex dependants, we have two MSRV policies: - `d3d12`, `naga`, `wgpu-core`, `wgpu-hal`, and `wgpu-types`'s MSRV is **1.65**. - - The rest of the workspace has the MSRV of **1.71**. + - The rest of the workspace has an MSRV of **1.71**. -It is enforced on CI (in "/.github/workflows/ci.yml") with `CORE_MSRV` and `REPO_MSRV` variable. -This version can only be upgraded in breaking releases, though we release a breaking version every 3 months. +It is enforced on CI (in "/.github/workflows/ci.yml") with the `CORE_MSRV` and `REPO_MSRV` variables. +This version can only be upgraded in breaking releases, though we release a breaking version every three months. The `naga`, `wgpu-core`, `wgpu-hal`, and `wgpu-types` crates should never require an MSRV ahead of Firefox's MSRV for nightly builds, as @@ -136,10 +134,10 @@ determined by the value of `MINIMUM_RUST_VERSION` in ## Environment Variables -All testing and example infrastructure shares the same set of environment variables that determine which Backend/GPU it will run on. +All testing and example infrastructure share the same set of environment variables that determine which Backend/GPU it will run on. - `WGPU_ADAPTER_NAME` with a substring of the name of the adapter you want to use (ex. `1080` will match `NVIDIA GeForce 1080ti`). -- `WGPU_BACKEND` with a comma separated list of the backends you want to use (`vulkan`, `metal`, `dx12`, `dx11`, or `gl`). +- `WGPU_BACKEND` with a comma-separated list of the backends you want to use (`vulkan`, `metal`, `dx12`, or `gl`). - `WGPU_POWER_PREF` with the power preference to choose when a specific adapter name isn't specified (`high`, `low` or `none`) - `WGPU_DX12_COMPILER` with the DX12 shader compiler you wish to use (`dxc` or `fxc`, note that `dxc` requires `dxil.dll` and `dxcompiler.dll` to be in the working directory otherwise it will fall back to `fxc`) - `WGPU_GLES_MINOR_VERSION` with the minor OpenGL ES 3 version number to request (`0`, `1`, `2` or `automatic`). @@ -187,7 +185,7 @@ If you are a user and want a way to help contribute to wgpu, we always need more WebGPU includes a Conformance Test Suite to validate that implementations are working correctly. We can run this CTS against wgpu. -To run the CTS, first you need to check it out: +To run the CTS, first, you need to check it out: ``` git clone https://github.com/gpuweb/cts.git @@ -199,7 +197,7 @@ git checkout $(cat ../cts_runner/revision.txt) To run a given set of tests: ``` -# Must be inside the cts folder we just checked out, else this will fail +# Must be inside the `cts` folder we just checked out, else this will fail cargo run --manifest-path ../Cargo.toml --bin cts_runner -- ./tools/run_deno --verbose "" ``` @@ -224,7 +222,7 @@ Exactly which WGSL features `wgpu` supports depends on how you are using it: to translate WGSL code into the shading language of your platform's native GPU API. Naga has [a milestone][naga wgsl milestone] for catching up to the WGSL specification, - but in general there is no up-to-date summary + but in general, there is no up-to-date summary of the differences between Naga and the WGSL spec. - When running in a web browser (by compilation to WebAssembly) diff --git a/deno_webgpu/01_webgpu.js b/deno_webgpu/01_webgpu.js index 92157e5490..3f7b1ed570 100644 --- a/deno_webgpu/01_webgpu.js +++ b/deno_webgpu/01_webgpu.js @@ -4980,6 +4980,7 @@ webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( "texture-compression-astc", "rg11b10ufloat-renderable", "bgra8unorm-storage", + "float32-filterable", // extended from spec diff --git a/deno_webgpu/Cargo.toml b/deno_webgpu/Cargo.toml index 716f3770d8..b9d281f04d 100644 --- a/deno_webgpu/Cargo.toml +++ b/deno_webgpu/Cargo.toml @@ -34,10 +34,10 @@ features = ["trace", "replay", "serde", "strict_asserts", "wgsl", "gles"] workspace = true features = ["metal"] -# We want the wgpu-core Direct3D backends on Windows. +# We want the wgpu-core Direct3D backend on Windows. [target.'cfg(windows)'.dependencies.wgpu-core] workspace = true -features = ["dx11", "dx12"] +features = ["dx12"] [target.'cfg(windows)'.dependencies.wgpu-hal] version = "0.18.0" diff --git a/deno_webgpu/README.md b/deno_webgpu/README.md index 2f915dcbbe..1cf031cda2 100644 --- a/deno_webgpu/README.md +++ b/deno_webgpu/README.md @@ -19,7 +19,7 @@ running through our WPT runner. This will be used to validate implementation conformance. GitHub CI doesn't run with GPUs, so testing relies on software like DX WARP & -Vulkan lavapipe. Currently only using DX WARP works, so tests are only run on +Vulkan lavapipe. Currently, only using DX WARP works, so tests are only run on Windows. ## Links diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index b69157df52..15151ce952 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -33,8 +33,6 @@ mod macros { wgpu_types::Backend::Metal => $global.$method::( $($param),* ), #[cfg(all(not(target_arch = "wasm32"), windows))] wgpu_types::Backend::Dx12 => $global.$method::( $($param),* ), - #[cfg(all(not(target_arch = "wasm32"), windows))] - wgpu_types::Backend::Dx11 => $global.$method::( $($param),* ), #[cfg(any( all(unix, not(target_os = "macos"), not(target_os = "ios")), feature = "angle", @@ -266,6 +264,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { if features.contains(wgpu_types::Features::BGRA8UNORM_STORAGE) { return_features.push("bgra8unorm-storage"); } + if features.contains(wgpu_types::Features::FLOAT32_FILTERABLE) { + return_features.push("float32-filterable"); + } // extended from spec @@ -498,6 +499,10 @@ impl From for wgpu_types::Features { wgpu_types::Features::BGRA8UNORM_STORAGE, required_features.0.contains("bgra8unorm-storage"), ); + features.set( + wgpu_types::Features::FLOAT32_FILTERABLE, + required_features.0.contains("float32-filterable"), + ); // extended from spec diff --git a/deno_webgpu/webgpu.idl b/deno_webgpu/webgpu.idl index 0b6b04eb4e..bf4da0124b 100644 --- a/deno_webgpu/webgpu.idl +++ b/deno_webgpu/webgpu.idl @@ -103,6 +103,7 @@ enum GPUFeatureName { "shader-f16", "rg11b10ufloat-renderable", "bgra8unorm-storage", + "float32-filterable", // extended from spec diff --git a/etc/big-picture.png b/etc/big-picture.png index d52d60189c..86d754da9d 100644 Binary files a/etc/big-picture.png and b/etc/big-picture.png differ diff --git a/etc/big-picture.xml b/etc/big-picture.xml index d43f4631d1..91844f1101 100644 --- a/etc/big-picture.xml +++ b/etc/big-picture.xml @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/examples/README.md b/examples/README.md index 09a33bbbf0..8232b863ad 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,9 +8,9 @@ For the simplest examples without using any helping code (see `framework.rs` her ### Summary of examples -A summary of the basic examples as split along the graphics and compute "pathways", layed out roughly in order of building on each other. Those further indented and thus more roughly dependant on more other examples tend to be more complicated as well as those further down. It should be noted though that computing examples, even though they are mentioned further down (because rendering to a window is by far the most common use case), tend to be less complex as they require less surrounding context to create and manage a window to render to. +A summary of the basic examples as split along the graphics and compute "pathways" laid out roughly in order of building on each other. Those further indented, and thus more roughly dependent on more other examples, tend to be more complicated as well as those further down. It should be noted, though, that computing examples, even though they are mentioned further down (because rendering to a window is by far the most common use case), tend to be less complex as they require less surrounding context to create and manage a window to render to. -The rest of the example are for demonstrating specific features that you can come back for later when you know what those features are. +The rest of the examples are for demonstrating specific features that you can come back for later when you know what those features are. #### General @@ -19,24 +19,24 @@ The rest of the example are for demonstrating specific features that you can com #### 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. -- `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. +- `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, preforming 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 state. -- `skybox` - Shows off too many concepts to list here. The name comes from game development where a "skybox" acts as a background for rendering, usually to add a sky texture for immersion although they can also be used for backdrops to give the idea of a world beyond of the game scene. This example does so much more than this though as it uses a car model loaded from a file and uses the user's mouse to rotate the car model in 3d. `skybox` also makes use of depth textures and similar app patterns to `uniform-values`. -- `shadow` - Likely by far the most complex example (certainly the largest in lines of code) of the official WGPU examples. `shadow` demonstrates basic scene rendering with the main attraction being lighting and shadows (as the name implies). It is recommended that any user looking into lighting be very familiar with the basic concepts of not only rendering with WGPU but the primary mathematical ideas of computer graphics. +- `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. +- `skybox` - Shows off too many concepts to list here. The name comes from game development where a "skybox" acts as a background for rendering, usually to add a sky texture for immersion, although they can also be used for backdrops to give the idea of a world beyond the game scene. This example does so much more than this, though, as it uses a car model loaded from a file and uses the user's mouse to rotate the car model in 3d. `skybox` also makes use of depth textures and similar app patterns to `uniform-values`. +- `shadow` - Likely by far the most complex example (certainly the largest in lines of code) of the official WGPU examples. `shadow` demonstrates basic scene rendering with the main attraction being lighting and shadows (as the name implies). It is recommended that any user looking into lighting be very familiar with the basic concepts of not only rendering with WGPU but also the primary mathematical ideas of computer graphics. - `render-to-texture` - Renders to an image texture offscreen, demonstrating both off-screen rendering as well as how to add a sort of resolution-agnostic screenshot feature to an engine. This example either outputs an image file of your naming (pass command line arguments after specifying a `--` like `cargo run --bin render-to-texture -- "test.png"`) or adds an `img` element containing the image to the page in WASM. #### Compute -- `hello-compute` - Demonstrates the basic workflow for getting arrays of numbers to the GPU, executing a shader on them, and getting the results back. The operation it preforms is finding the Collatz value (how many iterations of the [Collatz equation](https://en.wikipedia.org/wiki/Collatz_conjecture) it takes for the number to either reach 1 or overflow) of a set of numbers and prints the results. -- `repeated-compute` - Mostly for going into detail on subjects `hello-compute` did not. It, too, computes the Collatz conjecture but this time, it automatically loads large arrays of randomly generated numbers, prints them, runs them, and prints the result. It does this cycle 10 times. +- `hello-compute` - Demonstrates the basic workflow for getting arrays of numbers to the GPU, executing a shader on them, and getting the results back. The operation it performs is finding the Collatz value (how many iterations of the [Collatz equation](https://en.wikipedia.org/wiki/Collatz_conjecture) it takes for the number to either reach 1 or overflow) of a set of numbers and prints the results. +- `repeated-compute` - Mostly for going into detail on subjects `hello-compute` did not. It, too, computes the Collatz conjecture, but this time, it automatically loads large arrays of randomly generated numbers, prints them, runs them, and prints the result. It does this cycle 10 times. - `hello-workgroups` - Teaches the user about the basics of compute workgroups; what they are and what they can do. - `hello-synchronization` - Teaches the user about synchronization in WGSL, the ability to force all invocations in a workgroup to synchronize with each other before continuing via a sort of barrier. -- `storage-texture` - Demonstrates the use of storage textures as outputs to compute shaders. The example on the outside seems very similar to `render-to-texture` in that it outputs an image either to the file system or the web page except displaying a grayscale render of the Mandelbrot Set. However, inside, the example dispatches a grid of compute workgroups, one for each pixel which calculates the pixel value and stores it to the corresponding pixel of the output storage texture. +- `storage-texture` - Demonstrates the use of storage textures as outputs to compute shaders. The example on the outside seems very similar to `render-to-texture` in that it outputs an image either to the file system or the web page, except displaying a grayscale render of the Mandelbrot Set. However, inside, the example dispatches a grid of compute workgroups, one for each pixel, which calculates the pixel value and stores it to the corresponding pixel of the output storage texture. #### Combined -- `boids` - Demonstrates how to combine compute and render workflows by preforming a [boid](https://en.wikipedia.org/wiki/Boids) simulation and rendering the boids to the screen as little triangles. +- `boids` - Demonstrates how to combine compute and render workflows by performing a [boid](https://en.wikipedia.org/wiki/Boids) simulation and rendering the boids to the screen as little triangles. ## Feature matrix @@ -83,7 +83,7 @@ The rest of the example are for demonstrating specific features that you can com ## Additional notes -Note that the examples regarding computing build off of each other; repeated-compute extends hello-compute, hello-workgroups assumes you know the basic workflow of gpu computation, and hello-synchronization assumes you know what a workgroup is. Also note that the computing examples cannot be downleveled to WebGL as WebGL does not allow storage textures. Running these in a browser will require that browser to support WebGPU. +Note that the examples regarding computing build off of each other; repeated-compute extends hello-compute, hello-workgroups assumes you know the basic workflow of GPU computation, and hello-synchronization assumes you know what a workgroup is. Also, note that the computing examples cannot be downleveled to WebGL as WebGL does not allow storage textures. Running these in a browser will require that browser to support WebGPU. All the examples use [WGSL](https://gpuweb.github.io/gpuweb/wgsl.html) shaders unless specified otherwise. @@ -91,8 +91,8 @@ All framework-based examples render to the window and are reftested against the ## Hacking -You can record an API trace any of the framework-based examples by starting them as: +You can record an API trace for any of the framework-based examples by starting them as: ```sh -mkdir -p trace && WGPU_TRACE=trace cargo run --features trace --bin +mkdir -p trace && WGPU_TRACE=trace cargo run --features trace --bin wgpu-examples ``` diff --git a/naga/README.md b/naga/README.md index 04ed84ab5e..8cce5bc35f 100644 --- a/naga/README.md +++ b/naga/README.md @@ -33,7 +33,7 @@ DOT (GraphViz) | :ok: | dot-out | Not a shading language | ## Conversion tool -Naga can be used as a CLI, which allows to test the conversion of different code paths. +Naga can be used as a CLI, which allows testing the conversion of different code paths. First, install `naga-cli` from crates.io or directly from GitHub. @@ -54,7 +54,7 @@ naga my_shader.spv my_shader.metal --flow-dir flow-dir # convert the SPV to Meta naga my_shader.wgsl my_shader.vert --profile es310 # convert the WGSL to GLSL vertex stage under ES 3.20 profile ``` -As naga includes a default binary target, you can also use `cargo run` without installation. This is useful when you develop naga itself, or investigate the behavior of naga at a specific commit (e.g. [wgpu](https://github.com/gfx-rs/wgpu) might pin a different version of naga than the `HEAD` of this repository). +As naga includes a default binary target, you can also use `cargo run` without installation. This is useful when you develop naga itself or investigate the behavior of naga at a specific commit (e.g. [wgpu](https://github.com/gfx-rs/wgpu) might pin a different version of naga than the `HEAD` of this repository). ```bash cargo run my_shader.wgsl @@ -63,7 +63,7 @@ cargo run my_shader.wgsl ## Development workflow The main instrument aiding the development is the good old `cargo test --all-features --workspace`, -which will run the unit tests, and also update all the snapshots. You'll see these +which will run the unit tests and also update all the snapshots. You'll see these changes in git before committing the code. If working on a particular front-end or back-end, it may be convenient to @@ -71,7 +71,7 @@ enable the relevant features in `Cargo.toml`, e.g. ```toml default = ["spv-out"] #TEMP! ``` -This allows IDE basic checks to report errors there, unless your IDE is sufficiently configurable already. +This allows IDE basic checks to report errors there unless your IDE is sufficiently configurable already. Finally, when changes to the snapshots are made, we should verify that the produced shaders are indeed valid for the target platforms they are compiled for: diff --git a/naga/src/front/wgsl/error.rs b/naga/src/front/wgsl/error.rs index dc10124680..f2db433e81 100644 --- a/naga/src/front/wgsl/error.rs +++ b/naga/src/front/wgsl/error.rs @@ -34,9 +34,9 @@ impl ParseError { .with_labels( self.labels .iter() - .map(|label| { - Label::primary((), label.0.to_range().unwrap()) - .with_message(label.1.to_string()) + .filter_map(|label| label.0.to_range().map(|range| (label, range))) + .map(|(label, range)| { + Label::primary((), range).with_message(label.1.to_string()) }) .collect(), ) diff --git a/naga/src/front/wgsl/lower/construction.rs b/naga/src/front/wgsl/lower/construction.rs index c7e4106460..96cc45bfa5 100644 --- a/naga/src/front/wgsl/lower/construction.rs +++ b/naga/src/front/wgsl/lower/construction.rs @@ -448,7 +448,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ctx.try_automatic_conversions_slice( &mut components, &Tr::Value(component_ty), - span, + ty_span, )?; expr = crate::Expression::Compose { ty, components }; } @@ -497,7 +497,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { // Array constructor, explicit type (components, Constructor::Type((ty, &crate::TypeInner::Array { base, .. }))) => { let mut components = components.into_components_vec(); - ctx.try_automatic_conversions_slice(&mut components, &Tr::Handle(base), span)?; + ctx.try_automatic_conversions_slice(&mut components, &Tr::Handle(base), ty_span)?; expr = crate::Expression::Compose { ty, components }; } diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index b050ffc343..6486e6cf6b 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -875,10 +875,30 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ast::GlobalDeclKind::Var(ref v) => { let ty = self.resolve_ast_type(v.ty, &mut ctx)?; - let init = v - .init - .map(|init| self.expression(init, &mut ctx.as_const())) - .transpose()?; + let init; + if let Some(init_ast) = v.init { + let mut ectx = ctx.as_const(); + let lowered = self.expression_for_abstract(init_ast, &mut ectx)?; + let ty_res = crate::proc::TypeResolution::Handle(ty); + let converted = ectx + .try_automatic_conversions(lowered, &ty_res, v.name.span) + .map_err(|error| match error { + Error::AutoConversion { + dest_span: _, + dest_type, + source_span: _, + source_type, + } => Error::InitializationTypeMismatch { + name: v.name.span, + expected: dest_type, + got: source_type, + }, + other => other, + })?; + init = Some(converted); + } else { + init = None; + } let binding = if let Some(ref binding) = v.binding { Some(crate::ResourceBinding { @@ -1142,45 +1162,49 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { return Ok(()); } ast::LocalDecl::Var(ref v) => { - let mut emitter = Emitter::default(); - emitter.start(&ctx.function.expressions); - - let initializer = match v.init { - Some(init) => Some( - self.expression(init, &mut ctx.as_expression(block, &mut emitter))?, - ), - None => None, - }; - let explicit_ty = - v.ty.map(|ty| self.resolve_ast_type(ty, &mut ctx.as_global())) + v.ty.map(|ast| self.resolve_ast_type(ast, &mut ctx.as_global())) .transpose()?; - let ty = match (explicit_ty, initializer) { - (Some(explicit), Some(initializer)) => { - let mut ctx = ctx.as_expression(block, &mut emitter); - let initializer_ty = resolve_inner!(ctx, initializer); - if !ctx.module.types[explicit] - .inner - .equivalent(initializer_ty, &ctx.module.types) - { - let gctx = &ctx.module.to_ctx(); - return Err(Error::InitializationTypeMismatch { + let mut emitter = Emitter::default(); + emitter.start(&ctx.function.expressions); + let mut ectx = ctx.as_expression(block, &mut emitter); + + let ty; + let initializer; + match (v.init, explicit_ty) { + (Some(init), Some(explicit_ty)) => { + let init = self.expression_for_abstract(init, &mut ectx)?; + let ty_res = crate::proc::TypeResolution::Handle(explicit_ty); + let init = ectx + .try_automatic_conversions(init, &ty_res, v.name.span) + .map_err(|error| match error { + Error::AutoConversion { + dest_span: _, + dest_type, + source_span: _, + source_type, + } => Error::InitializationTypeMismatch { name: v.name.span, - expected: explicit.to_wgsl(gctx), - got: initializer_ty.to_wgsl(gctx), - }); - } - explicit + expected: dest_type, + got: source_type, + }, + other => other, + })?; + ty = explicit_ty; + initializer = Some(init); } - (Some(explicit), None) => explicit, - (None, Some(initializer)) => ctx - .as_expression(block, &mut emitter) - .register_type(initializer)?, - (None, None) => { - return Err(Error::MissingType(v.name.span)); + (Some(init), None) => { + let concretized = self.expression(init, &mut ectx)?; + ty = ectx.register_type(concretized)?; + initializer = Some(concretized); } - }; + (None, Some(explicit_ty)) => { + ty = explicit_ty; + initializer = None; + } + (None, None) => return Err(Error::MissingType(v.name.span)), + } let (const_initializer, initializer) = { match initializer { diff --git a/naga/tests/in/abstract-types.wgsl b/naga/tests/in/abstract-types-const.wgsl similarity index 100% rename from naga/tests/in/abstract-types.wgsl rename to naga/tests/in/abstract-types-const.wgsl diff --git a/naga/tests/in/abstract-types-var.wgsl b/naga/tests/in/abstract-types-var.wgsl new file mode 100644 index 0000000000..a733888530 --- /dev/null +++ b/naga/tests/in/abstract-types-var.wgsl @@ -0,0 +1,120 @@ +// i/x: type inferred / explicit +// vX/mX/aX: vector / matrix / array of X +// where X: u/i/f: u32 / i32 / f32 +// s: vector splat +// r: vector spread (vector arg to vector constructor) +// p: "partial" constructor (type parameter inferred) +// u/i/f/ai/af: u32 / i32 / f32 / abstract float / abstract integer as parameter +// _: just for alignment + +// Ensure that: +// - the inferred type is correct. +// - all parameters' types are considered. +// - all parameters are converted to the consensus type. + +var xvipaiai: vec2 = vec2(42, 43); +var xvupaiai: vec2 = vec2(44, 45); +var xvfpaiai: vec2 = vec2(46, 47); + +var xvupuai: vec2 = vec2(42u, 43); +var xvupaiu: vec2 = vec2(42, 43u); + +var xvuuai: vec2 = vec2(42u, 43); +var xvuaiu: vec2 = vec2(42, 43u); + +var xmfpaiaiaiai: mat2x2 = mat2x2(1, 2, 3, 4); +var xmfpafaiaiai: mat2x2 = mat2x2(1.0, 2, 3, 4); +var xmfpaiafaiai: mat2x2 = mat2x2(1, 2.0, 3, 4); +var xmfpaiaiafai: mat2x2 = mat2x2(1, 2, 3.0, 4); +var xmfpaiaiaiaf: mat2x2 = mat2x2(1, 2, 3, 4.0); + +var xvispai: vec2 = vec2(1); +var xvfspaf: vec2 = vec2(1.0); +var xvis_ai: vec2 = vec2(1); +var xvus_ai: vec2 = vec2(1); +var xvfs_ai: vec2 = vec2(1); +var xvfs_af: vec2 = vec2(1.0); + +var xafafaf: array = array(1.0, 2.0); +var xafaiai: array = array(1, 2); + +var xafpaiai: array = array(1, 2); +var xafpaiaf: array = array(1, 2.0); +var xafpafai: array = array(1.0, 2); +var xafpafaf: array = array(1.0, 2.0); + +fn all_constant_arguments() { + var xvipaiai: vec2 = vec2(42, 43); + var xvupaiai: vec2 = vec2(44, 45); + var xvfpaiai: vec2 = vec2(46, 47); + + var xvupuai: vec2 = vec2(42u, 43); + var xvupaiu: vec2 = vec2(42, 43u); + + var xvuuai: vec2 = vec2(42u, 43); + var xvuaiu: vec2 = vec2(42, 43u); + + var xmfpaiaiaiai: mat2x2 = mat2x2(1, 2, 3, 4); + var xmfpafaiaiai: mat2x2 = mat2x2(1.0, 2, 3, 4); + var xmfpaiafaiai: mat2x2 = mat2x2(1, 2.0, 3, 4); + var xmfpaiaiafai: mat2x2 = mat2x2(1, 2, 3.0, 4); + var xmfpaiaiaiaf: mat2x2 = mat2x2(1, 2, 3, 4.0); + + var xmfp_faiaiai: mat2x2 = mat2x2(1.0f, 2, 3, 4); + var xmfpai_faiai: mat2x2 = mat2x2(1, 2.0f, 3, 4); + var xmfpaiai_fai: mat2x2 = mat2x2(1, 2, 3.0f, 4); + var xmfpaiaiai_f: mat2x2 = mat2x2(1, 2, 3, 4.0f); + + var xvispai: vec2 = vec2(1); + var xvfspaf: vec2 = vec2(1.0); + var xvis_ai: vec2 = vec2(1); + var xvus_ai: vec2 = vec2(1); + var xvfs_ai: vec2 = vec2(1); + var xvfs_af: vec2 = vec2(1.0); + + var xafafaf: array = array(1.0, 2.0); + var xaf_faf: array = array(1.0f, 2.0); + var xafaf_f: array = array(1.0, 2.0f); + var xafaiai: array = array(1, 2); + var xai_iai: array = array(1i, 2); + var xaiai_i: array = array(1, 2i); + + // Ideally these would infer the var type from the initializer, + // but we don't support that yet. + var xaipaiai: array = array(1, 2); + var xafpaiai: array = array(1, 2); + var xafpaiaf: array = array(1, 2.0); + var xafpafai: array = array(1.0, 2); + var xafpafaf: array = array(1.0, 2.0); +} + +fn mixed_constant_and_runtime_arguments() { + var u: u32; + var i: i32; + var f: f32; + + var xvupuai: vec2 = vec2(u, 43); + var xvupaiu: vec2 = vec2(42, u); + + var xvuuai: vec2 = vec2(u, 43); + var xvuaiu: vec2 = vec2(42, u); + + var xmfp_faiaiai: mat2x2 = mat2x2(f, 2, 3, 4); + var xmfpai_faiai: mat2x2 = mat2x2(1, f, 3, 4); + var xmfpaiai_fai: mat2x2 = mat2x2(1, 2, f, 4); + var xmfpaiaiai_f: mat2x2 = mat2x2(1, 2, 3, f); + + var xaf_faf: array = array(f, 2.0); + var xafaf_f: array = array(1.0, f); + var xaf_fai: array = array(f, 2); + var xafai_f: array = array(1, f); + var xai_iai: array = array(i, 2); + var xaiai_i: array = array(1, i); + + var xafp_faf: array = array(f, 2.0); + var xafpaf_f: array = array(1.0, f); + var xafp_fai: array = array(f, 2); + var xafpai_f: array = array(1, f); + var xaip_iai: array = array(i, 2); + var xaipai_i: array = array(1, i); +} diff --git a/naga/tests/out/msl/abstract-types.msl b/naga/tests/out/msl/abstract-types-const.msl similarity index 100% rename from naga/tests/out/msl/abstract-types.msl rename to naga/tests/out/msl/abstract-types-const.msl diff --git a/naga/tests/out/msl/abstract-types-var.msl b/naga/tests/out/msl/abstract-types-var.msl new file mode 100644 index 0000000000..45096f8672 --- /dev/null +++ b/naga/tests/out/msl/abstract-types-var.msl @@ -0,0 +1,117 @@ +// language: metal1.0 +#include +#include + +using metal::uint; + +struct type_5 { + float inner[2]; +}; +struct type_7 { + int inner[2]; +}; + +void all_constant_arguments( +) { + metal::int2 xvipaiai = metal::int2(42, 43); + metal::uint2 xvupaiai = metal::uint2(44u, 45u); + metal::float2 xvfpaiai = metal::float2(46.0, 47.0); + metal::uint2 xvupuai = metal::uint2(42u, 43u); + metal::uint2 xvupaiu = metal::uint2(42u, 43u); + metal::uint2 xvuuai = metal::uint2(42u, 43u); + metal::uint2 xvuaiu = metal::uint2(42u, 43u); + metal::float2x2 xmfpaiaiaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::float2x2 xmfpafaiaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::float2x2 xmfpaiafaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::float2x2 xmfpaiaiafai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::float2x2 xmfpaiaiaiaf = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::float2x2 xmfp_faiaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::float2x2 xmfpai_faiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::float2x2 xmfpaiai_fai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::float2x2 xmfpaiaiai_f = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0)); + metal::int2 xvispai = metal::int2(1); + metal::float2 xvfspaf = metal::float2(1.0); + metal::int2 xvis_ai = metal::int2(1); + metal::uint2 xvus_ai = metal::uint2(1u); + metal::float2 xvfs_ai = metal::float2(1.0); + metal::float2 xvfs_af = metal::float2(1.0); + type_5 xafafaf = type_5 {1.0, 2.0}; + type_5 xaf_faf = type_5 {1.0, 2.0}; + type_5 xafaf_f = type_5 {1.0, 2.0}; + type_5 xafaiai = type_5 {1.0, 2.0}; + type_7 xai_iai = type_7 {1, 2}; + type_7 xaiai_i = type_7 {1, 2}; + type_7 xaipaiai = type_7 {1, 2}; + type_5 xafpaiai = type_5 {1.0, 2.0}; + type_5 xafpaiaf = type_5 {1.0, 2.0}; + type_5 xafpafai = type_5 {1.0, 2.0}; + type_5 xafpafaf = type_5 {1.0, 2.0}; +} + +void mixed_constant_and_runtime_arguments( +) { + uint u = {}; + int i = {}; + float f = {}; + metal::uint2 xvupuai_1 = {}; + metal::uint2 xvupaiu_1 = {}; + metal::uint2 xvuuai_1 = {}; + metal::uint2 xvuaiu_1 = {}; + metal::float2x2 xmfp_faiaiai_1 = {}; + metal::float2x2 xmfpai_faiai_1 = {}; + metal::float2x2 xmfpaiai_fai_1 = {}; + metal::float2x2 xmfpaiaiai_f_1 = {}; + type_5 xaf_faf_1 = {}; + type_5 xafaf_f_1 = {}; + type_5 xaf_fai = {}; + type_5 xafai_f = {}; + type_7 xai_iai_1 = {}; + type_7 xaiai_i_1 = {}; + type_5 xafp_faf = {}; + type_5 xafpaf_f = {}; + type_5 xafp_fai = {}; + type_5 xafpai_f = {}; + type_7 xaip_iai = {}; + type_7 xaipai_i = {}; + uint _e3 = u; + xvupuai_1 = metal::uint2(_e3, 43u); + uint _e7 = u; + xvupaiu_1 = metal::uint2(42u, _e7); + uint _e11 = u; + xvuuai_1 = metal::uint2(_e11, 43u); + uint _e15 = u; + xvuaiu_1 = metal::uint2(42u, _e15); + float _e19 = f; + xmfp_faiaiai_1 = metal::float2x2(metal::float2(_e19, 2.0), metal::float2(3.0, 4.0)); + float _e27 = f; + xmfpai_faiai_1 = metal::float2x2(metal::float2(1.0, _e27), metal::float2(3.0, 4.0)); + float _e35 = f; + xmfpaiai_fai_1 = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(_e35, 4.0)); + float _e43 = f; + xmfpaiaiai_f_1 = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, _e43)); + float _e51 = f; + xaf_faf_1 = type_5 {_e51, 2.0}; + float _e55 = f; + xafaf_f_1 = type_5 {1.0, _e55}; + float _e59 = f; + xaf_fai = type_5 {_e59, 2.0}; + float _e63 = f; + xafai_f = type_5 {1.0, _e63}; + int _e67 = i; + xai_iai_1 = type_7 {_e67, 2}; + int _e71 = i; + xaiai_i_1 = type_7 {1, _e71}; + float _e75 = f; + xafp_faf = type_5 {_e75, 2.0}; + float _e79 = f; + xafpaf_f = type_5 {1.0, _e79}; + float _e83 = f; + xafp_fai = type_5 {_e83, 2.0}; + float _e87 = f; + xafpai_f = type_5 {1.0, _e87}; + int _e91 = i; + xaip_iai = type_7 {_e91, 2}; + int _e95 = i; + xaipai_i = type_7 {1, _e95}; + return; +} diff --git a/naga/tests/out/spv/abstract-types.spvasm b/naga/tests/out/spv/abstract-types-const.spvasm similarity index 100% rename from naga/tests/out/spv/abstract-types.spvasm rename to naga/tests/out/spv/abstract-types-const.spvasm diff --git a/naga/tests/out/spv/abstract-types-var.spvasm b/naga/tests/out/spv/abstract-types-var.spvasm new file mode 100644 index 0000000000..1b4b0664b4 --- /dev/null +++ b/naga/tests/out/spv/abstract-types-var.spvasm @@ -0,0 +1,243 @@ +; SPIR-V +; Version: 1.1 +; Generator: rspirv +; Bound: 209 +OpCapability Shader +OpCapability Linkage +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpDecorate %10 ArrayStride 4 +OpDecorate %12 ArrayStride 4 +%2 = OpTypeVoid +%4 = OpTypeInt 32 1 +%3 = OpTypeVector %4 2 +%6 = OpTypeInt 32 0 +%5 = OpTypeVector %6 2 +%8 = OpTypeFloat 32 +%7 = OpTypeVector %8 2 +%9 = OpTypeMatrix %7 2 +%11 = OpConstant %6 2 +%10 = OpTypeArray %8 %11 +%12 = OpTypeArray %4 %11 +%13 = OpConstant %4 42 +%14 = OpConstant %4 43 +%15 = OpConstantComposite %3 %13 %14 +%16 = OpConstant %6 44 +%17 = OpConstant %6 45 +%18 = OpConstantComposite %5 %16 %17 +%19 = OpConstant %8 46.0 +%20 = OpConstant %8 47.0 +%21 = OpConstantComposite %7 %19 %20 +%22 = OpConstant %6 42 +%23 = OpConstant %6 43 +%24 = OpConstantComposite %5 %22 %23 +%25 = OpConstant %8 1.0 +%26 = OpConstant %8 2.0 +%27 = OpConstantComposite %7 %25 %26 +%28 = OpConstant %8 3.0 +%29 = OpConstant %8 4.0 +%30 = OpConstantComposite %7 %28 %29 +%31 = OpConstantComposite %9 %27 %30 +%32 = OpConstant %4 1 +%33 = OpConstantComposite %3 %32 %32 +%34 = OpConstantComposite %7 %25 %25 +%35 = OpConstant %6 1 +%36 = OpConstantComposite %5 %35 %35 +%37 = OpConstantComposite %10 %25 %26 +%38 = OpConstant %4 2 +%39 = OpConstantComposite %12 %32 %38 +%41 = OpTypePointer Private %3 +%40 = OpVariable %41 Private %15 +%43 = OpTypePointer Private %5 +%42 = OpVariable %43 Private %18 +%45 = OpTypePointer Private %7 +%44 = OpVariable %45 Private %21 +%46 = OpVariable %43 Private %24 +%47 = OpVariable %43 Private %24 +%48 = OpVariable %43 Private %24 +%49 = OpVariable %43 Private %24 +%51 = OpTypePointer Private %9 +%50 = OpVariable %51 Private %31 +%52 = OpVariable %51 Private %31 +%53 = OpVariable %51 Private %31 +%54 = OpVariable %51 Private %31 +%55 = OpVariable %51 Private %31 +%56 = OpVariable %41 Private %33 +%57 = OpVariable %45 Private %34 +%58 = OpVariable %41 Private %33 +%59 = OpVariable %43 Private %36 +%60 = OpVariable %45 Private %34 +%61 = OpVariable %45 Private %34 +%63 = OpTypePointer Private %10 +%62 = OpVariable %63 Private %37 +%64 = OpVariable %63 Private %37 +%66 = OpTypePointer Private %12 +%65 = OpVariable %66 Private %39 +%67 = OpVariable %63 Private %37 +%68 = OpVariable %63 Private %37 +%69 = OpVariable %63 Private %37 +%72 = OpTypeFunction %2 +%74 = OpTypePointer Function %3 +%76 = OpTypePointer Function %5 +%78 = OpTypePointer Function %7 +%84 = OpTypePointer Function %9 +%100 = OpTypePointer Function %10 +%105 = OpTypePointer Function %12 +%116 = OpTypePointer Function %6 +%117 = OpConstantNull %6 +%119 = OpTypePointer Function %4 +%120 = OpConstantNull %4 +%122 = OpTypePointer Function %8 +%123 = OpConstantNull %8 +%125 = OpConstantNull %5 +%127 = OpConstantNull %5 +%129 = OpConstantNull %5 +%131 = OpConstantNull %5 +%133 = OpConstantNull %9 +%135 = OpConstantNull %9 +%137 = OpConstantNull %9 +%139 = OpConstantNull %9 +%141 = OpConstantNull %10 +%143 = OpConstantNull %10 +%145 = OpConstantNull %10 +%147 = OpConstantNull %10 +%149 = OpConstantNull %12 +%151 = OpConstantNull %12 +%153 = OpConstantNull %10 +%155 = OpConstantNull %10 +%157 = OpConstantNull %10 +%159 = OpConstantNull %10 +%161 = OpConstantNull %12 +%163 = OpConstantNull %12 +%71 = OpFunction %2 None %72 +%70 = OpLabel +%109 = OpVariable %100 Function %37 +%106 = OpVariable %105 Function %39 +%102 = OpVariable %100 Function %37 +%98 = OpVariable %78 Function %34 +%95 = OpVariable %74 Function %33 +%92 = OpVariable %84 Function %31 +%89 = OpVariable %84 Function %31 +%86 = OpVariable %84 Function %31 +%82 = OpVariable %76 Function %24 +%79 = OpVariable %76 Function %24 +%73 = OpVariable %74 Function %15 +%110 = OpVariable %100 Function %37 +%107 = OpVariable %105 Function %39 +%103 = OpVariable %100 Function %37 +%99 = OpVariable %100 Function %37 +%96 = OpVariable %76 Function %36 +%93 = OpVariable %74 Function %33 +%90 = OpVariable %84 Function %31 +%87 = OpVariable %84 Function %31 +%83 = OpVariable %84 Function %31 +%80 = OpVariable %76 Function %24 +%75 = OpVariable %76 Function %18 +%111 = OpVariable %100 Function %37 +%108 = OpVariable %100 Function %37 +%104 = OpVariable %105 Function %39 +%101 = OpVariable %100 Function %37 +%97 = OpVariable %78 Function %34 +%94 = OpVariable %78 Function %34 +%91 = OpVariable %84 Function %31 +%88 = OpVariable %84 Function %31 +%85 = OpVariable %84 Function %31 +%81 = OpVariable %76 Function %24 +%77 = OpVariable %78 Function %21 +OpBranch %112 +%112 = OpLabel +OpReturn +OpFunctionEnd +%114 = OpFunction %2 None %72 +%113 = OpLabel +%162 = OpVariable %105 Function %163 +%156 = OpVariable %100 Function %157 +%150 = OpVariable %105 Function %151 +%144 = OpVariable %100 Function %145 +%138 = OpVariable %84 Function %139 +%132 = OpVariable %84 Function %133 +%126 = OpVariable %76 Function %127 +%118 = OpVariable %119 Function %120 +%160 = OpVariable %105 Function %161 +%154 = OpVariable %100 Function %155 +%148 = OpVariable %105 Function %149 +%142 = OpVariable %100 Function %143 +%136 = OpVariable %84 Function %137 +%130 = OpVariable %76 Function %131 +%124 = OpVariable %76 Function %125 +%115 = OpVariable %116 Function %117 +%158 = OpVariable %100 Function %159 +%152 = OpVariable %100 Function %153 +%146 = OpVariable %100 Function %147 +%140 = OpVariable %100 Function %141 +%134 = OpVariable %84 Function %135 +%128 = OpVariable %76 Function %129 +%121 = OpVariable %122 Function %123 +OpBranch %164 +%164 = OpLabel +%165 = OpLoad %6 %115 +%166 = OpCompositeConstruct %5 %165 %23 +OpStore %124 %166 +%167 = OpLoad %6 %115 +%168 = OpCompositeConstruct %5 %22 %167 +OpStore %126 %168 +%169 = OpLoad %6 %115 +%170 = OpCompositeConstruct %5 %169 %23 +OpStore %128 %170 +%171 = OpLoad %6 %115 +%172 = OpCompositeConstruct %5 %22 %171 +OpStore %130 %172 +%173 = OpLoad %8 %121 +%174 = OpCompositeConstruct %7 %173 %26 +%175 = OpCompositeConstruct %9 %174 %30 +OpStore %132 %175 +%176 = OpLoad %8 %121 +%177 = OpCompositeConstruct %7 %25 %176 +%178 = OpCompositeConstruct %9 %177 %30 +OpStore %134 %178 +%179 = OpLoad %8 %121 +%180 = OpCompositeConstruct %7 %179 %29 +%181 = OpCompositeConstruct %9 %27 %180 +OpStore %136 %181 +%182 = OpLoad %8 %121 +%183 = OpCompositeConstruct %7 %28 %182 +%184 = OpCompositeConstruct %9 %27 %183 +OpStore %138 %184 +%185 = OpLoad %8 %121 +%186 = OpCompositeConstruct %10 %185 %26 +OpStore %140 %186 +%187 = OpLoad %8 %121 +%188 = OpCompositeConstruct %10 %25 %187 +OpStore %142 %188 +%189 = OpLoad %8 %121 +%190 = OpCompositeConstruct %10 %189 %26 +OpStore %144 %190 +%191 = OpLoad %8 %121 +%192 = OpCompositeConstruct %10 %25 %191 +OpStore %146 %192 +%193 = OpLoad %4 %118 +%194 = OpCompositeConstruct %12 %193 %38 +OpStore %148 %194 +%195 = OpLoad %4 %118 +%196 = OpCompositeConstruct %12 %32 %195 +OpStore %150 %196 +%197 = OpLoad %8 %121 +%198 = OpCompositeConstruct %10 %197 %26 +OpStore %152 %198 +%199 = OpLoad %8 %121 +%200 = OpCompositeConstruct %10 %25 %199 +OpStore %154 %200 +%201 = OpLoad %8 %121 +%202 = OpCompositeConstruct %10 %201 %26 +OpStore %156 %202 +%203 = OpLoad %8 %121 +%204 = OpCompositeConstruct %10 %25 %203 +OpStore %158 %204 +%205 = OpLoad %4 %118 +%206 = OpCompositeConstruct %12 %205 %38 +OpStore %160 %206 +%207 = OpLoad %4 %118 +%208 = OpCompositeConstruct %12 %32 %207 +OpStore %162 %208 +OpReturn +OpFunctionEnd \ No newline at end of file diff --git a/naga/tests/out/wgsl/abstract-types.wgsl b/naga/tests/out/wgsl/abstract-types-const.wgsl similarity index 100% rename from naga/tests/out/wgsl/abstract-types.wgsl rename to naga/tests/out/wgsl/abstract-types-const.wgsl diff --git a/naga/tests/out/wgsl/abstract-types-var.wgsl b/naga/tests/out/wgsl/abstract-types-var.wgsl new file mode 100644 index 0000000000..ae95ff2e82 --- /dev/null +++ b/naga/tests/out/wgsl/abstract-types-var.wgsl @@ -0,0 +1,130 @@ +var xvipaiai_1: vec2 = vec2(42, 43); +var xvupaiai_1: vec2 = vec2(44u, 45u); +var xvfpaiai_1: vec2 = vec2(46.0, 47.0); +var xvupuai_2: vec2 = vec2(42u, 43u); +var xvupaiu_2: vec2 = vec2(42u, 43u); +var xvuuai_2: vec2 = vec2(42u, 43u); +var xvuaiu_2: vec2 = vec2(42u, 43u); +var xmfpaiaiaiai_1: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xmfpafaiaiai_1: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xmfpaiafaiai_1: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xmfpaiaiafai_1: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xmfpaiaiaiaf_1: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xvispai_1: vec2 = vec2(1); +var xvfspaf_1: vec2 = vec2(1.0); +var xvis_ai_1: vec2 = vec2(1); +var xvus_ai_1: vec2 = vec2(1u); +var xvfs_ai_1: vec2 = vec2(1.0); +var xvfs_af_1: vec2 = vec2(1.0); +var xafafaf_1: array = array(1.0, 2.0); +var xafaiai_1: array = array(1.0, 2.0); +var xafpaiai_1: array = array(1, 2); +var xafpaiaf_1: array = array(1.0, 2.0); +var xafpafai_1: array = array(1.0, 2.0); +var xafpafaf_1: array = array(1.0, 2.0); + +fn all_constant_arguments() { + var xvipaiai: vec2 = vec2(42, 43); + var xvupaiai: vec2 = vec2(44u, 45u); + var xvfpaiai: vec2 = vec2(46.0, 47.0); + var xvupuai: vec2 = vec2(42u, 43u); + var xvupaiu: vec2 = vec2(42u, 43u); + var xvuuai: vec2 = vec2(42u, 43u); + var xvuaiu: vec2 = vec2(42u, 43u); + var xmfpaiaiaiai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xmfpafaiaiai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xmfpaiafaiai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xmfpaiaiafai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xmfpaiaiaiaf: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xmfp_faiaiai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xmfpai_faiai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xmfpaiai_fai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xmfpaiaiai_f: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); + var xvispai: vec2 = vec2(1); + var xvfspaf: vec2 = vec2(1.0); + var xvis_ai: vec2 = vec2(1); + var xvus_ai: vec2 = vec2(1u); + var xvfs_ai: vec2 = vec2(1.0); + var xvfs_af: vec2 = vec2(1.0); + var xafafaf: array = array(1.0, 2.0); + var xaf_faf: array = array(1.0, 2.0); + var xafaf_f: array = array(1.0, 2.0); + var xafaiai: array = array(1.0, 2.0); + var xai_iai: array = array(1, 2); + var xaiai_i: array = array(1, 2); + var xaipaiai: array = array(1, 2); + var xafpaiai: array = array(1.0, 2.0); + var xafpaiaf: array = array(1.0, 2.0); + var xafpafai: array = array(1.0, 2.0); + var xafpafaf: array = array(1.0, 2.0); + +} + +fn mixed_constant_and_runtime_arguments() { + var u: u32; + var i: i32; + var f: f32; + var xvupuai_1: vec2; + var xvupaiu_1: vec2; + var xvuuai_1: vec2; + var xvuaiu_1: vec2; + var xmfp_faiaiai_1: mat2x2; + var xmfpai_faiai_1: mat2x2; + var xmfpaiai_fai_1: mat2x2; + var xmfpaiaiai_f_1: mat2x2; + var xaf_faf_1: array; + var xafaf_f_1: array; + var xaf_fai: array; + var xafai_f: array; + var xai_iai_1: array; + var xaiai_i_1: array; + var xafp_faf: array; + var xafpaf_f: array; + var xafp_fai: array; + var xafpai_f: array; + var xaip_iai: array; + var xaipai_i: array; + + let _e3 = u; + xvupuai_1 = vec2(_e3, 43u); + let _e7 = u; + xvupaiu_1 = vec2(42u, _e7); + let _e11 = u; + xvuuai_1 = vec2(_e11, 43u); + let _e15 = u; + xvuaiu_1 = vec2(42u, _e15); + let _e19 = f; + xmfp_faiaiai_1 = mat2x2(vec2(_e19, 2.0), vec2(3.0, 4.0)); + let _e27 = f; + xmfpai_faiai_1 = mat2x2(vec2(1.0, _e27), vec2(3.0, 4.0)); + let _e35 = f; + xmfpaiai_fai_1 = mat2x2(vec2(1.0, 2.0), vec2(_e35, 4.0)); + let _e43 = f; + xmfpaiaiai_f_1 = mat2x2(vec2(1.0, 2.0), vec2(3.0, _e43)); + let _e51 = f; + xaf_faf_1 = array(_e51, 2.0); + let _e55 = f; + xafaf_f_1 = array(1.0, _e55); + let _e59 = f; + xaf_fai = array(_e59, 2.0); + let _e63 = f; + xafai_f = array(1.0, _e63); + let _e67 = i; + xai_iai_1 = array(_e67, 2); + let _e71 = i; + xaiai_i_1 = array(1, _e71); + let _e75 = f; + xafp_faf = array(_e75, 2.0); + let _e79 = f; + xafpaf_f = array(1.0, _e79); + let _e83 = f; + xafp_fai = array(_e83, 2.0); + let _e87 = f; + xafpai_f = array(1.0, _e87); + let _e91 = i; + xaip_iai = array(_e91, 2); + let _e95 = i; + xaipai_i = array(1, _e95); + return; +} + diff --git a/naga/tests/snapshots.rs b/naga/tests/snapshots.rs index 35370e7f07..c201b206a2 100644 --- a/naga/tests/snapshots.rs +++ b/naga/tests/snapshots.rs @@ -791,7 +791,11 @@ fn convert_wgsl() { Targets::SPIRV | Targets::GLSL | Targets::HLSL | Targets::WGSL, ), ( - "abstract-types", + "abstract-types-const", + Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::WGSL, + ), + ( + "abstract-types-var", Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::WGSL, ), ]; diff --git a/naga/tests/wgsl_errors.rs b/naga/tests/wgsl_errors.rs index 56ca313464..7dddf633a4 100644 --- a/naga/tests/wgsl_errors.rs +++ b/naga/tests/wgsl_errors.rs @@ -213,9 +213,8 @@ fn constructor_parameter_type_mismatch() { ┌─ wgsl:3:21 │ 3 │ _ = mat2x2(array(0, 1), vec2(2, 3)); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ │ - │ │ this expression has type array<{AbstractInt}, 2> + │ ^^^^^^^^^^^ ^^^^^^^^^^^ this expression has type array<{AbstractInt}, 2> + │ │ │ a value of type vec2 is required here "#, @@ -1985,6 +1984,41 @@ fn function_param_redefinition_as_local() { ) } +#[test] +fn constructor_type_error_span() { + check( + " + fn unfortunate() { + var i: i32; + var a: array = array(i); + } + ", + r###"error: automatic conversions cannot convert `i32` to `f32` + ┌─ wgsl:4:36 + │ +4 │ var a: array = array(i); + │ ^^^^^^^^^^^^^ a value of type f32 is required here + +"###, + ) +} + +#[test] +fn global_initialization_type_mismatch() { + check( + " + var a: vec2 = vec2(1i, 2i); + ", + r###"error: the type of `a` is expected to be `vec2`, but got `vec2` + ┌─ wgsl:2:22 + │ +2 │ var a: vec2 = vec2(1i, 2i); + │ ^ definition of `a` + +"###, + ) +} + #[test] fn binding_array_local() { check_validation! { diff --git a/player/Cargo.toml b/player/Cargo.toml index 8e05346e2c..63493a4ee2 100644 --- a/player/Cargo.toml +++ b/player/Cargo.toml @@ -33,7 +33,7 @@ features = ["replay"] [target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgc] workspace = true -features = ["replay", "raw-window-handle", "strict_asserts", "wgsl", "metal", "dx11", "dx12", "vulkan", "gles"] +features = ["replay", "raw-window-handle", "strict_asserts", "wgsl", "metal", "dx12", "vulkan", "gles"] [dev-dependencies] serde.workspace = true diff --git a/player/README.md b/player/README.md index 859e079c7e..c816dd57e7 100644 --- a/player/README.md +++ b/player/README.md @@ -1,13 +1,13 @@ # wgpu player This is an application that allows replaying the `wgpu` workloads recorded elsewhere. It requires the player to be built from -the same revision as an application was linking to, or otherwise the data may fail to load. +the same revision as an application was linking to, or otherwise, the data may fail to load. Launch as: ```rust play ``` -When built with "winit" feature, it's able to replay the workloads that operate on a swapchain. It renders each frame sequentially, then waits for the user to close the window. When built without "winit", it launches in console mode and can replay any trace that doesn't use swapchains. +When built with "winit" feature, it's able to replay the workloads that operate on a swapchain. It renders each frame sequentially and then waits for the user to close the window. When built without "winit", it launches in console mode and can replay any trace that doesn't use swapchains. -Note: replaying is currently restricted to the same backend, as one used for recording a trace. It is straightforward, however, to just replace the backend in RON, since it's serialized as plain text. Valid values are: Vulkan, Metal, Dx12, and Dx11. +Note: replaying is currently restricted to the same backend as one used for recording a trace. It is straightforward, however, to just replace the backend in RON since it's serialized as plain text. Valid values are: Vulkan, Metal, and Dx12. diff --git a/player/tests/test.rs b/player/tests/test.rs index 76983ec2fc..a622742b67 100644 --- a/player/tests/test.rs +++ b/player/tests/test.rs @@ -68,7 +68,6 @@ impl Test<'_> { wgt::Backend::Vulkan => "Vulkan", wgt::Backend::Metal => "Metal", wgt::Backend::Dx12 => "Dx12", - wgt::Backend::Dx11 => "Dx11", wgt::Backend::Gl => "Gl", _ => unreachable!(), }; @@ -170,7 +169,6 @@ const BACKENDS: &[wgt::Backend] = &[ wgt::Backend::Vulkan, wgt::Backend::Metal, wgt::Backend::Dx12, - wgt::Backend::Dx11, wgt::Backend::Gl, ]; diff --git a/tests/src/expectations.rs b/tests/src/expectations.rs index 369e0d69ea..ee48e83aa8 100644 --- a/tests/src/expectations.rs +++ b/tests/src/expectations.rs @@ -11,7 +11,7 @@ /// ``` /// # use wgpu_test::*; /// FailureCase { -/// backends: Some(wgpu::Backends::DX11 | wgpu::Backends::DX12), +/// backends: Some(wgpu::Backends::DX12), /// vendor: None, /// adapter: Some("RTX"), /// driver: None, diff --git a/tests/tests/bgra8unorm_storage.rs b/tests/tests/bgra8unorm_storage.rs index 0caf7f80e3..942b6c5a8b 100644 --- a/tests/tests/bgra8unorm_storage.rs +++ b/tests/tests/bgra8unorm_storage.rs @@ -1,4 +1,4 @@ -//! Tests for texture copy bounds checks. +//! Tests for BGRA8UNORM_STORAGE feature use std::borrow::Cow; diff --git a/tests/tests/float32_filterable.rs b/tests/tests/float32_filterable.rs new file mode 100644 index 0000000000..c170deda9b --- /dev/null +++ b/tests/tests/float32_filterable.rs @@ -0,0 +1,75 @@ +//! Tests for FLOAT32_FILTERABLE feature. + +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, TestParameters}; + +fn create_texture_binding(device: &wgpu::Device, format: wgpu::TextureFormat, filterable: bool) { + let texture = device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, + view_formats: &[], + }); + + let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); + + let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable }, + multisampled: false, + view_dimension: wgpu::TextureViewDimension::D2, + }, + count: None, + }], + }); + + let _bg = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &bgl, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&view), + }], + }); +} + +#[gpu_test] +static FLOAT32_FILTERABLE_WITHOUT_FEATURE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default()) + .run_sync(|ctx| { + let device = &ctx.device; + // Unorm textures are always filterable + create_texture_binding(device, wgpu::TextureFormat::R8Unorm, true); + create_texture_binding(device, wgpu::TextureFormat::R8Unorm, false); + // As are float16 textures + create_texture_binding(device, wgpu::TextureFormat::R16Float, true); + create_texture_binding(device, wgpu::TextureFormat::R16Float, false); + // Float 32 textures can be used as non-filterable only + create_texture_binding(device, wgpu::TextureFormat::R32Float, false); + // This is supposed to fail, since we have not activated the feature + fail(&ctx.device, || { + create_texture_binding(device, wgpu::TextureFormat::R32Float, true); + }); + }); + +#[gpu_test] +static FLOAT32_FILTERABLE_WITH_FEATURE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().features(wgpu::Features::FLOAT32_FILTERABLE)) + .run_sync(|ctx| { + let device = &ctx.device; + // With the feature enabled, it does work! + create_texture_binding(device, wgpu::TextureFormat::R32Float, true); + create_texture_binding(device, wgpu::TextureFormat::Rg32Float, true); + create_texture_binding(device, wgpu::TextureFormat::Rgba32Float, true); + }); diff --git a/tests/tests/root.rs b/tests/tests/root.rs index 5fd119b2c9..e3f116b0c7 100644 --- a/tests/tests/root.rs +++ b/tests/tests/root.rs @@ -15,6 +15,7 @@ mod create_surface_error; mod device; mod encoder; mod external_texture; +mod float32_filterable; mod instance; mod life_cycle; mod mem_leaks; diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index ecfb315d27..ee908124b7 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -38,7 +38,6 @@ resource_log_info = [] metal = ["hal/metal"] vulkan = ["hal/vulkan"] gles = ["hal/gles"] -dx11 = ["hal/dx11"] dx12 = ["hal/dx12"] # Use static linking for libraries. Disale to manually link. Enabled by default. diff --git a/wgpu-core/src/any_surface.rs b/wgpu-core/src/any_surface.rs index 757e5c152b..5ae3295dc1 100644 --- a/wgpu-core/src/any_surface.rs +++ b/wgpu-core/src/any_surface.rs @@ -35,10 +35,6 @@ impl AnySurface { if self.downcast_ref::().is_some() { return Backend::Dx12; } - #[cfg(all(feature = "dx11", windows))] - if self.downcast_ref::().is_some() { - return Backend::Dx11; - } #[cfg(feature = "gles")] if self.downcast_ref::().is_some() { return Backend::Gl; diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index b043e2106c..f375bef6b1 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -526,7 +526,7 @@ impl Global { if wait { match device.wait_for_submit(last_submit_index) { Ok(()) => (), - Err(e) => log::error!("Failed to wait for buffer {:?}: {:?}", buffer_id, e), + Err(e) => log::error!("Failed to wait for buffer {:?}: {}", buffer_id, e), } } } @@ -574,7 +574,7 @@ impl Global { return (id, None); }; - log::error!("Device::create_texture error {error:?}"); + log::error!("Device::create_texture error: {error}"); let id = fid.assign_error(desc.label.borrow_or_default()); (id, Some(error)) @@ -648,7 +648,7 @@ impl Global { return (id, None); }; - log::error!("Device::create_texture error {error:?}"); + log::error!("Device::create_texture error: {error}"); let id = fid.assign_error(desc.label.borrow_or_default()); (id, Some(error)) @@ -702,7 +702,7 @@ impl Global { return (id, None); }; - log::error!("Device::create_buffer error {error:?}"); + log::error!("Device::create_buffer error: {error}"); let id = fid.assign_error(desc.label.borrow_or_default()); (id, Some(error)) @@ -790,7 +790,7 @@ impl Global { if wait { match device.wait_for_submit(last_submit_index) { Ok(()) => (), - Err(e) => log::error!("Failed to wait for texture {:?}: {:?}", texture_id, e), + Err(e) => log::error!("Failed to wait for texture {texture_id:?}: {e}"), } } } @@ -835,7 +835,7 @@ impl Global { return (id, None); }; - log::error!("Texture::create_view({texture_id:?}) error {error:?}"); + log::error!("Texture::create_view({texture_id:?}) error: {error}"); let id = fid.assign_error(desc.label.borrow_or_default()); (id, Some(error)) } @@ -865,11 +865,9 @@ impl Global { if wait { match view.device.wait_for_submit(last_submit_index) { Ok(()) => (), - Err(e) => log::error!( - "Failed to wait for texture view {:?}: {:?}", - texture_view_id, - e - ), + Err(e) => { + log::error!("Failed to wait for texture view {texture_view_id:?}: {e}") + } } } } @@ -1217,7 +1215,7 @@ impl Global { return (id, None); }; - log::error!("Device::create_shader_module error: {error:?}"); + log::error!("Device::create_shader_module error: {error}"); let id = fid.assign_error(desc.label.borrow_or_default()); (id, Some(error)) @@ -1274,7 +1272,7 @@ impl Global { return (id, None); }; - log::error!("Device::create_shader_module_spirv error: {error:?}"); + log::error!("Device::create_shader_module_spirv error: {error}"); let id = fid.assign_error(desc.label.borrow_or_default()); (id, Some(error)) @@ -1598,7 +1596,7 @@ impl Global { } } - log::error!("Device::create_render_pipeline error {error:?}"); + log::error!("Device::create_render_pipeline error: {error}"); (id, Some(error)) } @@ -2180,11 +2178,6 @@ impl Global { all_queue_empty = self.poll_device::(force_wait, &mut closures)? && all_queue_empty; } - #[cfg(all(feature = "dx11", windows))] - { - all_queue_empty = - self.poll_device::(force_wait, &mut closures)? && all_queue_empty; - } #[cfg(feature = "gles")] { all_queue_empty = @@ -2321,7 +2314,7 @@ impl Global { if let Some(callback) = operation.callback.take() { callback.call(Err(err.clone())); } - log::error!("Buffer::map_async error {err:?}"); + log::error!("Buffer::map_async error: {err}"); return Err(err); } diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 8b421c11af..0193d0987b 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -930,7 +930,7 @@ impl LifetimeTracker { Ok(()) } Err(e) => { - log::error!("Mapping failed {:?}", e); + log::error!("Mapping failed: {e}"); Err(e) } } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 246661d5dd..e8f6802edb 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -268,7 +268,7 @@ impl Device { Some(trace) } Err(e) => { - log::error!("Unable to start a trace in '{:?}': {:?}", path, e); + log::error!("Unable to start a trace in '{path:?}': {e}"); None } })), @@ -2065,7 +2065,7 @@ impl Device { .views .add_single(&*texture_view_guard, id) .ok_or(Error::InvalidTextureView(id))?; - let (pub_usage, internal_use) = Self::texture_use_parameters( + let (pub_usage, internal_use) = self.texture_use_parameters( binding, decl, view, @@ -2096,7 +2096,7 @@ impl Device { .add_single(&*texture_view_guard, id) .ok_or(Error::InvalidTextureView(id))?; let (pub_usage, internal_use) = - Self::texture_use_parameters(binding, decl, view, + self.texture_use_parameters(binding, decl, view, "SampledTextureArray, ReadonlyStorageTextureArray or WriteonlyStorageTextureArray")?; Self::create_texture_binding( view, @@ -2199,6 +2199,7 @@ impl Device { } pub(crate) fn texture_use_parameters( + self: &Arc, binding: u32, decl: &wgt::BindGroupLayoutEntry, view: &TextureView, @@ -2229,7 +2230,7 @@ impl Device { let compat_sample_type = view .desc .format - .sample_type(Some(view.desc.range.aspect)) + .sample_type(Some(view.desc.range.aspect), Some(self.features)) .unwrap(); match (sample_type, compat_sample_type) { (Tst::Uint, Tst::Uint) | @@ -3200,6 +3201,24 @@ impl Device { Ok(pipeline) } + pub(crate) fn get_texture_format_features( + &self, + adapter: &Adapter, + format: TextureFormat, + ) -> wgt::TextureFormatFeatures { + // Variant of adapter.get_texture_format_features that takes device features into account + use wgt::TextureFormatFeatureFlags as tfsc; + let mut format_features = adapter.get_texture_format_features(format); + if (format == TextureFormat::R32Float + || format == TextureFormat::Rg32Float + || format == TextureFormat::Rgba32Float) + && !self.features.contains(wgt::Features::FLOAT32_FILTERABLE) + { + format_features.flags.set(tfsc::FILTERABLE, false); + } + format_features + } + pub(crate) fn describe_format_features( &self, adapter: &Adapter, @@ -3215,7 +3234,7 @@ impl Device { let downlevel = !self.downlevel.is_webgpu_compliant(); if using_device_features || downlevel { - Ok(adapter.get_texture_format_features(format)) + Ok(self.get_texture_format_features(adapter, format)) } else { Ok(format.guaranteed_format_features(self.features)) } @@ -3341,7 +3360,7 @@ impl Device { .unwrap() .wait(fence, current_index, CLEANUP_WAIT_MS) } { - log::error!("failed to wait for the device: {:?}", error); + log::error!("failed to wait for the device: {error}"); } let mut life_tracker = self.lock_life(); let _ = life_tracker.triage_submissions( diff --git a/wgpu-core/src/global.rs b/wgpu-core/src/global.rs index 5de766f61f..e1c3d8c6d4 100644 --- a/wgpu-core/src/global.rs +++ b/wgpu-core/src/global.rs @@ -22,8 +22,6 @@ pub struct GlobalReport { pub metal: Option, #[cfg(all(feature = "dx12", windows))] pub dx12: Option, - #[cfg(all(feature = "dx11", windows))] - pub dx11: Option, #[cfg(feature = "gles")] pub gl: Option, } @@ -40,8 +38,6 @@ impl GlobalReport { Backend::Metal => self.metal.as_ref().unwrap(), #[cfg(all(feature = "dx12", windows))] Backend::Dx12 => self.dx12.as_ref().unwrap(), - #[cfg(all(feature = "dx11", windows))] - Backend::Dx11 => self.dx11.as_ref().unwrap(), #[cfg(feature = "gles")] Backend::Gl => self.gl.as_ref().unwrap(), _ => panic!("HubReport is not supported on this backend"), @@ -132,12 +128,6 @@ impl Global { } else { None }, - #[cfg(all(feature = "dx11", windows))] - dx11: if self.instance.dx11.is_some() { - Some(self.hubs.dx11.generate_report()) - } else { - None - }, #[cfg(feature = "gles")] gl: if self.instance.gl.is_some() { Some(self.hubs.gl.generate_report()) @@ -167,10 +157,6 @@ impl Drop for Global { { self.hubs.dx12.clear(&surfaces_locked, true); } - #[cfg(all(feature = "dx11", windows))] - { - self.hubs.dx11.clear(&surfaces_locked, true); - } #[cfg(feature = "gles")] { self.hubs.gl.clear(&surfaces_locked, true); diff --git a/wgpu-core/src/hal_api.rs b/wgpu-core/src/hal_api.rs index cb3e25b09e..a19b3c4bb7 100644 --- a/wgpu-core/src/hal_api.rs +++ b/wgpu-core/src/hal_api.rs @@ -94,27 +94,6 @@ impl HalApi for hal::api::Dx12 { } } -#[cfg(all(feature = "dx11", windows))] -impl HalApi for hal::api::Dx11 { - const VARIANT: Backend = Backend::Dx11; - fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { - Instance { - name: name.to_owned(), - dx11: Some(hal_instance), - ..Default::default() - } - } - fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> { - instance.dx11.as_ref() - } - fn hub(global: &Global) -> &Hub { - &global.hubs.dx11 - } - fn get_surface(surface: &Surface) -> Option<&HalSurface> { - surface.raw.downcast_ref() - } -} - #[cfg(feature = "gles")] impl HalApi for hal::api::Gles { const VARIANT: Backend = Backend::Gl; diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 6cb9ee64d1..a2f89f92df 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -308,15 +308,12 @@ pub struct Hubs { pub(crate) metal: Hub, #[cfg(all(feature = "dx12", windows))] pub(crate) dx12: Hub, - #[cfg(all(feature = "dx11", windows))] - pub(crate) dx11: Hub, #[cfg(feature = "gles")] pub(crate) gl: Hub, #[cfg(all( not(all(feature = "vulkan", not(target_arch = "wasm32"))), not(all(feature = "metal", any(target_os = "macos", target_os = "ios"))), not(all(feature = "dx12", windows)), - not(all(feature = "dx11", windows)), not(feature = "gles"), ))] pub(crate) empty: Hub, @@ -331,15 +328,12 @@ impl Hubs { metal: Hub::new(factory), #[cfg(all(feature = "dx12", windows))] dx12: Hub::new(factory), - #[cfg(all(feature = "dx11", windows))] - dx11: Hub::new(factory), #[cfg(feature = "gles")] gl: Hub::new(factory), #[cfg(all( not(all(feature = "vulkan", not(target_arch = "wasm32"))), not(all(feature = "metal", any(target_os = "macos", target_os = "ios"))), not(all(feature = "dx12", windows)), - not(all(feature = "dx11", windows)), not(feature = "gles"), ))] empty: Hub::new(factory), diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index 9daa0ef56c..1782172c2a 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -131,8 +131,7 @@ where 1 => Backend::Vulkan, 2 => Backend::Metal, 3 => Backend::Dx12, - 4 => Backend::Dx11, - 5 => Backend::Gl, + 4 => Backend::Gl, _ => unreachable!(), } } @@ -156,13 +155,12 @@ where fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { let (index, epoch, backend) = self.unzip(); let backend = match backend { + Backend::Empty => "_", Backend::Vulkan => "vk", Backend::Metal => "mtl", Backend::Dx12 => "d3d12", - Backend::Dx11 => "d3d11", Backend::Gl => "gl", Backend::BrowserWebGpu => "webgpu", - Backend::Empty => "_", }; write!(formatter, "Id({index},{epoch},{backend})")?; Ok(()) @@ -280,7 +278,6 @@ fn test_id_backend() { Backend::Vulkan, Backend::Metal, Backend::Dx12, - Backend::Dx11, Backend::Gl, ] { let id: Id<()> = Id::zip(1, 0, b); @@ -300,7 +297,6 @@ fn test_id() { Backend::Vulkan, Backend::Metal, Backend::Dx12, - Backend::Dx11, Backend::Gl, ]; for &i in &indexes { diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index b8340cd659..7a12d98a6d 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -68,8 +68,6 @@ pub struct Instance { pub metal: Option>, #[cfg(all(feature = "dx12", windows))] pub dx12: Option>, - #[cfg(all(feature = "dx11", windows))] - pub dx11: Option>, #[cfg(feature = "gles")] pub gl: Option>, pub flags: wgt::InstanceFlags, @@ -113,8 +111,6 @@ impl Instance { metal: init(hal::api::Metal, &instance_desc), #[cfg(all(feature = "dx12", windows))] dx12: init(hal::api::Dx12, &instance_desc), - #[cfg(all(feature = "dx11", windows))] - dx11: init(hal::api::Dx11, &instance_desc), #[cfg(feature = "gles")] gl: init(hal::api::Gles, &instance_desc), flags: instance_desc.flags, @@ -144,8 +140,6 @@ impl Instance { Backend::Metal => destroy(hal::api::Metal, &self.metal, surface.raw), #[cfg(all(feature = "dx12", windows))] Backend::Dx12 => destroy(hal::api::Dx12, &self.dx12, surface.raw), - #[cfg(all(feature = "dx11", windows))] - Backend::Dx11 => destroy(hal::api::Dx11, &self.dx11, surface.raw), #[cfg(feature = "gles")] Backend::Gl => destroy(hal::api::Gles, &self.gl, surface.raw), _ => unreachable!(), @@ -531,13 +525,6 @@ impl Global { display_handle, window_handle, ); - #[cfg(all(feature = "dx11", windows))] - init::( - &mut hal_surface, - &self.instance.dx11, - display_handle, - window_handle, - ); #[cfg(feature = "gles")] init::( &mut hal_surface, @@ -787,8 +774,6 @@ impl Global { unconfigure::<_, hal::api::Metal>(self, &surface.raw, &present); #[cfg(all(feature = "dx12", windows))] unconfigure::<_, hal::api::Dx12>(self, &surface.raw, &present); - #[cfg(all(feature = "dx11", windows))] - unconfigure::<_, hal::api::Dx11>(self, &surface.raw, &present); #[cfg(feature = "gles")] unconfigure::<_, hal::api::Gles>(self, &surface.raw, &present); } @@ -849,8 +834,6 @@ impl Global { ); #[cfg(all(feature = "dx12", windows))] self.enumerate(hal::api::Dx12, &self.instance.dx12, &inputs, &mut adapters); - #[cfg(all(feature = "dx11", windows))] - self.enumerate(hal::api::Dx11, &self.instance.dx11, &inputs, &mut adapters); #[cfg(feature = "gles")] self.enumerate(hal::api::Gles, &self.instance.gl, &inputs, &mut adapters); @@ -960,15 +943,6 @@ impl Global { desc.force_fallback_adapter, &mut device_types, ); - #[cfg(all(feature = "dx11", windows))] - let (id_dx11, adapters_dx11) = gather( - hal::api::Dx11, - self.instance.dx11.as_ref(), - &inputs, - compatible_surface, - desc.force_fallback_adapter, - &mut device_types, - ); #[cfg(feature = "gles")] let (id_gl, adapters_gl) = gather( hal::api::Gles, @@ -1042,10 +1016,6 @@ impl Global { if let Some(id) = self.select(&mut selected, id_dx12, adapters_dx12) { return Ok(id); } - #[cfg(all(feature = "dx11", windows))] - if let Some(id) = self.select(&mut selected, id_dx11, adapters_dx11) { - return Ok(id); - } #[cfg(feature = "gles")] if let Some(id) = self.select(&mut selected, id_gl, adapters_gl) { return Ok(id); @@ -1076,8 +1046,6 @@ impl Global { Backend::Metal => fid.assign(Adapter::new(hal_adapter)), #[cfg(all(feature = "dx12", windows))] Backend::Dx12 => fid.assign(Adapter::new(hal_adapter)), - #[cfg(all(feature = "dx11", windows))] - Backend::Dx11 => fid.assign(Adapter::new(hal_adapter)), #[cfg(feature = "gles")] Backend::Gl => fid.assign(Adapter::new(hal_adapter)), _ => unreachable!(), @@ -1283,7 +1251,6 @@ impl Global { /// Names: /// - vulkan = "vulkan" or "vk" /// - dx12 = "dx12" or "d3d12" -/// - dx11 = "dx11" or "d3d11" /// - metal = "metal" or "mtl" /// - gles = "opengl" or "gles" or "gl" /// - webgpu = "webgpu" @@ -1293,7 +1260,6 @@ pub fn parse_backends_from_comma_list(string: &str) -> Backends { backends |= match backend.trim() { "vulkan" | "vk" => Backends::VULKAN, "dx12" | "d3d12" => Backends::DX12, - "dx11" | "d3d11" => Backends::DX11, "metal" | "mtl" => Backends::METAL, "opengl" | "gles" | "gl" => Backends::GL, "webgpu" => Backends::BROWSER_WEBGPU, diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 944d7eff46..4d5646d2b9 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -9,7 +9,6 @@ not(all(feature = "vulkan", not(target_arch = "wasm32"))), not(all(feature = "metal", any(target_os = "macos", target_os = "ios"))), not(all(feature = "dx12", windows)), - not(all(feature = "dx11", windows)), not(feature = "gles"), ), allow(unused, clippy::let_and_return) @@ -217,7 +216,6 @@ macro_rules! define_backend_caller { define_backend_caller! { gfx_if_vulkan, gfx_if_vulkan_hidden, "vulkan" if all(feature = "vulkan", not(target_arch = "wasm32")) } define_backend_caller! { gfx_if_metal, gfx_if_metal_hidden, "metal" if all(feature = "metal", any(target_os = "macos", target_os = "ios")) } define_backend_caller! { gfx_if_dx12, gfx_if_dx12_hidden, "dx12" if all(feature = "dx12", windows) } -define_backend_caller! { gfx_if_dx11, gfx_if_dx11_hidden, "dx11" if all(feature = "dx11", windows) } define_backend_caller! { gfx_if_gles, gfx_if_gles_hidden, "gles" if feature = "gles" } /// Dispatch on an [`Id`]'s backend to a backend-generic method. @@ -272,7 +270,6 @@ macro_rules! gfx_select { wgt::Backend::Vulkan => $crate::gfx_if_vulkan!($global.$method::<$crate::api::Vulkan>( $($param),* )), wgt::Backend::Metal => $crate::gfx_if_metal!($global.$method::<$crate::api::Metal>( $($param),* )), wgt::Backend::Dx12 => $crate::gfx_if_dx12!($global.$method::<$crate::api::Dx12>( $($param),* )), - wgt::Backend::Dx11 => $crate::gfx_if_dx11!($global.$method::<$crate::api::Dx11>( $($param),* )), wgt::Backend::Gl => $crate::gfx_if_gles!($global.$method::<$crate::api::Gles>( $($param),+ )), other => panic!("Unexpected backend {:?}", other), } diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 551b495954..5ca8445e25 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -18,9 +18,9 @@ rust-version = "1.65" [package.metadata.docs.rs] # Ideally we would enable all the features. # -# However the metal features fails to be documented because the docs.rs runner cross compiling under +# However, the metal features fail to be documented because the docs.rs runner cross-compiling under # x86_64-unknown-linux-gnu and metal-rs cannot compile in that environment at the moment. The same applies -# with the dx11 and dx12 features. +# for the dx12 feature. features = ["vulkan", "gles", "renderdoc"] rustdoc-args = ["--cfg", "docsrs"] targets = [ @@ -44,17 +44,6 @@ vulkan = [ "smallvec", ] gles = ["naga/glsl-out", "glow", "glutin_wgl_sys", "khronos-egl", "libloading"] -dx11 = [ - "naga/hlsl-out", - "d3d12", - "libloading", - "winapi/d3d11", - "winapi/std", - "winapi/d3d11_1", - "winapi/d3d11_2", - "winapi/d3d11sdklayers", - "winapi/dxgi1_6", -] dx12 = [ "naga/hlsl-out", "d3d12", diff --git a/wgpu-hal/README.md b/wgpu-hal/README.md index 0ab7a0283a..588baa3cf5 100644 --- a/wgpu-hal/README.md +++ b/wgpu-hal/README.md @@ -15,7 +15,7 @@ such as running out-of-memory, or losing the device. For the counter-example, there is no error for mapping a buffer that's not mappable. As the buffer creator, the user should already know if they can map it. -The API accept iterators in order to avoid forcing the user to store data in particular containers. The implementation doesn't guarantee that any of the iterators are drained, unless stated otherwise by the function documentation. +The API accepts iterators in order to avoid forcing the user to store data in particular containers. The implementation doesn't guarantee that any of the iterators are drained, unless stated otherwise by the function documentation. For this reason, we recommend that iterators don't do any mutating work. # Debugging diff --git a/wgpu-hal/src/auxil/mod.rs b/wgpu-hal/src/auxil/mod.rs index f0aa6a4a89..5e45c1f2b6 100644 --- a/wgpu-hal/src/auxil/mod.rs +++ b/wgpu-hal/src/auxil/mod.rs @@ -1,4 +1,4 @@ -#[cfg(all(any(feature = "dx11", feature = "dx12"), windows))] +#[cfg(all(feature = "dx12", windows))] pub(super) mod dxgi; #[cfg(all(not(target_arch = "wasm32"), feature = "renderdoc"))] diff --git a/wgpu-hal/src/dx11/adapter.rs b/wgpu-hal/src/dx11/adapter.rs deleted file mode 100644 index 41b4b4e573..0000000000 --- a/wgpu-hal/src/dx11/adapter.rs +++ /dev/null @@ -1,299 +0,0 @@ -use std::num::NonZeroU64; - -use winapi::um::{d3d11, d3dcommon}; - -impl crate::Adapter for super::Adapter { - unsafe fn open( - &self, - features: wgt::Features, - limits: &wgt::Limits, - ) -> Result, crate::DeviceError> { - todo!() - } - - unsafe fn texture_format_capabilities( - &self, - format: wgt::TextureFormat, - ) -> crate::TextureFormatCapabilities { - todo!() - } - - unsafe fn surface_capabilities( - &self, - surface: &super::Surface, - ) -> Option { - todo!() - } - - unsafe fn get_presentation_timestamp(&self) -> wgt::PresentationTimestamp { - todo!() - } -} - -impl super::Adapter { - pub(super) fn expose( - instance: &super::library::D3D11Lib, - adapter: d3d12::DxgiAdapter, - ) -> Option> { - use d3dcommon::{ - D3D_FEATURE_LEVEL_10_0 as FL10_0, D3D_FEATURE_LEVEL_10_1 as FL10_1, - D3D_FEATURE_LEVEL_11_0 as FL11_0, D3D_FEATURE_LEVEL_11_1 as FL11_1, - D3D_FEATURE_LEVEL_9_1 as FL9_1, D3D_FEATURE_LEVEL_9_2 as FL9_2, - D3D_FEATURE_LEVEL_9_3 as FL9_3, - }; - - let (device, feature_level) = instance.create_device(adapter)?; - - // - // Query Features from d3d11 - // - - let d3d9_features = unsafe { - device.check_feature_support::( - d3d11::D3D11_FEATURE_D3D9_OPTIONS1, - ) - }; - - let d3d10_features = unsafe { - device.check_feature_support::( - d3d11::D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, - ) - }; - - let d3d11_features = unsafe { - device.check_feature_support::( - d3d11::D3D11_FEATURE_D3D11_OPTIONS, - ) - }; - - let d3d11_features1 = unsafe { - device.check_feature_support::( - d3d11::D3D11_FEATURE_D3D11_OPTIONS1, - ) - }; - - let d3d11_features2 = unsafe { - device.check_feature_support::( - d3d11::D3D11_FEATURE_D3D11_OPTIONS2, - ) - }; - - let d3d11_features3 = unsafe { - device.check_feature_support::( - d3d11::D3D11_FEATURE_D3D11_OPTIONS3, - ) - }; - - // - // Fill out features and downlevel features - // - // TODO(cwfitzgerald): Needed downlevel features: 3D dispatch - - let mut features = wgt::Features::DEPTH_CLIP_CONTROL - | wgt::Features::PUSH_CONSTANTS - | wgt::Features::POLYGON_MODE_LINE - | wgt::Features::CLEAR_TEXTURE - | wgt::Features::TEXTURE_FORMAT_16BIT_NORM - | wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO - | wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER; - let mut downlevel = wgt::DownlevelFlags::BASE_VERTEX - | wgt::DownlevelFlags::READ_ONLY_DEPTH_STENCIL - | wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER - | wgt::DownlevelFlags::UNRESTRICTED_EXTERNAL_TEXTURE_COPIES; - - // Features from queries - downlevel.set( - wgt::DownlevelFlags::NON_POWER_OF_TWO_MIPMAPPED_TEXTURES, - d3d9_features.FullNonPow2TextureSupported == 1, - ); - downlevel.set( - wgt::DownlevelFlags::COMPUTE_SHADERS, - d3d10_features.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x == 1, - ); - - // Features from feature level - if feature_level >= FL9_2 { - downlevel |= wgt::DownlevelFlags::INDEPENDENT_BLEND; - // formally FL9_1 supports aniso 2, but we don't support that level of distinction - downlevel |= wgt::DownlevelFlags::ANISOTROPIC_FILTERING; - // this is actually the first FL that supports u32 at all - downlevel |= wgt::DownlevelFlags::FULL_DRAW_INDEX_UINT32; - } - - if feature_level >= FL9_3 { - downlevel |= wgt::DownlevelFlags::COMPARISON_SAMPLERS; - } - - if feature_level >= FL10_0 { - downlevel |= wgt::DownlevelFlags::FRAGMENT_STORAGE; - downlevel |= wgt::DownlevelFlags::FRAGMENT_WRITABLE_STORAGE; - downlevel |= wgt::DownlevelFlags::DEPTH_BIAS_CLAMP; - downlevel |= wgt::DownlevelFlags::VERTEX_STORAGE; - features |= wgt::Features::DEPTH_CLIP_CONTROL; - features |= wgt::Features::TIMESTAMP_QUERY; - features |= wgt::Features::PIPELINE_STATISTICS_QUERY; - features |= wgt::Features::SHADER_PRIMITIVE_INDEX; - features |= wgt::Features::DEPTH32FLOAT_STENCIL8; - features |= wgt::Features::RG11B10UFLOAT_RENDERABLE; - } - - if feature_level >= FL10_1 { - downlevel |= wgt::DownlevelFlags::CUBE_ARRAY_TEXTURES; - downlevel |= wgt::DownlevelFlags::MULTISAMPLED_SHADING; - } - - if feature_level >= FL11_0 { - downlevel |= wgt::DownlevelFlags::INDIRECT_EXECUTION; - downlevel |= wgt::DownlevelFlags::WEBGPU_TEXTURE_FORMAT_SUPPORT; - features |= wgt::Features::TEXTURE_COMPRESSION_BC; - } - - if feature_level >= FL11_1 { - features |= wgt::Features::VERTEX_WRITABLE_STORAGE; - } - - // bgra8unorm-storage is never supported on dx11 according to: - // https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware#dxgi_format_b8g8r8a8_unormfcs-87 - - // - // Fill out limits and alignments - // - - let max_texture_dimension_2d = match feature_level { - FL9_1 | FL9_2 => 2048, - FL9_3 => 4096, - FL10_0 | FL10_1 => 8192, - _ => d3d11::D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION, - }; - - let max_texture_dimension_3d = match feature_level { - FL9_1..=FL9_3 => 256, - _ => d3d11::D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION, - }; - let max_vertex_buffers = match feature_level { - FL9_1..=FL9_3 => 16, - _ => 32, - } - .min(crate::MAX_VERTEX_BUFFERS as u32); - let max_compute_workgroup_storage_size = match feature_level { - FL9_1..=FL9_3 => 0, - FL10_0 | FL10_1 => 4096 * 4, // This doesn't have an equiv SM4 constant :\ - _ => d3d11::D3D11_CS_TGSM_REGISTER_COUNT * 4, - }; - let max_workgroup_size_xy = match feature_level { - FL9_1..=FL9_3 => 0, - FL10_0 | FL10_1 => d3d11::D3D11_CS_4_X_THREAD_GROUP_MAX_X, - _ => d3d11::D3D11_CS_THREAD_GROUP_MAX_X, - }; - let max_workgroup_size_z = match feature_level { - FL9_1..=FL9_3 => 0, - FL10_0 | FL10_1 => 1, - _ => d3d11::D3D11_CS_THREAD_GROUP_MAX_Z, - }; - // let max_workgroup_count_z = match feature_level { - // FL9_1..=FL9_3 => 0, - // FL10_0 | FL10_1 => 1, - // _ => d3d11::D3D11_CS_THREAD_GROUP_MAX_Z, - // }; - - let max_sampled_textures = d3d11::D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT; - let max_samplers = d3d11::D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; - let max_constant_buffers = d3d11::D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1; - let max_uavs = if device.as_device1().is_some() { - d3d11::D3D11_1_UAV_SLOT_COUNT - } else { - d3d11::D3D11_PS_CS_UAV_REGISTER_COUNT - }; - let max_output_registers = d3d11::D3D11_VS_OUTPUT_REGISTER_COMPONENTS; - let max_compute_invocations_per_workgroup = - d3d11::D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP; - let max_compute_workgroups_per_dimension = - d3d11::D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION; - - let limits = wgt::Limits { - max_texture_dimension_1d: max_texture_dimension_2d, - max_texture_dimension_2d, - max_texture_dimension_3d, - max_texture_array_layers: max_texture_dimension_3d, - max_bind_groups: u32::MAX, - max_bindings_per_bind_group: 65535, - max_dynamic_uniform_buffers_per_pipeline_layout: max_constant_buffers, - max_dynamic_storage_buffers_per_pipeline_layout: 0, - max_sampled_textures_per_shader_stage: max_sampled_textures, - max_samplers_per_shader_stage: max_samplers, - max_storage_buffers_per_shader_stage: max_uavs, - max_storage_textures_per_shader_stage: max_uavs, - max_uniform_buffers_per_shader_stage: max_constant_buffers, - max_uniform_buffer_binding_size: 1 << 16, - max_storage_buffer_binding_size: u32::MAX, - max_vertex_buffers, - max_vertex_attributes: max_vertex_buffers, - max_vertex_buffer_array_stride: u32::MAX, - max_push_constant_size: 1 << 16, - min_uniform_buffer_offset_alignment: 256, - min_storage_buffer_offset_alignment: 1, - max_inter_stage_shader_components: max_output_registers, - max_compute_workgroup_storage_size, - max_compute_invocations_per_workgroup, - max_compute_workgroup_size_x: max_workgroup_size_xy, - max_compute_workgroup_size_y: max_workgroup_size_xy, - max_compute_workgroup_size_z: max_workgroup_size_z, - max_compute_workgroups_per_dimension, - // D3D11_BUFFER_DESC represents the buffer size as a 32 bit int. - max_buffer_size: u32::MAX as u64, - max_non_sampler_bindings: u32::MAX, - }; - - // - // Other capabilities - // - - let shader_model = match feature_level { - FL9_1..=FL9_3 => wgt::ShaderModel::Sm2, - FL10_0 | FL10_1 => wgt::ShaderModel::Sm4, - _ => wgt::ShaderModel::Sm5, - }; - - let device_info = wgt::AdapterInfo { - name: String::new(), - vendor: 0, - device: 0, - device_type: match d3d11_features2.UnifiedMemoryArchitecture { - 0 => wgt::DeviceType::DiscreteGpu, - 1 => wgt::DeviceType::IntegratedGpu, - _ => unreachable!(), - }, - driver: String::new(), - driver_info: String::new(), - backend: wgt::Backend::Dx11, - }; - - // - // Build up the structs - // - - let api_adapter = super::Adapter { device }; - - let alignments = crate::Alignments { - buffer_copy_offset: NonZeroU64::new(1).unwrap(), // todo - buffer_copy_pitch: NonZeroU64::new(1).unwrap(), // todo - }; - - let capabilities = crate::Capabilities { - limits, - alignments, - downlevel: wgt::DownlevelCapabilities { - flags: downlevel, - limits: wgt::DownlevelLimits {}, - shader_model, - }, - }; - - Some(crate::ExposedAdapter { - adapter: api_adapter, - info: device_info, - features, - capabilities, - }) - } -} diff --git a/wgpu-hal/src/dx11/command.rs b/wgpu-hal/src/dx11/command.rs deleted file mode 100644 index b9296149ea..0000000000 --- a/wgpu-hal/src/dx11/command.rs +++ /dev/null @@ -1,289 +0,0 @@ -impl crate::CommandEncoder for super::CommandEncoder { - unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> { - todo!() - } - - unsafe fn discard_encoding(&mut self) { - todo!() - } - - unsafe fn end_encoding(&mut self) -> Result { - todo!() - } - - unsafe fn reset_all(&mut self, command_buffers: I) - where - I: Iterator, - { - todo!() - } - - unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) - where - T: Iterator>, - { - todo!() - } - - unsafe fn transition_textures<'a, T>(&mut self, barriers: T) - where - T: Iterator>, - { - todo!() - } - - unsafe fn clear_buffer(&mut self, buffer: &super::Buffer, range: crate::MemoryRange) { - todo!() - } - - unsafe fn copy_buffer_to_buffer( - &mut self, - src: &super::Buffer, - dst: &super::Buffer, - regions: T, - ) where - T: Iterator, - { - todo!() - } - - unsafe fn copy_texture_to_texture( - &mut self, - src: &super::Texture, - src_usage: crate::TextureUses, - dst: &super::Texture, - regions: T, - ) where - T: Iterator, - { - todo!() - } - - unsafe fn copy_buffer_to_texture( - &mut self, - src: &super::Buffer, - dst: &super::Texture, - regions: T, - ) where - T: Iterator, - { - todo!() - } - - unsafe fn copy_texture_to_buffer( - &mut self, - src: &super::Texture, - src_usage: crate::TextureUses, - dst: &super::Buffer, - regions: T, - ) where - T: Iterator, - { - todo!() - } - - unsafe fn set_bind_group( - &mut self, - layout: &super::PipelineLayout, - index: u32, - group: &super::BindGroup, - dynamic_offsets: &[wgt::DynamicOffset], - ) { - todo!() - } - - unsafe fn set_push_constants( - &mut self, - layout: &super::PipelineLayout, - stages: wgt::ShaderStages, - offset_bytes: u32, - data: &[u32], - ) { - todo!() - } - - unsafe fn insert_debug_marker(&mut self, label: &str) { - todo!() - } - - unsafe fn begin_debug_marker(&mut self, group_label: &str) { - todo!() - } - - unsafe fn end_debug_marker(&mut self) { - todo!() - } - - unsafe fn begin_query(&mut self, set: &super::QuerySet, index: u32) { - todo!() - } - - unsafe fn end_query(&mut self, set: &super::QuerySet, index: u32) { - todo!() - } - - unsafe fn write_timestamp(&mut self, set: &super::QuerySet, index: u32) { - todo!() - } - - unsafe fn reset_queries(&mut self, set: &super::QuerySet, range: std::ops::Range) { - todo!() - } - - unsafe fn copy_query_results( - &mut self, - set: &super::QuerySet, - range: std::ops::Range, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - stride: wgt::BufferSize, - ) { - todo!() - } - - unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) { - todo!() - } - - unsafe fn end_render_pass(&mut self) { - todo!() - } - - unsafe fn set_render_pipeline(&mut self, pipeline: &super::RenderPipeline) { - todo!() - } - - unsafe fn set_index_buffer<'a>( - &mut self, - binding: crate::BufferBinding<'a, super::Api>, - format: wgt::IndexFormat, - ) { - todo!() - } - - unsafe fn set_vertex_buffer<'a>( - &mut self, - index: u32, - binding: crate::BufferBinding<'a, super::Api>, - ) { - todo!() - } - - unsafe fn set_viewport(&mut self, rect: &crate::Rect, depth_range: std::ops::Range) { - todo!() - } - - unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect) { - todo!() - } - - unsafe fn set_stencil_reference(&mut self, value: u32) { - todo!() - } - - unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) { - todo!() - } - - unsafe fn draw( - &mut self, - first_vertex: u32, - vertex_count: u32, - first_instance: u32, - instance_count: u32, - ) { - todo!() - } - - unsafe fn draw_indexed( - &mut self, - first_index: u32, - index_count: u32, - base_vertex: i32, - first_instance: u32, - instance_count: u32, - ) { - todo!() - } - - unsafe fn draw_indirect( - &mut self, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - draw_count: u32, - ) { - todo!() - } - - unsafe fn draw_indexed_indirect( - &mut self, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - draw_count: u32, - ) { - todo!() - } - - unsafe fn draw_indirect_count( - &mut self, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - count_buffer: &super::Buffer, - count_offset: wgt::BufferAddress, - max_count: u32, - ) { - todo!() - } - - unsafe fn draw_indexed_indirect_count( - &mut self, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - count_buffer: &super::Buffer, - count_offset: wgt::BufferAddress, - max_count: u32, - ) { - todo!() - } - - unsafe fn begin_compute_pass<'a>( - &mut self, - desc: &crate::ComputePassDescriptor<'a, super::Api>, - ) { - todo!() - } - - unsafe fn end_compute_pass(&mut self) { - todo!() - } - - unsafe fn set_compute_pipeline(&mut self, pipeline: &super::ComputePipeline) { - todo!() - } - - unsafe fn dispatch(&mut self, count: [u32; 3]) { - todo!() - } - - unsafe fn dispatch_indirect(&mut self, buffer: &super::Buffer, offset: wgt::BufferAddress) { - todo!() - } - - unsafe fn build_acceleration_structures<'a, T>( - &mut self, - _descriptor_count: u32, - _descriptors: T, - ) where - super::Api: 'a, - T: IntoIterator>, - { - unimplemented!() - } - - unsafe fn place_acceleration_structure_barrier( - &mut self, - _barriers: crate::AccelerationStructureBarrier, - ) { - unimplemented!() - } -} diff --git a/wgpu-hal/src/dx11/device.rs b/wgpu-hal/src/dx11/device.rs deleted file mode 100644 index 769a417349..0000000000 --- a/wgpu-hal/src/dx11/device.rs +++ /dev/null @@ -1,267 +0,0 @@ -use std::{ffi::c_void, mem}; - -use winapi::um::d3d11; - -use crate::auxil::dxgi::result::HResult; - -impl crate::Device for super::Device { - unsafe fn exit(self, queue: super::Queue) { - todo!() - } - - unsafe fn create_buffer( - &self, - desc: &crate::BufferDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_buffer(&self, buffer: super::Buffer) { - todo!() - } - - unsafe fn map_buffer( - &self, - buffer: &super::Buffer, - range: crate::MemoryRange, - ) -> Result { - todo!() - } - - unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> { - todo!() - } - - unsafe fn flush_mapped_ranges(&self, buffer: &super::Buffer, ranges: I) - where - I: Iterator, - { - todo!() - } - - unsafe fn invalidate_mapped_ranges(&self, buffer: &super::Buffer, ranges: I) - where - I: Iterator, - { - todo!() - } - - unsafe fn create_texture( - &self, - desc: &crate::TextureDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_texture(&self, texture: super::Texture) { - todo!() - } - - unsafe fn create_texture_view( - &self, - texture: &super::Texture, - desc: &crate::TextureViewDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_texture_view(&self, view: super::TextureView) { - todo!() - } - - unsafe fn create_sampler( - &self, - desc: &crate::SamplerDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_sampler(&self, sampler: super::Sampler) { - todo!() - } - - unsafe fn create_command_encoder( - &self, - desc: &crate::CommandEncoderDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_command_encoder(&self, pool: super::CommandEncoder) { - todo!() - } - - unsafe fn create_bind_group_layout( - &self, - desc: &crate::BindGroupLayoutDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_bind_group_layout(&self, bg_layout: super::BindGroupLayout) { - todo!() - } - - unsafe fn create_pipeline_layout( - &self, - desc: &crate::PipelineLayoutDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_pipeline_layout(&self, pipeline_layout: super::PipelineLayout) { - todo!() - } - - unsafe fn create_bind_group( - &self, - desc: &crate::BindGroupDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_bind_group(&self, group: super::BindGroup) { - todo!() - } - - unsafe fn create_shader_module( - &self, - desc: &crate::ShaderModuleDescriptor, - shader: crate::ShaderInput, - ) -> Result { - todo!() - } - - unsafe fn destroy_shader_module(&self, module: super::ShaderModule) { - todo!() - } - - unsafe fn create_render_pipeline( - &self, - desc: &crate::RenderPipelineDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_render_pipeline(&self, pipeline: super::RenderPipeline) { - todo!() - } - - unsafe fn create_compute_pipeline( - &self, - desc: &crate::ComputePipelineDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_compute_pipeline(&self, pipeline: super::ComputePipeline) { - todo!() - } - - unsafe fn create_query_set( - &self, - desc: &wgt::QuerySetDescriptor, - ) -> Result { - todo!() - } - - unsafe fn destroy_query_set(&self, set: super::QuerySet) { - todo!() - } - - unsafe fn create_fence(&self) -> Result { - todo!() - } - - unsafe fn destroy_fence(&self, fence: super::Fence) { - todo!() - } - - unsafe fn get_fence_value( - &self, - fence: &super::Fence, - ) -> Result { - todo!() - } - - unsafe fn wait( - &self, - fence: &super::Fence, - value: crate::FenceValue, - timeout_ms: u32, - ) -> Result { - todo!() - } - - unsafe fn start_capture(&self) -> bool { - todo!() - } - - unsafe fn stop_capture(&self) { - todo!() - } - - unsafe fn create_acceleration_structure( - &self, - desc: &crate::AccelerationStructureDescriptor, - ) -> Result { - unimplemented!() - } - unsafe fn get_acceleration_structure_build_sizes<'a>( - &self, - _desc: &crate::GetAccelerationStructureBuildSizesDescriptor<'a, super::Api>, - ) -> crate::AccelerationStructureBuildSizes { - unimplemented!() - } - unsafe fn get_acceleration_structure_device_address( - &self, - acceleration_structure: &super::AccelerationStructure, - ) -> wgt::BufferAddress { - unimplemented!() - } - unsafe fn destroy_acceleration_structure( - &self, - acceleration_structure: super::AccelerationStructure, - ) { - unimplemented!() - } -} - -impl crate::Queue for super::Queue { - unsafe fn submit( - &self, - command_buffers: &[&super::CommandBuffer], - signal_fence: Option<(&mut super::Fence, crate::FenceValue)>, - ) -> Result<(), crate::DeviceError> { - todo!() - } - - unsafe fn present( - &self, - surface: &super::Surface, - texture: super::SurfaceTexture, - ) -> Result<(), crate::SurfaceError> { - todo!() - } - - unsafe fn get_timestamp_period(&self) -> f32 { - todo!() - } -} - -impl super::D3D11Device { - #[allow(trivial_casts)] // come on - pub unsafe fn check_feature_support(&self, feature: d3d11::D3D11_FEATURE) -> T { - unsafe { - let mut value = mem::zeroed::(); - let ret = self.CheckFeatureSupport( - feature, - &mut value as *mut T as *mut c_void, - mem::size_of::() as u32, - ); - assert_eq!(ret.into_result(), Ok(())); - - value - } - } -} diff --git a/wgpu-hal/src/dx11/instance.rs b/wgpu-hal/src/dx11/instance.rs deleted file mode 100644 index 7df96ca6bd..0000000000 --- a/wgpu-hal/src/dx11/instance.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::auxil; - -impl crate::Instance for super::Instance { - unsafe fn init(desc: &crate::InstanceDescriptor) -> Result { - profiling::scope!("Init DX11 Backend"); - - let enable_dx11 = match std::env::var("WGPU_UNSTABLE_DX11_BACKEND") { - Ok(string) => string == "1" || string == "true", - Err(_) => false, - }; - - if !enable_dx11 { - return Err(crate::InstanceError::new(String::from( - "DX11 support is unstable; set WGPU_UNSTABLE_DX11_BACKEND=1 to enable anyway", - ))); - } - - let lib_d3d11 = super::library::D3D11Lib::new() - .ok_or_else(|| crate::InstanceError::new(String::from("failed to load d3d11.dll")))?; - - let (lib_dxgi, factory) = auxil::dxgi::factory::create_factory( - auxil::dxgi::factory::DxgiFactoryType::Factory1, - desc.flags, - )?; - - Ok(super::Instance { - lib_d3d11, - lib_dxgi, - factory, - }) - } - - unsafe fn create_surface( - &self, - display_handle: raw_window_handle::RawDisplayHandle, - window_handle: raw_window_handle::RawWindowHandle, - ) -> Result { - todo!() - } - - unsafe fn destroy_surface(&self, surface: super::Surface) { - todo!() - } - - unsafe fn enumerate_adapters(&self) -> Vec> { - let adapters = auxil::dxgi::factory::enumerate_adapters(self.factory.clone()); - - adapters - .into_iter() - .filter_map(|adapter| super::Adapter::expose(&self.lib_d3d11, adapter)) - .collect() - } -} diff --git a/wgpu-hal/src/dx11/library.rs b/wgpu-hal/src/dx11/library.rs deleted file mode 100644 index 2b7b1b1c2a..0000000000 --- a/wgpu-hal/src/dx11/library.rs +++ /dev/null @@ -1,142 +0,0 @@ -use std::ptr; - -use winapi::{ - shared::{ - dxgi, - minwindef::{HMODULE, UINT}, - winerror, - }, - um::{d3d11, d3d11_1, d3d11_2, d3dcommon}, -}; - -use crate::auxil::dxgi::result::HResult; - -type D3D11CreateDeviceFun = unsafe extern "system" fn( - *mut dxgi::IDXGIAdapter, - d3dcommon::D3D_DRIVER_TYPE, - HMODULE, - UINT, - *const d3dcommon::D3D_FEATURE_LEVEL, - UINT, - UINT, - *mut *mut d3d11::ID3D11Device, - *mut d3dcommon::D3D_FEATURE_LEVEL, - *mut *mut d3d11::ID3D11DeviceContext, -) -> d3d12::HRESULT; - -pub(super) struct D3D11Lib { - // We use the os specific symbol to drop the lifetime parameter. - // - // SAFETY: we must ensure this outlives the Library. - d3d11_create_device: libloading::os::windows::Symbol, - - lib: libloading::Library, -} -impl D3D11Lib { - pub fn new() -> Option { - unsafe { - let lib = libloading::Library::new("d3d11.dll").ok()?; - - let d3d11_create_device = lib - .get::(b"D3D11CreateDevice") - .ok()? - .into_raw(); - - Some(Self { - lib, - d3d11_create_device, - }) - } - } - - pub fn create_device( - &self, - adapter: d3d12::DxgiAdapter, - ) -> Option<(super::D3D11Device, d3dcommon::D3D_FEATURE_LEVEL)> { - let feature_levels = [ - d3dcommon::D3D_FEATURE_LEVEL_11_1, - d3dcommon::D3D_FEATURE_LEVEL_11_0, - d3dcommon::D3D_FEATURE_LEVEL_10_1, - d3dcommon::D3D_FEATURE_LEVEL_10_0, - d3dcommon::D3D_FEATURE_LEVEL_9_3, - d3dcommon::D3D_FEATURE_LEVEL_9_2, - d3dcommon::D3D_FEATURE_LEVEL_9_1, - ]; - - let mut device = d3d12::ComPtr::::null(); - let mut feature_level: d3dcommon::D3D_FEATURE_LEVEL = 0; - - // We need to try this twice. If the first time fails due to E_INVALIDARG - // we are running on a machine without a D3D11.1 runtime, and need to - // retry without the feature level 11_1 feature level. - // - // Why they thought this was a good API, who knows. - - let mut hr = unsafe { - (self.d3d11_create_device)( - adapter.as_mut_ptr() as *mut _, - d3dcommon::D3D_DRIVER_TYPE_UNKNOWN, - ptr::null_mut(), // software implementation DLL??? - 0, // flags - feature_levels.as_ptr(), - feature_levels.len() as u32, - d3d11::D3D11_SDK_VERSION, - device.mut_self(), - &mut feature_level, - ptr::null_mut(), // device context - ) - }; - - // Try again without FL11_1 - if hr == winerror::E_INVALIDARG { - hr = unsafe { - (self.d3d11_create_device)( - adapter.as_mut_ptr() as *mut _, - d3dcommon::D3D_DRIVER_TYPE_UNKNOWN, - ptr::null_mut(), // software implementation DLL??? - 0, // flags - feature_levels[1..].as_ptr(), - feature_levels[1..].len() as u32, - d3d11::D3D11_SDK_VERSION, - device.mut_self(), - &mut feature_level, - ptr::null_mut(), // device context - ) - }; - } - - // Any errors here are real and we should complain about - if let Err(err) = hr.into_result() { - log::error!("Failed to make a D3D11 device: {}", err); - return None; - } - - // We always try to upcast in highest -> lowest order - - // Device -> Device2 - unsafe { - match device.cast::().into_result() { - Ok(device2) => { - return Some((super::D3D11Device::Device2(device2), feature_level)); - } - Err(hr) => { - log::warn!("Failed to cast device to ID3D11Device2: {}", hr) - } - } - } - - // Device -> Device1 - unsafe { - match device.cast::().into_result() { - Ok(device1) => { - return Some((super::D3D11Device::Device1(device1), feature_level)); - } - Err(hr) => { - log::warn!("Failed to cast device to ID3D11Device1: {}", hr) - } - } - } - - Some((super::D3D11Device::Device(device), feature_level)) - } -} diff --git a/wgpu-hal/src/dx11/mod.rs b/wgpu-hal/src/dx11/mod.rs deleted file mode 100644 index 1b715c45b4..0000000000 --- a/wgpu-hal/src/dx11/mod.rs +++ /dev/null @@ -1,143 +0,0 @@ -#![allow(dead_code)] -#![allow(unused_variables)] - -use winapi::um::{d3d11, d3d11_1, d3d11_2}; - -mod adapter; -mod command; -mod device; -mod instance; -mod library; - -#[derive(Clone, Debug)] -pub struct Api; - -impl crate::Api for Api { - type Instance = Instance; - type Surface = Surface; - type Adapter = Adapter; - type Device = Device; - - type Queue = Queue; - type CommandEncoder = CommandEncoder; - type CommandBuffer = CommandBuffer; - - type Buffer = Buffer; - type Texture = Texture; - type SurfaceTexture = SurfaceTexture; - type TextureView = TextureView; - type Sampler = Sampler; - type QuerySet = QuerySet; - type Fence = Fence; - - type BindGroupLayout = BindGroupLayout; - type BindGroup = BindGroup; - type PipelineLayout = PipelineLayout; - type ShaderModule = ShaderModule; - type RenderPipeline = RenderPipeline; - type ComputePipeline = ComputePipeline; - - type AccelerationStructure = AccelerationStructure; -} - -pub struct Instance { - lib_d3d11: library::D3D11Lib, - lib_dxgi: d3d12::DxgiLib, - factory: d3d12::DxgiFactory, -} - -unsafe impl Send for Instance {} -unsafe impl Sync for Instance {} - -pub struct Surface {} - -pub struct Adapter { - device: D3D11Device, -} - -unsafe impl Send for Adapter {} -unsafe impl Sync for Adapter {} - -d3d12::weak_com_inheritance_chain! { - #[derive(Debug, Clone, PartialEq)] - enum D3D11Device { - Device(d3d11::ID3D11Device), from_device, as_device, device; - Device1(d3d11_1::ID3D11Device1), from_device1, as_device1, unwrap_device1; - Device2(d3d11_2::ID3D11Device2), from_device2, as_device2, unwrap_device2; - } -} - -pub struct Device {} - -unsafe impl Send for Device {} -unsafe impl Sync for Device {} - -pub struct Queue {} - -#[derive(Debug)] -pub struct CommandEncoder {} - -#[derive(Debug)] -pub struct CommandBuffer {} - -#[derive(Debug)] -pub struct Buffer {} -#[derive(Debug)] -pub struct Texture {} -#[derive(Debug)] -pub struct SurfaceTexture {} - -impl std::borrow::Borrow for SurfaceTexture { - fn borrow(&self) -> &Texture { - todo!() - } -} - -#[derive(Debug)] -pub struct TextureView {} -#[derive(Debug)] -pub struct Sampler {} -#[derive(Debug)] -pub struct QuerySet {} -#[derive(Debug)] -pub struct Fence {} - -#[derive(Debug)] -pub struct BindGroupLayout {} -#[derive(Debug)] -pub struct BindGroup {} -#[derive(Debug)] -pub struct PipelineLayout {} -#[derive(Debug)] -pub struct ShaderModule {} -#[derive(Debug)] -pub struct AccelerationStructure {} -#[derive(Debug)] -pub struct RenderPipeline {} -#[derive(Debug)] -pub struct ComputePipeline {} - -impl crate::Surface for Surface { - unsafe fn configure( - &self, - device: &Device, - config: &crate::SurfaceConfiguration, - ) -> Result<(), crate::SurfaceError> { - todo!() - } - - unsafe fn unconfigure(&self, device: &Device) { - todo!() - } - - unsafe fn acquire_texture( - &self, - _timeout: Option, - ) -> Result>, crate::SurfaceError> { - todo!() - } - - unsafe fn discard_texture(&self, texture: SurfaceTexture) { - todo!() - } -} diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index c28e88c658..1db9b0877d 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -294,6 +294,9 @@ impl super::Adapter { bgra8unorm_storage_supported, ); + // float32-filterable should always be available on d3d12 + features.set(wgt::Features::FLOAT32_FILTERABLE, true); + // TODO: Determine if IPresentationManager is supported let presentation_timer = auxil::dxgi::time::PresentationTimer::new_dxgi(); diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 0e8285240a..8c35e452c1 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -549,6 +549,13 @@ impl super::Adapter { ); } + features.set( + wgt::Features::FLOAT32_FILTERABLE, + extensions.contains("GL_ARB_color_buffer_float") + || extensions.contains("GL_EXT_color_buffer_float") + || extensions.contains("OES_texture_float_linear"), + ); + // We *might* be able to emulate bgra8unorm-storage but currently don't attempt to. let mut private_caps = super::PrivateCapabilities::empty(); @@ -594,14 +601,6 @@ impl super::Adapter { super::PrivateCapabilities::COLOR_BUFFER_FLOAT, color_buffer_float, ); - private_caps.set( - super::PrivateCapabilities::TEXTURE_FLOAT_LINEAR, - if full_ver.is_some() { - color_buffer_float - } else { - extensions.contains("OES_texture_float_linear") - }, - ); private_caps.set(super::PrivateCapabilities::QUERY_BUFFERS, query_buffers); private_caps.set(super::PrivateCapabilities::QUERY_64BIT, full_ver.is_some()); private_caps.set( @@ -1022,8 +1021,7 @@ impl crate::Adapter for super::Adapter { | Tfc::MULTISAMPLE_RESOLVE, ); - let texture_float_linear = - private_caps_fn(super::PrivateCapabilities::TEXTURE_FLOAT_LINEAR, filterable); + let texture_float_linear = feature_fn(wgt::Features::FLOAT32_FILTERABLE, filterable); match format { Tf::R8Unorm => filterable_renderable, diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index 5f3c439792..fee08f201b 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -605,7 +605,7 @@ impl crate::CommandEncoder for super::CommandEncoder { if !cat.ops.contains(crate::AttachmentOps::LOAD) { let c = &cat.clear_value; self.cmd_buffer.commands.push( - match cat.target.view.format.sample_type(None).unwrap() { + match cat.target.view.format.sample_type(None, None).unwrap() { wgt::TextureSampleType::Float { .. } => C::ClearColorF { draw_buffer: i as u32, color: [c.r as f32, c.g as f32, c.b as f32, c.a as f32], diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 6993d6dc77..a48fe9dc75 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -746,7 +746,7 @@ impl crate::Device for super::Device { unsafe { gl.bind_texture(target, Some(raw)) }; //Note: this has to be done before defining the storage! - match desc.format.sample_type(None) { + match desc.format.sample_type(None, Some(self.shared.features)) { Some( wgt::TextureSampleType::Float { filterable: false } | wgt::TextureSampleType::Uint diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 52d369682c..f384507f59 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -187,8 +187,6 @@ bitflags::bitflags! { const COLOR_BUFFER_HALF_FLOAT = 1 << 8; /// Supports `f11/f10` and `f32` color buffers const COLOR_BUFFER_FLOAT = 1 << 9; - /// Supports linear flitering `f32` textures. - const TEXTURE_FLOAT_LINEAR = 1 << 10; /// Supports query buffer objects. const QUERY_BUFFERS = 1 << 11; /// Supports 64 bit queries via `glGetQueryObjectui64v` diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 311788e50d..1da760f50c 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -11,7 +11,7 @@ * General design direction is to follow the majority by the following weights: * - wgpu-core: 1.5 * - primary backends (Vulkan/Metal/DX12): 1.0 each - * - secondary backends (DX11/GLES): 0.5 each + * - secondary backend (GLES): 0.5 */ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -51,9 +51,6 @@ clippy::pattern_type_mismatch, )] -/// DirectX11 API internals. -#[cfg(all(feature = "dx11", windows))] -pub mod dx11; /// DirectX12 API internals. #[cfg(all(feature = "dx12", windows))] pub mod dx12; @@ -71,8 +68,6 @@ pub mod vulkan; pub mod auxil; pub mod api { - #[cfg(all(feature = "dx11", windows))] - pub use super::dx11::Api as Dx11; #[cfg(all(feature = "dx12", windows))] pub use super::dx12::Api as Dx12; pub use super::empty::Api as Empty; diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 1d3e2e5016..c398b28583 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -604,6 +604,9 @@ impl super::PrivateCapabilities { function_specialization: Self::supports_any(device, FUNCTION_SPECIALIZATION_SUPPORT), depth_clip_mode: Self::supports_any(device, DEPTH_CLIP_MODE), texture_cube_array: Self::supports_any(device, TEXTURE_CUBE_ARRAY_SUPPORT), + supports_float_filtering: os_is_mac + || (version.at_least((11, 0), (14, 0), os_is_mac) + && device.supports_32bit_float_filtering()), format_depth24_stencil8: os_is_mac && device.d24_s8_supported(), format_depth32_stencil8_filter: os_is_mac, format_depth32_stencil8_none: !os_is_mac, @@ -821,6 +824,7 @@ impl super::PrivateCapabilities { | F::DEPTH32FLOAT_STENCIL8 | F::BGRA8UNORM_STORAGE; + features.set(F::FLOAT32_FILTERABLE, self.supports_float_filtering); features.set( F::INDIRECT_FIRST_INSTANCE | F::MULTI_DRAW_INDIRECT, self.indirect_draw_dispatch, diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 2a2ef02517..39589115e7 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -193,6 +193,7 @@ struct PrivateCapabilities { function_specialization: bool, depth_clip_mode: bool, texture_cube_array: bool, + supports_float_filtering: bool, format_depth24_stencil8: bool, format_depth32_stencil8_filter: bool, format_depth32_stencil8_none: bool, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 42d1c70d1b..a9eaf8b609 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -591,6 +591,10 @@ impl PhysicalDeviceFeatures { supports_bgra8unorm_storage(instance, phd, caps.device_api_version), ); + features.set( + F::FLOAT32_FILTERABLE, + is_float32_filterable_supported(instance, phd), + ); features.set( F::TEXTURE_FORMAT_NV12, (caps.device_api_version >= vk::API_VERSION_1_1 @@ -1073,13 +1077,6 @@ impl super::Instance { phd_features.to_wgpu(&info, &self.shared.raw, phd, &phd_capabilities); let mut workarounds = super::Workarounds::empty(); { - // see https://github.com/gfx-rs/gfx/issues/1930 - let _is_windows_intel_dual_src_bug = cfg!(windows) - && phd_capabilities.properties.vendor_id == db::intel::VENDOR - && (phd_capabilities.properties.device_id & db::intel::DEVICE_KABY_LAKE_MASK - == db::intel::DEVICE_KABY_LAKE_MASK - || phd_capabilities.properties.device_id & db::intel::DEVICE_SKY_LAKE_MASK - == db::intel::DEVICE_SKY_LAKE_MASK); // TODO: only enable for particular devices workarounds |= super::Workarounds::SEPARATE_ENTRY_POINTS; workarounds.set( @@ -1674,8 +1671,8 @@ impl crate::Adapter for super::Adapter { .framebuffer_stencil_sample_counts .min(limits.sampled_image_stencil_sample_counts) } else { - match format.sample_type(None) { - Some(wgt::TextureSampleType::Float { filterable: _ }) => limits + match format.sample_type(None, None) { + Some(wgt::TextureSampleType::Float { .. }) => limits .framebuffer_color_sample_counts .min(limits.sampled_image_color_sample_counts), Some(wgt::TextureSampleType::Sint) | Some(wgt::TextureSampleType::Uint) => { @@ -1866,6 +1863,21 @@ fn is_format_16bit_norm_supported(instance: &ash::Instance, phd: vk::PhysicalDev r16unorm && r16snorm && rg16unorm && rg16snorm && rgba16unorm && rgba16snorm } +fn is_float32_filterable_supported(instance: &ash::Instance, phd: vk::PhysicalDevice) -> bool { + let tiling = vk::ImageTiling::OPTIMAL; + let features = vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_LINEAR; + let r_float = supports_format(instance, phd, vk::Format::R32_SFLOAT, tiling, features); + let rg_float = supports_format(instance, phd, vk::Format::R32G32_SFLOAT, tiling, features); + let rgba_float = supports_format( + instance, + phd, + vk::Format::R32G32B32A32_SFLOAT, + tiling, + features, + ); + r_float && rg_float && rgba_float +} + fn supports_format( instance: &ash::Instance, phd: vk::PhysicalDevice, diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 1b9aecf2d1..826da91416 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -200,7 +200,7 @@ impl crate::ColorAttachment<'_, super::Api> { .view .attachment .view_format - .sample_type(None) + .sample_type(None, None) .unwrap() { wgt::TextureSampleType::Float { .. } => vk::ClearColorValue { diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 0c92158d4e..0caf1aa1c2 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -989,7 +989,7 @@ impl crate::Device for super::Device { wgt_view_formats = desc.view_formats.clone(); wgt_view_formats.push(desc.format); - if self.shared.private_caps.image_format_list { + if self.shared.private_caps.image_format_list && !desc.format.is_multi_planar_format() { vk_view_formats = desc .view_formats .iter() diff --git a/wgpu-info/README.md b/wgpu-info/README.md index 7857553b7a..8bfdd7d210 100644 --- a/wgpu-info/README.md +++ b/wgpu-info/README.md @@ -14,6 +14,6 @@ cargo run --bin wgpu-info #### Running Test on many Adapters -When called with any amount of arguments it will interpret all of the arguments as a command to run. It will run this command N different times, one for every combination of adapter and backend on the system. +When called with any amount of arguments, it will interpret all of the arguments as a command to run. It will run this command N different times, one for every combination of adapter and backend on the system. For every command invocation, it will set `WGPU_ADAPTER_NAME` to the name of the adapter name and `WGPU_BACKEND` to the name of the backend. This is used as the primary means of testing across many adapters. diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index f9d91fb2cc..dd9f906746 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -102,12 +102,10 @@ pub enum Backend { Metal = 2, /// Direct3D-12 (Windows) Dx12 = 3, - /// Direct3D-11 (Windows) - Dx11 = 4, /// OpenGL ES-3 (Linux, Android) - Gl = 5, + Gl = 4, /// WebGPU in the browser - BrowserWebGpu = 6, + BrowserWebGpu = 5, } impl Backend { @@ -118,7 +116,6 @@ impl Backend { Backend::Vulkan => "vulkan", Backend::Metal => "metal", Backend::Dx12 => "dx12", - Backend::Dx11 => "dx11", Backend::Gl => "gl", Backend::BrowserWebGpu => "webgpu", } @@ -158,8 +155,6 @@ bitflags::bitflags! { const METAL = 1 << Backend::Metal as u32; /// Supported on Windows 10 const DX12 = 1 << Backend::Dx12 as u32; - /// Supported on Windows 7+ - const DX11 = 1 << Backend::Dx11 as u32; /// Supported when targeting the web through webassembly const BROWSER_WEBGPU = 1 << Backend::BrowserWebGpu as u32; /// All the apis that wgpu offers first tier of support for. @@ -172,8 +167,8 @@ bitflags::bitflags! { /// All the apis that wgpu offers second tier of support for. These may /// be unsupported/still experimental. /// - /// OpenGL + DX11 - const SECONDARY = Self::GL.bits() | Self::DX11.bits(); + /// OpenGL + const SECONDARY = Self::GL.bits(); } } @@ -337,7 +332,18 @@ bitflags::bitflags! { // ? const NORM16_FILTERABLE = 1 << 17; (https://github.com/gpuweb/gpuweb/issues/3839) // ? const NORM16_RESOLVE = 1 << 18; (https://github.com/gpuweb/gpuweb/issues/3839) - // TODO const FLOAT32_FILTERABLE = 1 << 19; + + /// Allows textures with formats "r32float", "rg32float", and "rgba32float" to be filterable. + /// + /// Supported Platforms: + /// - Vulkan (mainly on Desktop GPUs) + /// - DX12 + /// - Metal on macOS or Apple9+ GPUs, optional on iOS/iPadOS with Apple7/8 GPUs + /// - GL with one of `GL_ARB_color_buffer_float`/`GL_EXT_color_buffer_float`/`OES_texture_float_linear` + /// + /// This is a web and native feature. + const FLOAT32_FILTERABLE = 1 << 19; + // ? const FLOAT32_BLENDABLE = 1 << 20; (https://github.com/gpuweb/gpuweb/issues/3556) // ? const 32BIT_FORMAT_MULTISAMPLE = 1 << 21; (https://github.com/gpuweb/gpuweb/issues/3844) // ? const 32BIT_FORMAT_RESOLVE = 1 << 22; (https://github.com/gpuweb/gpuweb/issues/3844) @@ -654,7 +660,6 @@ bitflags::bitflags! { /// - DX12 /// - Vulkan /// - Metal - /// - DX11 (emulated with uniforms) /// - OpenGL (emulated with uniforms) /// /// This is a native only feature. @@ -670,7 +675,6 @@ bitflags::bitflags! { /// - DX12 /// - Vulkan /// - Metal - /// - DX11 /// - OpenGL /// /// This is a native only feature. @@ -682,7 +686,6 @@ bitflags::bitflags! { /// - DX12 /// - Vulkan /// - Metal (macOS 10.12+ only) - /// - DX11 /// - OpenGL /// /// This is a native only feature. @@ -821,7 +824,6 @@ bitflags::bitflags! { /// /// Supported platforms: /// - Vulkan - /// - DX11 (feature level 10+) /// - DX12 /// - Metal (some) /// - OpenGL (some) @@ -1076,7 +1078,7 @@ pub struct Limits { /// - Vulkan: 128-256 bytes /// - DX12: 256 bytes /// - Metal: 4096 bytes - /// - DX11 & OpenGL don't natively support push constants, and are emulated with uniforms, + /// - OpenGL doesn't natively support push constants, and are emulated with uniforms, /// so this number is less useful but likely 256. pub max_push_constant_size: u32, @@ -1421,13 +1423,13 @@ bitflags::bitflags! { pub struct DownlevelFlags: u32 { /// The device supports compiling and using compute shaders. /// - /// DX11 on FL10 level hardware, WebGL2, and GLES3.0 devices do not support compute. + /// WebGL2, and GLES3.0 devices do not support compute. const COMPUTE_SHADERS = 1 << 0; /// Supports binding storage buffers and textures to fragment shaders. const FRAGMENT_WRITABLE_STORAGE = 1 << 1; /// Supports indirect drawing and dispatching. /// - /// DX11 on FL10 level hardware, WebGL2, GLES 3.0, and Metal on Apple1/Apple2 GPUs do not support indirect. + /// WebGL2, GLES 3.0, and Metal on Apple1/Apple2 GPUs do not support indirect. const INDIRECT_EXECUTION = 1 << 2; /// Supports non-zero `base_vertex` parameter to direct indexed draw calls. /// @@ -2890,6 +2892,11 @@ impl TextureFormat { } } + /// Returns `true` if the format is a multi-planar format + pub fn is_multi_planar_format(&self) -> bool { + matches!(*self, Self::NV12) + } + /// Returns `true` if the format has a color aspect pub fn has_color_aspect(&self) -> bool { !self.is_depth_stencil_format() @@ -3229,10 +3236,16 @@ impl TextureFormat { Self::Astc { .. } => ( noaa, basic), }; - let is_filterable = - self.sample_type(None) == Some(TextureSampleType::Float { filterable: true }); + // Get whether the format is filterable, taking features into account + let sample_type1 = self.sample_type(None, Some(device_features)); + let is_filterable = sample_type1 == Some(TextureSampleType::Float { filterable: true }); + + // Features that enable filtering don't affect blendability + let sample_type2 = self.sample_type(None, None); + let is_blendable = sample_type2 == Some(TextureSampleType::Float { filterable: true }); + flags.set(TextureFormatFeatureFlags::FILTERABLE, is_filterable); - flags.set(TextureFormatFeatureFlags::BLENDABLE, is_filterable); + flags.set(TextureFormatFeatureFlags::BLENDABLE, is_blendable); TextureFormatFeatures { allowed_usages, @@ -3244,9 +3257,17 @@ impl TextureFormat { /// /// Returns `None` only if the format is combined depth-stencil /// and `TextureAspect::All` or no `aspect` was provided - pub fn sample_type(&self, aspect: Option) -> Option { + pub fn sample_type( + &self, + aspect: Option, + device_features: Option, + ) -> Option { let float = TextureSampleType::Float { filterable: true }; - let unfilterable_float = TextureSampleType::Float { filterable: false }; + let float32_sample_type = TextureSampleType::Float { + filterable: device_features + .unwrap_or(Features::empty()) + .contains(Features::FLOAT32_FILTERABLE), + }; let depth = TextureSampleType::Depth; let uint = TextureSampleType::Uint; let sint = TextureSampleType::Sint; @@ -3267,7 +3288,7 @@ impl TextureFormat { | Self::Rgb10a2Unorm | Self::Rg11b10Float => Some(float), - Self::R32Float | Self::Rg32Float | Self::Rgba32Float => Some(unfilterable_float), + Self::R32Float | Self::Rg32Float | Self::Rgba32Float => Some(float32_sample_type), Self::R8Uint | Self::Rg8Uint @@ -4913,7 +4934,7 @@ pub enum PresentMode { /// /// No tearing will be observed. /// - /// Supported on DX11/12 on Windows 10, NVidia on Vulkan and Wayland on Vulkan. + /// Supported on DX12 on Windows 10, NVidia on Vulkan and Wayland on Vulkan. /// /// This is traditionally called "Fast Vsync" Mailbox = 5, diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 210e4d87db..bebeeaf5ff 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -66,10 +66,10 @@ features = ["raw-window-handle"] workspace = true features = ["metal"] -# We want the wgpu-core Direct3D backends and OpenGL (via WGL) on Windows. +# We want the wgpu-core Direct3D backend and OpenGL (via WGL) on Windows. [target.'cfg(windows)'.dependencies.wgc] workspace = true -features = ["dx11", "dx12", "gles"] +features = ["dx12", "gles"] # We want the wgpu-core Vulkan backend on Unix (but not emscripten, macOS, iOS) and Windows. [target.'cfg(any(windows, all(unix, not(target_os = "emscripten"), not(target_os = "ios"), not(target_os = "macos"))))'.dependencies.wgc] diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 658fc47c30..1faf25bfee 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -661,7 +661,7 @@ fn map_map_mode(mode: crate::MapMode) -> u32 { } } -const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 10] = [ +const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 11] = [ //TODO: update the name ( wgt::Features::DEPTH_CLIP_CONTROL, @@ -703,6 +703,10 @@ const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 10] = [ wgt::Features::BGRA8UNORM_STORAGE, web_sys::GpuFeatureName::Bgra8unormStorage, ), + ( + wgt::Features::FLOAT32_FILTERABLE, + web_sys::GpuFeatureName::Float32Filterable, + ), ]; fn map_wgt_features(supported_features: web_sys::GpuSupportedFeatures) -> wgt::Features { diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 9069b8758b..19199a0490 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -3971,7 +3971,7 @@ impl<'a> RenderPass<'a> { /// This is like calling [`RenderPass::draw`] but the contents of the call are specified in the `indirect_buffer`. /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs). /// - /// Indirect drawing has some caviats depending on the features available. We are not currently able to validate + /// Indirect drawing has some caveats depending on the features available. We are not currently able to validate /// these and issue an error. /// - If [`Features::INDIRECT_FIRST_INSTANCE`] is not present on the adapter, /// [`DrawIndirect::first_instance`](crate::util::DrawIndirectArgs::first_instance) will be ignored. @@ -3996,7 +3996,7 @@ impl<'a> RenderPass<'a> { /// This is like calling [`RenderPass::draw_indexed`] but the contents of the call are specified in the `indirect_buffer`. /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs). /// - /// Indirect drawing has some caviats depending on the features available. We are not currently able to validate + /// Indirect drawing has some caveats depending on the features available. We are not currently able to validate /// these and issue an error. /// - If [`Features::INDIRECT_FIRST_INSTANCE`] is not present on the adapter, /// [`DrawIndexedIndirect::first_instance`](crate::util::DrawIndexedIndirectArgs::first_instance) will be ignored.