Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Updated Dxc integration for DX12 backend #3356

Merged
merged 33 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
99aa681
DXC Integration in DX12 Backend
39ali Oct 29, 2022
c3d3dba
Added DXC compile flags
39ali Oct 29, 2022
402c611
Replaced `and` with `and_then` so that `hassle_rs::compile_hlsl` isn'…
39ali Nov 1, 2022
85cfc38
Fixed clippy warnings
39ali Nov 3, 2022
b41a662
why doesn't this work...
Elabajaba Jan 5, 2023
49fb214
error handling
Elabajaba Jan 5, 2023
f0a426a
store dxc related stuff in `DxcContainer` to make it work
Elabajaba Jan 5, 2023
de254f4
clippy
Elabajaba Jan 6, 2023
f31917c
Rename ShaderDXIL to CompiledShader, don't re-validate/re-sign after …
Elabajaba Jan 6, 2023
2145dfd
arrayvec and clippy
Elabajaba Jan 6, 2023
89b76b5
add dx12compiler option to Instance::new()
Elabajaba Jan 11, 2023
c2bdc39
use InstanceOptions struct when creating an Instance
Elabajaba Jan 11, 2023
02617bb
Move dx12 shader compilation to a separate file and put hassle-rs beh…
Elabajaba Jan 11, 2023
e4e6622
clippy
Elabajaba Jan 11, 2023
124f2bd
docs and minor cleanup
Elabajaba Jan 12, 2023
84584e2
use InstanceOptions instead of Backends for web init
Elabajaba Jan 12, 2023
50d8479
unwrap_or_default()
Elabajaba Jan 12, 2023
1313757
fmt
Elabajaba Jan 12, 2023
21f04c8
Link to where to download the .dlls from Microsoft
Elabajaba Jan 12, 2023
1fde6fc
derive default for enum
Elabajaba Jan 12, 2023
7034749
more docs
Elabajaba Jan 12, 2023
c2e43f2
changelog
Elabajaba Jan 12, 2023
11835ac
changelog
Elabajaba Jan 12, 2023
ecf46bc
misc cleanup
Elabajaba Jan 12, 2023
458eb8f
Replace compile_dxc stub fallback with unimplemented!() as it is defi…
Elabajaba Jan 12, 2023
6d01198
document `WGPU_DX12_COMPILER` in the readme
Elabajaba Jan 13, 2023
879adb8
move shader compilation profiling to the functions where it happens
Elabajaba Jan 13, 2023
dbc1dc9
add CompiledShader helpers
Elabajaba Jan 13, 2023
b90908f
rename `shader` mod to `dxc`
Elabajaba Jan 13, 2023
221db56
remove InstanceOptions::new(...) in favour of using the struct
Elabajaba Jan 13, 2023
37e60b4
misc cleanup
Elabajaba Jan 13, 2023
84f19c2
rename InstanceOptions to InstanceDescriptor, dx12_shader_compiler is…
Elabajaba Jan 16, 2023
2048c27
Merge branch 'master' into dxc-integration
cwfitzgerald Jan 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,54 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non

`Instance::create_surface()` now returns `Result<Surface, CreateSurfaceError>` instead of `Surface`. This allows an error to be returned instead of panicking if the given window is a HTML canvas and obtaining a WebGPU or WebGL 2 context fails. (No other platforms currently report any errors through this path.) By @kpreid in [#3052](https://github.com/gfx-rs/wgpu/pull/3052/)

#### Instance creation now takes `InstanceDescriptor` instead of `Backends`

`Instance::new()` and `hub::Global::new()` now take an `InstanceDescriptor` struct which cointains both the existing `Backends` selection as well as a new `Dx12Compiler` field for selecting which Dx12 shader compiler to use.

```diff
- let instance = Instance::new(wgpu::Backends::all());
+ let instance = Instance::new(wgpu::InstanceDescriptor {
+ backends: wgpu::Backends::all(),
+ dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
+ });
```

```diff
- let global = wgc::hub::Global::new(
- "player",
- IdentityPassThroughFactory,
- wgpu::Backends::all(),
- );
+ let global = wgc::hub::Global::new(
+ "player",
+ IdentityPassThroughFactory,
+ wgpu::InstanceDescriptor {
+ backends: wgpu::Backends::all(),
+ dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
+ },
+ );
```

`Instance` now also also implements `Default`, which uses `wgpu::Backends::all()` and `wgpu::Dx12Compiler::Fxc` for `InstanceDescriptor`

```diff
- let instance = Instance::new(wgpu::InstanceDescriptor {
- backends: wgpu::Backends::all(),
- dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
- });
+ let instance = Instance::default();
```

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

#### Suballocate DX12 buffers and textures

`wgpu`'s DX12 backend can now suballocate buffers and textures when the `windows_rs` feature is enabled, which can give a significant increase in performance (in testing I've seen a 10000%+ improvement in a simple scene with 200 `write_buffer` calls per frame, and a 40%+ improvement in [Bistro using Bevy](https://github.com/vleue/bevy_bistro_playground)). Previously `wgpu-hal`'s DX12 backend created a new heap on the GPU every time you called write_buffer (by calling `CreateCommittedResource`), whereas now with the `windows_rs` feature enabled it uses [`gpu_allocator`](https://crates.io/crates/gpu-allocator) to manage GPU memory (and calls `CreatePlacedResource` with a suballocated heap). By @Elabajaba in [#3163](https://github.com/gfx-rs/wgpu/pull/3163)

#### DXC Shader Compiler Support for DX12

You can now choose to use the DXC compiler for DX12 instead of FXC. The DXC compiler is faster, less buggy, and allows for new features compared to the old, unmaintained FXC compiler. You can choose which compiler to use at `Instance` creation using the `Dx12Compiler` field in the `InstanceDescriptor` struct. Note that DXC requires both `dxcompiler.dll` and `dxil.dll`, which can be downloaded from https://github.com/microsoft/DirectXShaderCompiler/releases. Both .dlls need to be shipped with your application when targeting DX12 and using the `DXC` compiler. If the .dlls can't be loaded, then it will fall back to the FXC compiler. By @39ali and @Elabajaba in [#3356](https://github.com/gfx-rs/wgpu/pull/3356)

#### Texture Format Reinterpretation

The `view_formats` field is used to specify formats that are compatible with the texture format to allow the creation of views with different formats, currently, only changing srgb-ness is allowed.
Expand Down
28 changes: 28 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ gpu-allocator = { version = "0.21", default_features = false, features = ["d3d12
native = { package = "d3d12", version = "0.5.0" }
range-alloc = "0.1"
winapi = "0.3"
hassle-rs = "0.9.0"

# Gles dependencies
egl = { package = "khronos-egl", version = "4.1" }
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ All testing and example infrastructure shares the same set of environment variab
- `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_POWER_PREF` with the power preference to choose when a specific adapter name isn't specified (`high` or `low`)
- `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`)

When running the CTS, use the variables `DENO_WEBGPU_ADAPTER_NAME`, `DENO_WEBGPU_BACKEND`, `DENO_WEBGPU_POWER_PREFERENCE`.

Expand Down
5 changes: 4 additions & 1 deletion deno_webgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,10 @@ pub async fn op_webgpu_request_adapter(
state.put(wgpu_core::hub::Global::new(
"webgpu",
wgpu_core::hub::IdentityManagerFactory,
backends,
wgpu_types::InstanceDescriptor {
backends,
dx12_shader_compiler: wgpu_types::Dx12Compiler::Fxc,
Elabajaba marked this conversation as resolved.
Show resolved Hide resolved
},
));
state.borrow::<Instance>()
};
Expand Down
6 changes: 5 additions & 1 deletion player/src/bin/play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ fn main() {
.build(&event_loop)
.unwrap();

let global = wgc::hub::Global::new("player", IdentityPassThroughFactory, wgt::Backends::all());
let global = wgc::hub::Global::new(
"player",
IdentityPassThroughFactory,
wgt::InstanceDescriptor::default(),
);
let mut command_buffer_id_manager = wgc::hub::IdentityManager::default();

#[cfg(feature = "winit")]
Expand Down
9 changes: 8 additions & 1 deletion player/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,14 @@ impl Corpus {
let dir = path.parent().unwrap();
let corpus: Corpus = ron::de::from_reader(File::open(&path).unwrap()).unwrap();

let global = wgc::hub::Global::new("test", IdentityPassThroughFactory, corpus.backends);
let global = wgc::hub::Global::new(
"test",
IdentityPassThroughFactory,
wgt::InstanceDescriptor {
backends: corpus.backends,
dx12_shader_compiler: wgt::Dx12Compiler::Fxc,
},
);
for &backend in BACKENDS {
if !corpus.backends.contains(backend.into()) {
continue;
Expand Down
4 changes: 2 additions & 2 deletions wgpu-core/src/hub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1108,10 +1108,10 @@ pub struct Global<G: GlobalIdentityHandlerFactory> {
}

impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn new(name: &str, factory: G, backends: wgt::Backends) -> Self {
pub fn new(name: &str, factory: G, instance_desc: wgt::InstanceDescriptor) -> Self {
profiling::scope!("Global::new");
Self {
instance: Instance::new(name, backends),
instance: Instance::new(name, instance_desc),
surfaces: Registry::without_backend(&factory, "Surface"),
hubs: Hubs::new(&factory),
}
Expand Down
17 changes: 9 additions & 8 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ pub struct Instance {
}

impl Instance {
pub fn new(name: &str, backends: Backends) -> Self {
fn init<A: HalApi>(_: A, mask: Backends) -> Option<A::Instance> {
if mask.contains(A::VARIANT.into()) {
pub fn new(name: &str, instance_desc: wgt::InstanceDescriptor) -> Self {
fn init<A: HalApi>(_: A, instance_desc: &wgt::InstanceDescriptor) -> Option<A::Instance> {
if instance_desc.backends.contains(A::VARIANT.into()) {
let mut flags = hal::InstanceFlags::empty();
if cfg!(debug_assertions) {
flags |= hal::InstanceFlags::VALIDATION;
Expand All @@ -78,6 +78,7 @@ impl Instance {
let hal_desc = hal::InstanceDescriptor {
name: "wgpu",
flags,
dx12_shader_compiler: instance_desc.dx12_shader_compiler.clone(),
};
unsafe { hal::Instance::init(&hal_desc).ok() }
} else {
Expand All @@ -88,15 +89,15 @@ impl Instance {
Self {
name: name.to_string(),
#[cfg(feature = "vulkan")]
vulkan: init(hal::api::Vulkan, backends),
vulkan: init(hal::api::Vulkan, &instance_desc),
#[cfg(feature = "metal")]
metal: init(hal::api::Metal, backends),
metal: init(hal::api::Metal, &instance_desc),
#[cfg(feature = "dx12")]
dx12: init(hal::api::Dx12, backends),
dx12: init(hal::api::Dx12, &instance_desc),
#[cfg(feature = "dx11")]
dx11: init(hal::api::Dx11, backends),
dx11: init(hal::api::Dx11, &instance_desc),
#[cfg(feature = "gles")]
gl: init(hal::api::Gles, backends),
gl: init(hal::api::Gles, &instance_desc),
}
}

Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dx11 = ["naga/hlsl-out", "native", "libloading", "winapi/d3d11", "winapi/d3d11_1
dx12 = ["naga/hlsl-out", "native", "bit-set", "range-alloc", "winapi/d3d12", "winapi/d3d12shader", "winapi/d3d12sdklayers", "winapi/dxgi1_6"]
# TODO: This is a separate feature until Mozilla okays windows-rs, see https://github.com/gfx-rs/wgpu/issues/3207 for the tracking issue.
windows_rs = ["gpu-allocator"]
dxc_shader_compiler = ["hassle-rs"]
renderdoc = ["libloading", "renderdoc-sys"]
emscripten = ["gles"]

Expand Down Expand Up @@ -75,6 +76,7 @@ glow = { git = "https://github.com/grovesNL/glow", rev = "c8a011fcd57a5c68cc917e
bit-set = { version = "0.5", optional = true }
range-alloc = { version = "0.1", optional = true }
gpu-allocator = { version = "0.21", default_features = false, features = ["d3d12", "windows", "public-winapi"], optional = true }
hassle-rs = { version = "0.9", optional = true }

[dependencies.wgt]
package = "wgpu-types"
Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/examples/halmark/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ impl<A: hal::Api> Example<A> {
} else {
hal::InstanceFlags::empty()
},
// Can't rely on having DXC available, so use FXC instead
dx12_shader_compiler: wgt::Dx12Compiler::Fxc,
};
let instance = unsafe { A::Instance::init(&instance_desc)? };
let mut surface = unsafe {
Expand Down
10 changes: 9 additions & 1 deletion wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl super::Adapter {
adapter: native::DxgiAdapter,
library: &Arc<native::D3D12Lib>,
instance_flags: crate::InstanceFlags,
dx12_shader_compiler: &wgt::Dx12Compiler,
) -> Option<crate::ExposedAdapter<super::Api>> {
// Create the device so that we can get the capabilities.
let device = {
Expand Down Expand Up @@ -243,6 +244,7 @@ impl super::Adapter {
private_caps,
presentation_timer,
workarounds,
dx12_shader_compiler: dx12_shader_compiler.clone(),
cwfitzgerald marked this conversation as resolved.
Show resolved Hide resolved
},
info,
features,
Expand Down Expand Up @@ -347,7 +349,13 @@ impl crate::Adapter<super::Api> for super::Adapter {
.into_device_result("Queue creation")?
};

let device = super::Device::new(self.device, queue, self.private_caps, &self.library)?;
let device = super::Device::new(
self.device,
queue,
self.private_caps,
&self.library,
self.dx12_shader_compiler.clone(),
)?;
Ok(crate::OpenDevice {
device,
queue: super::Queue {
Expand Down
Loading