bevy_render/
settings.rs

1use crate::renderer::{
2    RenderAdapter, RenderAdapterInfo, RenderDevice, RenderInstance, RenderQueue,
3};
4use std::borrow::Cow;
5
6pub use wgpu::{
7    Backends, Dx12Compiler, Features as WgpuFeatures, Gles3MinorVersion, InstanceFlags,
8    Limits as WgpuLimits, PowerPreference,
9};
10
11/// Configures the priority used when automatically configuring the features/limits of `wgpu`.
12#[derive(Clone)]
13pub enum WgpuSettingsPriority {
14    /// WebGPU default features and limits
15    Compatibility,
16    /// The maximum supported features and limits of the adapter and backend
17    Functionality,
18    /// WebGPU default limits plus additional constraints in order to be compatible with WebGL2
19    WebGL2,
20}
21
22/// Provides configuration for renderer initialization. Use [`RenderDevice::features`](RenderDevice::features),
23/// [`RenderDevice::limits`](RenderDevice::limits), and the [`RenderAdapterInfo`]
24/// resource to get runtime information about the actual adapter, backend, features, and limits.
25/// NOTE: [`Backends::DX12`](Backends::DX12), [`Backends::METAL`](Backends::METAL), and
26/// [`Backends::VULKAN`](Backends::VULKAN) are enabled by default for non-web and the best choice
27/// is automatically selected. Web using the `webgl` feature uses [`Backends::GL`](Backends::GL).
28/// NOTE: If you want to use [`Backends::GL`](Backends::GL) in a native app on `Windows` and/or `macOS`, you must
29/// use [`ANGLE`](https://github.com/gfx-rs/wgpu#angle). This is because wgpu requires EGL to
30/// create a GL context without a window and only ANGLE supports that.
31#[derive(Clone)]
32pub struct WgpuSettings {
33    pub device_label: Option<Cow<'static, str>>,
34    pub backends: Option<Backends>,
35    pub power_preference: PowerPreference,
36    pub priority: WgpuSettingsPriority,
37    /// The features to ensure are enabled regardless of what the adapter/backend supports.
38    /// Setting these explicitly may cause renderer initialization to fail.
39    pub features: WgpuFeatures,
40    /// The features to ensure are disabled regardless of what the adapter/backend supports
41    pub disabled_features: Option<WgpuFeatures>,
42    /// The imposed limits.
43    pub limits: WgpuLimits,
44    /// The constraints on limits allowed regardless of what the adapter/backend supports
45    pub constrained_limits: Option<WgpuLimits>,
46    /// The shader compiler to use for the DX12 backend.
47    pub dx12_shader_compiler: Dx12Compiler,
48    /// Allows you to choose which minor version of GLES3 to use (3.0, 3.1, 3.2, or automatic)
49    /// This only applies when using ANGLE and the GL backend.
50    pub gles3_minor_version: Gles3MinorVersion,
51    /// These are for controlling WGPU's debug information to eg. enable validation and shader debug info in release builds.
52    pub instance_flags: InstanceFlags,
53}
54
55impl Default for WgpuSettings {
56    fn default() -> Self {
57        let default_backends = if cfg!(all(
58            feature = "webgl",
59            target_arch = "wasm32",
60            not(feature = "webgpu")
61        )) {
62            Backends::GL
63        } else if cfg!(all(feature = "webgpu", target_arch = "wasm32")) {
64            Backends::BROWSER_WEBGPU
65        } else {
66            Backends::all()
67        };
68
69        let backends = Some(wgpu::util::backend_bits_from_env().unwrap_or(default_backends));
70
71        let power_preference =
72            wgpu::util::power_preference_from_env().unwrap_or(PowerPreference::HighPerformance);
73
74        let priority = settings_priority_from_env().unwrap_or(WgpuSettingsPriority::Functionality);
75
76        let limits = if cfg!(all(
77            feature = "webgl",
78            target_arch = "wasm32",
79            not(feature = "webgpu")
80        )) || matches!(priority, WgpuSettingsPriority::WebGL2)
81        {
82            wgpu::Limits::downlevel_webgl2_defaults()
83        } else {
84            #[allow(unused_mut)]
85            let mut limits = wgpu::Limits::default();
86            #[cfg(feature = "ci_limits")]
87            {
88                limits.max_storage_textures_per_shader_stage = 4;
89                limits.max_texture_dimension_3d = 1024;
90            }
91            limits
92        };
93
94        let dx12_compiler =
95            wgpu::util::dx12_shader_compiler_from_env().unwrap_or(Dx12Compiler::Dxc {
96                dxil_path: None,
97                dxc_path: None,
98            });
99
100        let gles3_minor_version = wgpu::util::gles_minor_version_from_env().unwrap_or_default();
101
102        let instance_flags = InstanceFlags::default().with_env();
103
104        Self {
105            device_label: Default::default(),
106            backends,
107            power_preference,
108            priority,
109            features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
110            disabled_features: None,
111            limits,
112            constrained_limits: None,
113            dx12_shader_compiler: dx12_compiler,
114            gles3_minor_version,
115            instance_flags,
116        }
117    }
118}
119
120/// An enum describing how the renderer will initialize resources. This is used when creating the [`RenderPlugin`](crate::RenderPlugin).
121pub enum RenderCreation {
122    /// Allows renderer resource initialization to happen outside of the rendering plugin.
123    Manual(
124        RenderDevice,
125        RenderQueue,
126        RenderAdapterInfo,
127        RenderAdapter,
128        RenderInstance,
129    ),
130    /// Lets the rendering plugin create resources itself.
131    Automatic(WgpuSettings),
132}
133
134impl RenderCreation {
135    /// Function to create a [`RenderCreation::Manual`] variant.
136    pub fn manual(
137        device: RenderDevice,
138        queue: RenderQueue,
139        adapter_info: RenderAdapterInfo,
140        adapter: RenderAdapter,
141        instance: RenderInstance,
142    ) -> Self {
143        Self::Manual(device, queue, adapter_info, adapter, instance)
144    }
145}
146
147impl Default for RenderCreation {
148    fn default() -> Self {
149        Self::Automatic(Default::default())
150    }
151}
152
153impl From<WgpuSettings> for RenderCreation {
154    fn from(value: WgpuSettings) -> Self {
155        Self::Automatic(value)
156    }
157}
158
159/// Get a features/limits priority from the environment variable `WGPU_SETTINGS_PRIO`
160pub fn settings_priority_from_env() -> Option<WgpuSettingsPriority> {
161    Some(
162        match std::env::var("WGPU_SETTINGS_PRIO")
163            .as_deref()
164            .map(str::to_lowercase)
165            .as_deref()
166        {
167            Ok("compatibility") => WgpuSettingsPriority::Compatibility,
168            Ok("functionality") => WgpuSettingsPriority::Functionality,
169            Ok("webgl2") => WgpuSettingsPriority::WebGL2,
170            _ => return None,
171        },
172    )
173}