Spirv passthrough main (adopted, part deux) (#15352)

**Note:** This is an adoption of @Shfty 's adoption (#8131) of #3996!
All I've done is updated the branch and run the docs CI.

> **Note:** This is an adoption of #3996, originally authored by
@molikto
> 
> # Objective
> Allow use of `wgpu::Features::SPIRV_SHADER_PASSTHROUGH` and the
corresponding `wgpu::Device::create_shader_module_spirv` for SPIR-V
shader assets.
> 
> This enables use-cases where naga is not sufficient to load a given
(valid) SPIR-V module, i.e. cases where naga lacks support for a given
SPIR-V feature employed by a third-party codegen backend like
`rust-gpu`.
> 
> ## Solution
> * Reimplemented the changes from [Spirv shader
bypass #3996](https://github.com/bevyengine/bevy/pull/3996), on account
of the original branch having been deleted.
> * Documented the new `spirv_shader_passthrough` feature flag with the
appropriate platform support context from [wgpu's
documentation](https://docs.rs/wgpu/latest/wgpu/struct.Features.html#associatedconstant.SPIRV_SHADER_PASSTHROUGH).
> 
> ## Changelog
> * Adds a `spirv_shader_passthrough` feature flag to the following
crates:
>   
>   * `bevy`
>   * `bevy_internal`
>   * `bevy_render`
> * Extends `RenderDevice::create_shader_module` with a conditional call
to `wgpu::Device::create_shader_module_spirv` if
`spirv_shader_passthrough` is enabled and
`wgpu::Features::SPIRV_SHADER_PASSTHROUGH` is present for the current
platform.
> * Documents the relevant `wgpu` platform support in
`docs/cargo_features.md`

---------

Co-authored-by: Josh Palmer <1253239+Shfty@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
Rich Churcher 2024-09-23 02:51:14 +12:00 committed by GitHub
parent 67615c5051
commit 58f6fa94a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 32 additions and 0 deletions

View file

@ -164,6 +164,9 @@ bevy_gizmos = ["bevy_internal/bevy_gizmos", "bevy_color"]
# Provides a collection of developer tools # Provides a collection of developer tools
bevy_dev_tools = ["bevy_internal/bevy_dev_tools"] bevy_dev_tools = ["bevy_internal/bevy_dev_tools"]
# Enable passthrough loading for SPIR-V shaders (Only supported on Vulkan, shader capabilities and extensions must agree with the platform implementation)
spirv_shader_passthrough = ["bevy_internal/spirv_shader_passthrough"]
# Tracing support, saving a file in Chrome Tracing format # Tracing support, saving a file in Chrome Tracing format
trace_chrome = ["trace", "bevy_internal/trace_chrome"] trace_chrome = ["trace", "bevy_internal/trace_chrome"]

View file

@ -44,6 +44,9 @@ ktx2 = ["bevy_render/ktx2"]
zlib = ["bevy_render/zlib"] zlib = ["bevy_render/zlib"]
zstd = ["bevy_render/zstd"] zstd = ["bevy_render/zstd"]
# Enable SPIR-V passthrough
spirv_shader_passthrough = ["bevy_render/spirv_shader_passthrough"]
# Include tonemapping LUT KTX2 files. # Include tonemapping LUT KTX2 files.
tonemapping_luts = ["bevy_core_pipeline/tonemapping_luts"] tonemapping_luts = ["bevy_core_pipeline/tonemapping_luts"]

View file

@ -27,6 +27,9 @@ shader_format_spirv = ["wgpu/spirv", "naga/spv-in", "naga/spv-out"]
zlib = ["flate2"] zlib = ["flate2"]
zstd = ["ruzstd"] zstd = ["ruzstd"]
# Enable SPIR-V shader passthrough
spirv_shader_passthrough = []
trace = ["profiling"] trace = ["profiling"]
tracing-tracy = [] tracing-tracy = []
ci_limits = [] ci_limits = []

View file

@ -49,6 +49,28 @@ impl RenderDevice {
/// Creates a [`ShaderModule`](wgpu::ShaderModule) from either SPIR-V or WGSL source code. /// Creates a [`ShaderModule`](wgpu::ShaderModule) from either SPIR-V or WGSL source code.
#[inline] #[inline]
pub fn create_shader_module(&self, desc: wgpu::ShaderModuleDescriptor) -> wgpu::ShaderModule { pub fn create_shader_module(&self, desc: wgpu::ShaderModuleDescriptor) -> wgpu::ShaderModule {
#[cfg(feature = "spirv_shader_passthrough")]
match &desc.source {
wgpu::ShaderSource::SpirV(source)
if self
.features()
.contains(wgpu::Features::SPIRV_SHADER_PASSTHROUGH) =>
{
// SAFETY:
// This call passes binary data to the backend as-is and can potentially result in a driver crash or bogus behaviour.
// No attempt is made to ensure that data is valid SPIR-V.
unsafe {
self.device
.create_shader_module_spirv(&wgpu::ShaderModuleDescriptorSpirV {
label: desc.label,
source: source.clone(),
})
}
}
_ => self.device.create_shader_module(desc),
}
#[cfg(not(feature = "spirv_shader_passthrough"))]
self.device.create_shader_module(desc) self.device.create_shader_module(desc)
} }

View file

@ -78,6 +78,7 @@ The default feature set enables most of the expected features of a game engine,
|serialize|Enable serialization support through serde| |serialize|Enable serialization support through serde|
|shader_format_glsl|Enable support for shaders in GLSL| |shader_format_glsl|Enable support for shaders in GLSL|
|shader_format_spirv|Enable support for shaders in SPIR-V| |shader_format_spirv|Enable support for shaders in SPIR-V|
|spirv_shader_passthrough|Enable passthrough loading for SPIR-V shaders (Only supported on Vulkan, shader capabilities and extensions must agree with the platform implementation)|
|symphonia-aac|AAC audio format support (through symphonia)| |symphonia-aac|AAC audio format support (through symphonia)|
|symphonia-all|AAC, FLAC, MP3, MP4, OGG/VORBIS, and WAV audio formats support (through symphonia)| |symphonia-all|AAC, FLAC, MP3, MP4, OGG/VORBIS, and WAV audio formats support (through symphonia)|
|symphonia-flac|FLAC audio format support (through symphonia)| |symphonia-flac|FLAC audio format support (through symphonia)|