Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_render/src/settings.rs
6595 views
1
use crate::renderer::{
2
RenderAdapter, RenderAdapterInfo, RenderDevice, RenderInstance, RenderQueue,
3
};
4
use alloc::borrow::Cow;
5
6
pub use wgpu::{
7
Backends, Dx12Compiler, Features as WgpuFeatures, Gles3MinorVersion, InstanceFlags,
8
Limits as WgpuLimits, MemoryHints, PowerPreference,
9
};
10
use wgpu::{DxcShaderModel, MemoryBudgetThresholds};
11
12
/// Configures the priority used when automatically configuring the features/limits of `wgpu`.
13
#[derive(Clone)]
14
pub enum WgpuSettingsPriority {
15
/// WebGPU default features and limits
16
Compatibility,
17
/// The maximum supported features and limits of the adapter and backend
18
Functionality,
19
/// WebGPU default limits plus additional constraints in order to be compatible with WebGL2
20
WebGL2,
21
}
22
23
/// Provides configuration for renderer initialization. Use [`RenderDevice::features`](RenderDevice::features),
24
/// [`RenderDevice::limits`](RenderDevice::limits), and the [`RenderAdapterInfo`]
25
/// resource to get runtime information about the actual adapter, backend, features, and limits.
26
/// NOTE: [`Backends::DX12`](Backends::DX12), [`Backends::METAL`](Backends::METAL), and
27
/// [`Backends::VULKAN`](Backends::VULKAN) are enabled by default for non-web and the best choice
28
/// is automatically selected. Web using the `webgl` feature uses [`Backends::GL`](Backends::GL).
29
/// NOTE: If you want to use [`Backends::GL`](Backends::GL) in a native app on `Windows` and/or `macOS`, you must
30
/// use [`ANGLE`](https://github.com/gfx-rs/wgpu#angle) and enable the `gles` feature. This is
31
/// because wgpu requires EGL to create a GL context without a window and only ANGLE supports that.
32
#[derive(Clone)]
33
pub struct WgpuSettings {
34
pub device_label: Option<Cow<'static, str>>,
35
pub backends: Option<Backends>,
36
pub power_preference: PowerPreference,
37
pub priority: WgpuSettingsPriority,
38
/// The features to ensure are enabled regardless of what the adapter/backend supports.
39
/// Setting these explicitly may cause renderer initialization to fail.
40
pub features: WgpuFeatures,
41
/// The features to ensure are disabled regardless of what the adapter/backend supports
42
pub disabled_features: Option<WgpuFeatures>,
43
/// The imposed limits.
44
pub limits: WgpuLimits,
45
/// The constraints on limits allowed regardless of what the adapter/backend supports
46
pub constrained_limits: Option<WgpuLimits>,
47
/// The shader compiler to use for the DX12 backend.
48
pub dx12_shader_compiler: Dx12Compiler,
49
/// Allows you to choose which minor version of GLES3 to use (3.0, 3.1, 3.2, or automatic)
50
/// This only applies when using ANGLE and the GL backend.
51
pub gles3_minor_version: Gles3MinorVersion,
52
/// These are for controlling WGPU's debug information to eg. enable validation and shader debug info in release builds.
53
pub instance_flags: InstanceFlags,
54
/// This hints to the WGPU device about the preferred memory allocation strategy.
55
pub memory_hints: MemoryHints,
56
/// The thresholds for device memory budget.
57
pub instance_memory_budget_thresholds: MemoryBudgetThresholds,
58
/// If true, will force wgpu to use a software renderer, if available.
59
pub force_fallback_adapter: bool,
60
/// The name of the adapter to use.
61
pub adapter_name: Option<String>,
62
}
63
64
impl Default for WgpuSettings {
65
fn default() -> Self {
66
let default_backends = if cfg!(all(
67
feature = "webgl",
68
target_arch = "wasm32",
69
not(feature = "webgpu")
70
)) {
71
Backends::GL
72
} else if cfg!(all(feature = "webgpu", target_arch = "wasm32")) {
73
Backends::BROWSER_WEBGPU
74
} else {
75
Backends::all()
76
};
77
78
let backends = Some(Backends::from_env().unwrap_or(default_backends));
79
80
let power_preference =
81
PowerPreference::from_env().unwrap_or(PowerPreference::HighPerformance);
82
83
let priority = settings_priority_from_env().unwrap_or(WgpuSettingsPriority::Functionality);
84
85
let limits = if cfg!(all(
86
feature = "webgl",
87
target_arch = "wasm32",
88
not(feature = "webgpu")
89
)) || matches!(priority, WgpuSettingsPriority::WebGL2)
90
{
91
wgpu::Limits::downlevel_webgl2_defaults()
92
} else {
93
#[expect(clippy::allow_attributes, reason = "`unused_mut` is not always linted")]
94
#[allow(
95
unused_mut,
96
reason = "This variable needs to be mutable if the `ci_limits` feature is enabled"
97
)]
98
let mut limits = wgpu::Limits::default();
99
#[cfg(feature = "ci_limits")]
100
{
101
limits.max_storage_textures_per_shader_stage = 4;
102
limits.max_texture_dimension_3d = 1024;
103
}
104
limits
105
};
106
107
let dx12_shader_compiler =
108
Dx12Compiler::from_env().unwrap_or(if cfg!(feature = "statically-linked-dxc") {
109
Dx12Compiler::StaticDxc
110
} else {
111
let dxc = "dxcompiler.dll";
112
113
if cfg!(target_os = "windows") && std::fs::metadata(dxc).is_ok() {
114
Dx12Compiler::DynamicDxc {
115
dxc_path: String::from(dxc),
116
max_shader_model: DxcShaderModel::V6_7,
117
}
118
} else {
119
Dx12Compiler::Fxc
120
}
121
});
122
123
let gles3_minor_version = Gles3MinorVersion::from_env().unwrap_or_default();
124
125
let instance_flags = InstanceFlags::default().with_env();
126
127
Self {
128
device_label: Default::default(),
129
backends,
130
power_preference,
131
priority,
132
features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
133
disabled_features: None,
134
limits,
135
constrained_limits: None,
136
dx12_shader_compiler,
137
gles3_minor_version,
138
instance_flags,
139
memory_hints: MemoryHints::default(),
140
instance_memory_budget_thresholds: MemoryBudgetThresholds::default(),
141
force_fallback_adapter: false,
142
adapter_name: None,
143
}
144
}
145
}
146
147
#[derive(Clone)]
148
pub struct RenderResources(
149
pub RenderDevice,
150
pub RenderQueue,
151
pub RenderAdapterInfo,
152
pub RenderAdapter,
153
pub RenderInstance,
154
#[cfg(feature = "raw_vulkan_init")]
155
pub crate::renderer::raw_vulkan_init::AdditionalVulkanFeatures,
156
);
157
158
/// An enum describing how the renderer will initialize resources. This is used when creating the [`RenderPlugin`](crate::RenderPlugin).
159
#[expect(
160
clippy::large_enum_variant,
161
reason = "See https://github.com/bevyengine/bevy/issues/19220"
162
)]
163
pub enum RenderCreation {
164
/// Allows renderer resource initialization to happen outside of the rendering plugin.
165
Manual(RenderResources),
166
/// Lets the rendering plugin create resources itself.
167
Automatic(WgpuSettings),
168
}
169
170
impl RenderCreation {
171
/// Function to create a [`RenderCreation::Manual`] variant.
172
pub fn manual(
173
device: RenderDevice,
174
queue: RenderQueue,
175
adapter_info: RenderAdapterInfo,
176
adapter: RenderAdapter,
177
instance: RenderInstance,
178
#[cfg(feature = "raw_vulkan_init")]
179
additional_vulkan_features: crate::renderer::raw_vulkan_init::AdditionalVulkanFeatures,
180
) -> Self {
181
RenderResources(
182
device,
183
queue,
184
adapter_info,
185
adapter,
186
instance,
187
#[cfg(feature = "raw_vulkan_init")]
188
additional_vulkan_features,
189
)
190
.into()
191
}
192
}
193
194
impl From<RenderResources> for RenderCreation {
195
fn from(value: RenderResources) -> Self {
196
Self::Manual(value)
197
}
198
}
199
200
impl Default for RenderCreation {
201
fn default() -> Self {
202
Self::Automatic(Default::default())
203
}
204
}
205
206
impl From<WgpuSettings> for RenderCreation {
207
fn from(value: WgpuSettings) -> Self {
208
Self::Automatic(value)
209
}
210
}
211
212
/// Get a features/limits priority from the environment variable `WGPU_SETTINGS_PRIO`
213
pub fn settings_priority_from_env() -> Option<WgpuSettingsPriority> {
214
Some(
215
match std::env::var("WGPU_SETTINGS_PRIO")
216
.as_deref()
217
.map(str::to_lowercase)
218
.as_deref()
219
{
220
Ok("compatibility") => WgpuSettingsPriority::Compatibility,
221
Ok("functionality") => WgpuSettingsPriority::Functionality,
222
Ok("webgl2") => WgpuSettingsPriority::WebGL2,
223
_ => return None,
224
},
225
)
226
}
227
228