Use wgpu environment variables (#198)
- Enables projects using `pixels` to select GPU and backend with the same environment variables used by `wgpu` examples. - cc #142
This commit is contained in:
parent
50c77a5f83
commit
c94dab65b7
|
@ -50,7 +50,7 @@ resolver = "2"
|
|||
### Driver issues
|
||||
|
||||
The most common issue is having an outdated graphics driver installed on the host machine. `pixels`
|
||||
requests a low power (aka integrated) GPU by default. If the examples are not working for any reason, you may try setting the `PIXELS_HIGH_PERF` environment variable (the value does not matter, e.g. `PIXELS_HIGH_PERF=1` is fine) to see if that addresses the issue on your host machine.
|
||||
requests a low power (aka integrated) GPU by default. If the examples are not working for any reason, you may try setting the `WGPU_POWER_PREF=high` environment variable to see if that addresses the issue on your host machine.
|
||||
|
||||
You should also try to keep your graphics drivers up-to-date, especially if you have an old Intel integrated GPU. Keep in mind that some drivers and GPUs are EOL and will not be supported.
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ use crate::renderers::{ScalingMatrix, ScalingRenderer};
|
|||
use crate::SurfaceSize;
|
||||
use crate::{Error, Pixels, PixelsContext, SurfaceTexture};
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
use std::env;
|
||||
|
||||
/// A builder to help create customized pixel buffers.
|
||||
pub struct PixelsBuilder<'req, 'dev, 'win, W: HasRawWindowHandle> {
|
||||
|
@ -51,7 +50,7 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
|
|||
PixelsBuilder {
|
||||
request_adapter_options: None,
|
||||
device_descriptor: wgpu::DeviceDescriptor::default(),
|
||||
backend: wgpu::Backends::PRIMARY,
|
||||
backend: wgpu::util::backend_bits_from_env().unwrap_or(wgpu::Backends::PRIMARY),
|
||||
width,
|
||||
height,
|
||||
_pixel_aspect_ratio: 1.0,
|
||||
|
@ -194,17 +193,25 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
|
|||
// TODO: Use `options.pixel_aspect_ratio` to stretch the scaled texture
|
||||
let surface = unsafe { instance.create_surface(self.surface_texture.window) };
|
||||
let compatible_surface = Some(&surface);
|
||||
let adapter = instance.request_adapter(&self.request_adapter_options.map_or_else(
|
||||
|| wgpu::RequestAdapterOptions {
|
||||
compatible_surface,
|
||||
power_preference: get_default_power_preference(),
|
||||
},
|
||||
|rao| wgpu::RequestAdapterOptions {
|
||||
compatible_surface: rao.compatible_surface.or(compatible_surface),
|
||||
power_preference: rao.power_preference,
|
||||
},
|
||||
));
|
||||
let adapter = pollster::block_on(adapter).ok_or(Error::AdapterNotFound)?;
|
||||
let request_adapter_options = &self.request_adapter_options;
|
||||
let adapter =
|
||||
wgpu::util::initialize_adapter_from_env(&instance, self.backend).or_else(|| {
|
||||
let future =
|
||||
instance.request_adapter(&request_adapter_options.as_ref().map_or_else(
|
||||
|| wgpu::RequestAdapterOptions {
|
||||
compatible_surface,
|
||||
power_preference:
|
||||
wgpu::util::power_preference_from_env().unwrap_or_default(),
|
||||
},
|
||||
|rao| wgpu::RequestAdapterOptions {
|
||||
compatible_surface: rao.compatible_surface.or(compatible_surface),
|
||||
power_preference: rao.power_preference,
|
||||
},
|
||||
));
|
||||
|
||||
pollster::block_on(future)
|
||||
});
|
||||
let adapter = adapter.ok_or(Error::AdapterNotFound)?;
|
||||
|
||||
let (device, queue) =
|
||||
pollster::block_on(adapter.request_device(&self.device_descriptor, None))
|
||||
|
@ -459,14 +466,3 @@ const fn get_texture_format_size(texture_format: wgpu::TextureFormat) -> f32 {
|
|||
| Astc12x12RgbaUnormSrgb => 9.0, // 12.0 * 12.0 / 16.0
|
||||
}
|
||||
}
|
||||
|
||||
fn get_default_power_preference() -> wgpu::PowerPreference {
|
||||
env::var("PIXELS_HIGH_PERF").map_or_else(
|
||||
|_| {
|
||||
env::var("PIXELS_LOW_POWER").map_or(wgpu::PowerPreference::default(), |_| {
|
||||
wgpu::PowerPreference::LowPower
|
||||
})
|
||||
},
|
||||
|_| wgpu::PowerPreference::HighPerformance,
|
||||
)
|
||||
}
|
||||
|
|
25
src/lib.rs
25
src/lib.rs
|
@ -12,19 +12,22 @@
|
|||
//!
|
||||
//! # Environment variables
|
||||
//!
|
||||
//! * `PIXELS_HIGH_PERF`: Switch the default adapter to high performance.
|
||||
//! * `PIXELS_LOW_POWER`: Switch the default adapter to low power.
|
||||
//! Pixels will default to selecting the most powerful GPU and most modern graphics API available on
|
||||
//! the system, and these choices can be overridden with environment variables. These are the same
|
||||
//! vars supported by the [`wgpu` examples](https://github.com/gfx-rs/wgpu/tree/v0.10/wgpu#usage).
|
||||
//!
|
||||
//! These variables change the default adapter to request either high performance or low power.
|
||||
//! (I.e. discrete or integrated GPUs.) The value is not checked, only the existence
|
||||
//! of the variable is relevant.
|
||||
//! * `WGPU_BACKEND`: Select the backend (aka graphics API).
|
||||
//! * Supported values: `vulkan`, `metal`, `dx11`, `dx12`, `gl`, `webgpu`
|
||||
//! * The default depends on capabilities of the host system, with `vulkan` being preferred on
|
||||
//! Linux and Windows, and `metal` preferred on macOS.
|
||||
//! * `WGPU_ADAPTER_NAME`: Select an adapter (aka GPU) with substring matching.
|
||||
//! * E.g. `1080` will match `NVIDIA GeForce 1080ti`
|
||||
//! * `WGPU_POWER_PREF`: Select an adapter (aka GPU) that meets the given power profile.
|
||||
//! * Supported values: `low`, `high`
|
||||
//! * The default is `low`. I.e. an integrated GPU will be preferred over a discrete GPU.
|
||||
//!
|
||||
//! The order of precedence for choosing a power preference is:
|
||||
//!
|
||||
//! 1. Application's specific adapter request through [`PixelsBuilder::request_adapter_options`]
|
||||
//! 2. `PIXELS_HIGH_PERF`
|
||||
//! 3. `PIXELS_LOW_POWER`
|
||||
//! 4. `wgpu` default power preference (usually low power)
|
||||
//! Note that `WGPU_ADAPTER_NAME` and `WGPU_POWER_PREF` are mutually exclusive and that
|
||||
//! `WGPU_ADAPTER_NAME` takes precedence.
|
||||
|
||||
#![deny(clippy::all)]
|
||||
|
||||
|
|
Loading…
Reference in a new issue