Load FXC dynamically to remove the dependency on d3dcompiler_47.dll
#7588
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Connections
Implements #7531.
Description
Currently, wgpu statically links
d3dcompiler_47.dll
, even though it is only required for FXC, which is probably very rarely used. This increases the size of the executable and reduces compatibility, even if only slightly.This PR loads
d3dcompiler_47.dll
dynamically, removing the dependence on it.To achieve this, we change
dxc_container
to a genericcompiler_container
which is an enum that holds the relevant data for each compiler variant: Fxc, DynamicDxc, and StaticDxc. Only the DX12 shader compiler variant specified by the user is loaded.Previously, the
shader_compilation
module exposed multiple functions to create a container and compile shaders.Now, everything has been unified under the new
CompilerContainer
enum which exposesnew_*
functions to create the appropriate compiler container, and acompile
function which will call the appropriate implementation for each of the different compilers.There is one thing I am unsure about and would like to get your feedback on: In this PR, every call to
D3DCompile
reloads the function from the dll usinglibloading
due to the lifetime imposed bylibloading
. I chose this route because it is safe, but it is clearly not very performant. A better option would be to obtain a pointer to the function, and reuse that pointer every time. The thing that stopped me from going down that route is that I don't know if the library is pinned in memory once it is loaded. If it is, we can simply keep a pointer to the function in the same struct that holds the library; If the library is not pinned in memory, it would be incorrect to store the pointer.Testing
Tested using
cargo test
and running my wgpu/bevy based application, both work as expected.Additionally, using windows'
dumpbin /dependents <executable>
no longer showsd3dcompiler_47.dll
as a dependent.Squash or Rebase?
Squash
Checklist
cargo fmt
.cargo test
.cargo xtask test
to run tests.CHANGELOG.md
entry.