use alloc::string::String;
use crate::Backends;
#[derive(Clone, Debug)]
pub struct InstanceDescriptor {
pub backends: Backends,
pub flags: InstanceFlags,
pub backend_options: BackendOptions,
}
impl Default for InstanceDescriptor {
fn default() -> Self {
Self {
backends: Backends::all(),
flags: InstanceFlags::default(),
backend_options: BackendOptions::default(),
}
}
}
impl InstanceDescriptor {
#[must_use]
pub fn from_env_or_default() -> Self {
Self::default().with_env()
}
#[must_use]
pub fn with_env(self) -> Self {
let backends = self.backends.with_env();
let flags = self.flags.with_env();
let backend_options = self.backend_options.with_env();
Self {
backends,
flags,
backend_options,
}
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct InstanceFlags: u32 {
const DEBUG = 1 << 0;
const VALIDATION = 1 << 1;
const DISCARD_HAL_LABELS = 1 << 2;
const ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER = 1 << 3;
const GPU_BASED_VALIDATION = 1 << 4;
}
}
impl Default for InstanceFlags {
fn default() -> Self {
Self::from_build_config()
}
}
impl InstanceFlags {
#[must_use]
pub fn debugging() -> Self {
InstanceFlags::DEBUG | InstanceFlags::VALIDATION
}
#[must_use]
pub fn advanced_debugging() -> Self {
Self::debugging() | InstanceFlags::GPU_BASED_VALIDATION
}
#[must_use]
pub fn from_build_config() -> Self {
if cfg!(debug_assertions) {
return InstanceFlags::debugging();
}
InstanceFlags::empty()
}
#[must_use]
pub fn from_env_or_default() -> Self {
Self::default().with_env()
}
#[must_use]
pub fn with_env(mut self) -> Self {
fn env(key: &str) -> Option<bool> {
crate::env::var(key).map(|s| match s.as_str() {
"0" => false,
_ => true,
})
}
if let Some(bit) = env("WGPU_VALIDATION") {
self.set(Self::VALIDATION, bit);
}
if let Some(bit) = env("WGPU_DEBUG") {
self.set(Self::DEBUG, bit);
}
if let Some(bit) = env("WGPU_DISCARD_HAL_LABELS") {
self.set(Self::DISCARD_HAL_LABELS, bit);
}
if let Some(bit) = env("WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER") {
self.set(Self::ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER, bit);
}
if let Some(bit) = env("WGPU_GPU_BASED_VALIDATION") {
self.set(Self::GPU_BASED_VALIDATION, bit);
}
self
}
}
#[derive(Clone, Debug, Default)]
pub struct BackendOptions {
pub gl: GlBackendOptions,
pub dx12: Dx12BackendOptions,
}
impl BackendOptions {
#[must_use]
pub fn from_env_or_default() -> Self {
let gl = GlBackendOptions::from_env_or_default();
let dx12 = Dx12BackendOptions::from_env_or_default();
Self { gl, dx12 }
}
#[must_use]
pub fn with_env(self) -> Self {
let gl = self.gl.with_env();
let dx12 = self.dx12.with_env();
Self { gl, dx12 }
}
}
#[derive(Clone, Debug, Default)]
pub struct GlBackendOptions {
pub gles_minor_version: Gles3MinorVersion,
}
impl GlBackendOptions {
#[must_use]
pub fn from_env_or_default() -> Self {
let gles_minor_version = Gles3MinorVersion::from_env().unwrap_or_default();
Self { gles_minor_version }
}
#[must_use]
pub fn with_env(self) -> Self {
let gles_minor_version = self.gles_minor_version.with_env();
Self { gles_minor_version }
}
}
#[derive(Clone, Debug, Default)]
pub struct Dx12BackendOptions {
pub shader_compiler: Dx12Compiler,
}
impl Dx12BackendOptions {
#[must_use]
pub fn from_env_or_default() -> Self {
let compiler = Dx12Compiler::from_env().unwrap_or_default();
Self {
shader_compiler: compiler,
}
}
#[must_use]
pub fn with_env(self) -> Self {
let shader_compiler = self.shader_compiler.with_env();
Self { shader_compiler }
}
}
#[derive(Clone, Debug, Default)]
pub enum Dx12Compiler {
#[default]
Fxc,
DynamicDxc {
dxc_path: String,
dxil_path: String,
},
StaticDxc,
}
impl Dx12Compiler {
#[must_use]
pub fn from_env() -> Option<Self> {
let value = crate::env::var("WGPU_DX12_COMPILER")
.as_deref()?
.to_lowercase();
match value.as_str() {
"dxc" | "dynamicdxc" => Some(Self::DynamicDxc {
dxc_path: String::from("dxcompiler.dll"),
dxil_path: String::from("dxil.dll"),
}),
"staticdxc" => Some(Self::StaticDxc),
"fxc" => Some(Self::Fxc),
_ => None,
}
}
#[must_use]
pub fn with_env(self) -> Self {
if let Some(compiler) = Self::from_env() {
compiler
} else {
self
}
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
pub enum Gles3MinorVersion {
#[default]
Automatic,
Version0,
Version1,
Version2,
}
impl Gles3MinorVersion {
#[must_use]
pub fn from_env() -> Option<Self> {
let value = crate::env::var("WGPU_GLES_MINOR_VERSION")
.as_deref()?
.to_lowercase();
match value.as_str() {
"automatic" => Some(Self::Automatic),
"0" => Some(Self::Version0),
"1" => Some(Self::Version1),
"2" => Some(Self::Version2),
_ => None,
}
}
#[must_use]
pub fn with_env(self) -> Self {
if let Some(compiler) = Self::from_env() {
compiler
} else {
self
}
}
}