mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Allow disabling waiting for latency waitable object (#7400)
This commit is contained in:
parent
f04b3b020f
commit
e7cdfc436a
@ -73,7 +73,7 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913).
|
|||||||
|
|
||||||
#### DX12
|
#### DX12
|
||||||
|
|
||||||
- Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438).
|
- Allow disabling waiting for latency waitable object. By @marcpabst in [#7400](https://github.com/gfx-rs/wgpu/pull/7400)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
@ -85,6 +85,11 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913).
|
|||||||
|
|
||||||
- Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043).
|
- Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043).
|
||||||
|
|
||||||
|
##### DX12
|
||||||
|
|
||||||
|
- Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438).
|
||||||
|
|
||||||
|
|
||||||
## v26.0.2 (2025-07-23)
|
## v26.0.2 (2025-07-23)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@ -158,6 +158,7 @@ impl GPU {
|
|||||||
backend_options: wgpu_types::BackendOptions {
|
backend_options: wgpu_types::BackendOptions {
|
||||||
dx12: wgpu_types::Dx12BackendOptions {
|
dx12: wgpu_types::Dx12BackendOptions {
|
||||||
shader_compiler: wgpu_types::Dx12Compiler::Fxc,
|
shader_compiler: wgpu_types::Dx12Compiler::Fxc,
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
gl: wgpu_types::GlBackendOptions::default(),
|
gl: wgpu_types::GlBackendOptions::default(),
|
||||||
noop: wgpu_types::NoopBackendOptions::default(),
|
noop: wgpu_types::NoopBackendOptions::default(),
|
||||||
|
|||||||
@ -50,6 +50,7 @@ pub fn initialize_instance(backends: wgpu::Backends, params: &TestParameters) ->
|
|||||||
backend_options: wgpu::BackendOptions {
|
backend_options: wgpu::BackendOptions {
|
||||||
dx12: wgpu::Dx12BackendOptions {
|
dx12: wgpu::Dx12BackendOptions {
|
||||||
shader_compiler: dx12_shader_compiler,
|
shader_compiler: dx12_shader_compiler,
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
gl: wgpu::GlBackendOptions {
|
gl: wgpu::GlBackendOptions {
|
||||||
fence_behavior: if cfg!(target_family = "wasm") {
|
fence_behavior: if cfg!(target_family = "wasm") {
|
||||||
|
|||||||
@ -242,6 +242,7 @@ impl<A: hal::Api> Example<A> {
|
|||||||
backend_options: wgpu_types::BackendOptions {
|
backend_options: wgpu_types::BackendOptions {
|
||||||
dx12: Dx12BackendOptions {
|
dx12: Dx12BackendOptions {
|
||||||
shader_compiler: wgpu_types::Dx12Compiler::default_dynamic_dxc(),
|
shader_compiler: wgpu_types::Dx12Compiler::default_dynamic_dxc(),
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|||||||
@ -58,6 +58,7 @@ impl super::Adapter {
|
|||||||
instance_flags: wgt::InstanceFlags,
|
instance_flags: wgt::InstanceFlags,
|
||||||
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
||||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||||
|
backend_options: wgt::Dx12BackendOptions,
|
||||||
) -> Option<crate::ExposedAdapter<super::Api>> {
|
) -> Option<crate::ExposedAdapter<super::Api>> {
|
||||||
// Create the device so that we can get the capabilities.
|
// Create the device so that we can get the capabilities.
|
||||||
let device = {
|
let device = {
|
||||||
@ -534,6 +535,7 @@ impl super::Adapter {
|
|||||||
workarounds,
|
workarounds,
|
||||||
memory_budget_thresholds,
|
memory_budget_thresholds,
|
||||||
compiler_container,
|
compiler_container,
|
||||||
|
options: backend_options,
|
||||||
},
|
},
|
||||||
info,
|
info,
|
||||||
features,
|
features,
|
||||||
@ -697,6 +699,7 @@ impl crate::Adapter for super::Adapter {
|
|||||||
&self.library,
|
&self.library,
|
||||||
self.memory_budget_thresholds,
|
self.memory_budget_thresholds,
|
||||||
self.compiler_container.clone(),
|
self.compiler_container.clone(),
|
||||||
|
self.options.clone(),
|
||||||
)?;
|
)?;
|
||||||
Ok(crate::OpenDevice {
|
Ok(crate::OpenDevice {
|
||||||
device,
|
device,
|
||||||
|
|||||||
@ -48,6 +48,7 @@ impl super::Device {
|
|||||||
library: &Arc<D3D12Lib>,
|
library: &Arc<D3D12Lib>,
|
||||||
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
||||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||||
|
backend_options: wgt::Dx12BackendOptions,
|
||||||
) -> Result<Self, crate::DeviceError> {
|
) -> Result<Self, crate::DeviceError> {
|
||||||
if private_caps
|
if private_caps
|
||||||
.instance_flags
|
.instance_flags
|
||||||
@ -198,6 +199,7 @@ impl super::Device {
|
|||||||
raw.clone(),
|
raw.clone(),
|
||||||
Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||||
)),
|
)),
|
||||||
|
options: backend_options,
|
||||||
library: Arc::clone(library),
|
library: Arc::clone(library),
|
||||||
#[cfg(feature = "renderdoc")]
|
#[cfg(feature = "renderdoc")]
|
||||||
render_doc: Default::default(),
|
render_doc: Default::default(),
|
||||||
|
|||||||
@ -109,6 +109,7 @@ impl crate::Instance for super::Instance {
|
|||||||
flags: desc.flags,
|
flags: desc.flags,
|
||||||
memory_budget_thresholds: desc.memory_budget_thresholds,
|
memory_budget_thresholds: desc.memory_budget_thresholds,
|
||||||
compiler_container: Arc::new(compiler_container),
|
compiler_container: Arc::new(compiler_container),
|
||||||
|
options: desc.backend_options.dx12.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +126,7 @@ impl crate::Instance for super::Instance {
|
|||||||
target: SurfaceTarget::WndHandle(Foundation::HWND(handle.hwnd.get() as *mut _)),
|
target: SurfaceTarget::WndHandle(Foundation::HWND(handle.hwnd.get() as *mut _)),
|
||||||
supports_allow_tearing: self.supports_allow_tearing,
|
supports_allow_tearing: self.supports_allow_tearing,
|
||||||
swap_chain: RwLock::new(None),
|
swap_chain: RwLock::new(None),
|
||||||
|
options: self.options.clone(),
|
||||||
}),
|
}),
|
||||||
_ => Err(crate::InstanceError::new(format!(
|
_ => Err(crate::InstanceError::new(format!(
|
||||||
"window handle {window_handle:?} is not a Win32 handle"
|
"window handle {window_handle:?} is not a Win32 handle"
|
||||||
@ -147,6 +149,7 @@ impl crate::Instance for super::Instance {
|
|||||||
self.flags,
|
self.flags,
|
||||||
self.memory_budget_thresholds,
|
self.memory_budget_thresholds,
|
||||||
self.compiler_container.clone(),
|
self.compiler_container.clone(),
|
||||||
|
self.options.clone(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|||||||
@ -464,6 +464,7 @@ pub struct Instance {
|
|||||||
flags: wgt::InstanceFlags,
|
flags: wgt::InstanceFlags,
|
||||||
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
||||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||||
|
options: wgt::Dx12BackendOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
@ -481,6 +482,7 @@ impl Instance {
|
|||||||
target: SurfaceTarget::Visual(visual.to_owned()),
|
target: SurfaceTarget::Visual(visual.to_owned()),
|
||||||
supports_allow_tearing: self.supports_allow_tearing,
|
supports_allow_tearing: self.supports_allow_tearing,
|
||||||
swap_chain: RwLock::new(None),
|
swap_chain: RwLock::new(None),
|
||||||
|
options: self.options.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,6 +500,7 @@ impl Instance {
|
|||||||
target: SurfaceTarget::SurfaceHandle(surface_handle),
|
target: SurfaceTarget::SurfaceHandle(surface_handle),
|
||||||
supports_allow_tearing: self.supports_allow_tearing,
|
supports_allow_tearing: self.supports_allow_tearing,
|
||||||
swap_chain: RwLock::new(None),
|
swap_chain: RwLock::new(None),
|
||||||
|
options: self.options.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,6 +517,7 @@ impl Instance {
|
|||||||
target: SurfaceTarget::SwapChainPanel(swap_chain_panel.to_owned()),
|
target: SurfaceTarget::SwapChainPanel(swap_chain_panel.to_owned()),
|
||||||
supports_allow_tearing: self.supports_allow_tearing,
|
supports_allow_tearing: self.supports_allow_tearing,
|
||||||
swap_chain: RwLock::new(None),
|
swap_chain: RwLock::new(None),
|
||||||
|
options: self.options.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,7 +532,7 @@ struct SwapChain {
|
|||||||
// when the swapchain is destroyed
|
// when the swapchain is destroyed
|
||||||
resources: Vec<Direct3D12::ID3D12Resource>,
|
resources: Vec<Direct3D12::ID3D12Resource>,
|
||||||
/// Handle is freed in [`Self::release_resources()`]
|
/// Handle is freed in [`Self::release_resources()`]
|
||||||
waitable: Foundation::HANDLE,
|
waitable: Option<Foundation::HANDLE>,
|
||||||
acquired_count: usize,
|
acquired_count: usize,
|
||||||
present_mode: wgt::PresentMode,
|
present_mode: wgt::PresentMode,
|
||||||
format: wgt::TextureFormat,
|
format: wgt::TextureFormat,
|
||||||
@ -550,6 +554,7 @@ pub struct Surface {
|
|||||||
target: SurfaceTarget,
|
target: SurfaceTarget,
|
||||||
supports_allow_tearing: bool,
|
supports_allow_tearing: bool,
|
||||||
swap_chain: RwLock<Option<SwapChain>>,
|
swap_chain: RwLock<Option<SwapChain>>,
|
||||||
|
options: wgt::Dx12BackendOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Surface {}
|
unsafe impl Send for Surface {}
|
||||||
@ -559,6 +564,12 @@ impl Surface {
|
|||||||
pub fn swap_chain(&self) -> Option<Dxgi::IDXGISwapChain3> {
|
pub fn swap_chain(&self) -> Option<Dxgi::IDXGISwapChain3> {
|
||||||
Some(self.swap_chain.read().as_ref()?.raw.clone())
|
Some(self.swap_chain.read().as_ref()?.raw.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the waitable handle associated with this swap chain, if any.
|
||||||
|
/// Handle is only valid while the swap chain is alive.
|
||||||
|
pub unsafe fn waitable_handle(&self) -> Option<Foundation::HANDLE> {
|
||||||
|
self.swap_chain.read().as_ref()?.waitable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@ -601,6 +612,7 @@ pub struct Adapter {
|
|||||||
workarounds: Workarounds,
|
workarounds: Workarounds,
|
||||||
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
|
||||||
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
compiler_container: Arc<shader_compilation::CompilerContainer>,
|
||||||
|
options: wgt::Dx12BackendOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Adapter {}
|
unsafe impl Send for Adapter {}
|
||||||
@ -659,6 +671,7 @@ pub struct Device {
|
|||||||
idler: Idler,
|
idler: Idler,
|
||||||
features: wgt::Features,
|
features: wgt::Features,
|
||||||
shared: Arc<DeviceShared>,
|
shared: Arc<DeviceShared>,
|
||||||
|
options: wgt::Dx12BackendOptions,
|
||||||
// CPU only pools
|
// CPU only pools
|
||||||
rtv_pool: Arc<Mutex<descriptor::CpuPool>>,
|
rtv_pool: Arc<Mutex<descriptor::CpuPool>>,
|
||||||
dsv_pool: Mutex<descriptor::CpuPool>,
|
dsv_pool: Mutex<descriptor::CpuPool>,
|
||||||
@ -1178,7 +1191,9 @@ impl crate::DynAccelerationStructure for AccelerationStructure {}
|
|||||||
|
|
||||||
impl SwapChain {
|
impl SwapChain {
|
||||||
unsafe fn release_resources(mut self) -> Dxgi::IDXGISwapChain3 {
|
unsafe fn release_resources(mut self) -> Dxgi::IDXGISwapChain3 {
|
||||||
unsafe { Foundation::HANDLE::free(&mut self.waitable) };
|
if let Some(mut waitable) = self.waitable.take() {
|
||||||
|
unsafe { Foundation::HANDLE::free(&mut waitable) };
|
||||||
|
}
|
||||||
self.raw
|
self.raw
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1190,14 +1205,21 @@ impl SwapChain {
|
|||||||
Some(duration) => duration.as_millis() as u32,
|
Some(duration) => duration.as_millis() as u32,
|
||||||
None => Threading::INFINITE,
|
None => Threading::INFINITE,
|
||||||
};
|
};
|
||||||
match unsafe { Threading::WaitForSingleObject(self.waitable, timeout_ms) } {
|
|
||||||
Foundation::WAIT_ABANDONED | Foundation::WAIT_FAILED => Err(crate::SurfaceError::Lost),
|
if let Some(waitable) = self.waitable {
|
||||||
Foundation::WAIT_OBJECT_0 => Ok(true),
|
match unsafe { Threading::WaitForSingleObject(waitable, timeout_ms) } {
|
||||||
Foundation::WAIT_TIMEOUT => Ok(false),
|
Foundation::WAIT_ABANDONED | Foundation::WAIT_FAILED => {
|
||||||
other => {
|
Err(crate::SurfaceError::Lost)
|
||||||
log::error!("Unexpected wait status: 0x{other:x?}");
|
}
|
||||||
Err(crate::SurfaceError::Lost)
|
Foundation::WAIT_OBJECT_0 => Ok(true),
|
||||||
|
Foundation::WAIT_TIMEOUT => Ok(false),
|
||||||
|
other => {
|
||||||
|
log::error!("Unexpected wait status: 0x{other:x?}");
|
||||||
|
Err(crate::SurfaceError::Lost)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Ok(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1365,7 +1387,14 @@ impl crate::Surface for Surface {
|
|||||||
|
|
||||||
unsafe { swap_chain.SetMaximumFrameLatency(config.maximum_frame_latency) }
|
unsafe { swap_chain.SetMaximumFrameLatency(config.maximum_frame_latency) }
|
||||||
.into_device_result("SetMaximumFrameLatency")?;
|
.into_device_result("SetMaximumFrameLatency")?;
|
||||||
let waitable = unsafe { swap_chain.GetFrameLatencyWaitableObject() };
|
|
||||||
|
let waitable = match device.options.latency_waitable_object {
|
||||||
|
wgt::Dx12UseFrameLatencyWaitableObject::None => None,
|
||||||
|
wgt::Dx12UseFrameLatencyWaitableObject::Wait
|
||||||
|
| wgt::Dx12UseFrameLatencyWaitableObject::DontWait => {
|
||||||
|
Some(unsafe { swap_chain.GetFrameLatencyWaitableObject() })
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut resources = Vec::with_capacity(swap_chain_buffer as usize);
|
let mut resources = Vec::with_capacity(swap_chain_buffer as usize);
|
||||||
for i in 0..swap_chain_buffer {
|
for i in 0..swap_chain_buffer {
|
||||||
@ -1412,7 +1441,13 @@ impl crate::Surface for Surface {
|
|||||||
let mut swapchain = self.swap_chain.write();
|
let mut swapchain = self.swap_chain.write();
|
||||||
let sc = swapchain.as_mut().unwrap();
|
let sc = swapchain.as_mut().unwrap();
|
||||||
|
|
||||||
unsafe { sc.wait(timeout) }?;
|
match self.options.latency_waitable_object {
|
||||||
|
wgt::Dx12UseFrameLatencyWaitableObject::None
|
||||||
|
| wgt::Dx12UseFrameLatencyWaitableObject::DontWait => {}
|
||||||
|
wgt::Dx12UseFrameLatencyWaitableObject::Wait => {
|
||||||
|
unsafe { sc.wait(timeout) }?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let base_index = unsafe { sc.raw.GetCurrentBackBufferIndex() } as usize;
|
let base_index = unsafe { sc.raw.GetCurrentBackBufferIndex() } as usize;
|
||||||
let index = (base_index + sc.acquired_count) % sc.resources.len();
|
let index = (base_index + sc.acquired_count) % sc.resources.len();
|
||||||
|
|||||||
@ -359,6 +359,8 @@ impl GlBackendOptions {
|
|||||||
pub struct Dx12BackendOptions {
|
pub struct Dx12BackendOptions {
|
||||||
/// Which DX12 shader compiler to use.
|
/// Which DX12 shader compiler to use.
|
||||||
pub shader_compiler: Dx12Compiler,
|
pub shader_compiler: Dx12Compiler,
|
||||||
|
/// Whether to wait for the latency waitable object before acquiring the next swapchain image.
|
||||||
|
pub latency_waitable_object: Dx12UseFrameLatencyWaitableObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dx12BackendOptions {
|
impl Dx12BackendOptions {
|
||||||
@ -368,8 +370,11 @@ impl Dx12BackendOptions {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn from_env_or_default() -> Self {
|
pub fn from_env_or_default() -> Self {
|
||||||
let compiler = Dx12Compiler::from_env().unwrap_or_default();
|
let compiler = Dx12Compiler::from_env().unwrap_or_default();
|
||||||
|
let latency_waitable_object =
|
||||||
|
Dx12UseFrameLatencyWaitableObject::from_env().unwrap_or_default();
|
||||||
Self {
|
Self {
|
||||||
shader_compiler: compiler,
|
shader_compiler: compiler,
|
||||||
|
latency_waitable_object,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +384,12 @@ impl Dx12BackendOptions {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_env(self) -> Self {
|
pub fn with_env(self) -> Self {
|
||||||
let shader_compiler = self.shader_compiler.with_env();
|
let shader_compiler = self.shader_compiler.with_env();
|
||||||
Self { shader_compiler }
|
let latency_waitable_object = self.latency_waitable_object.with_env();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
shader_compiler,
|
||||||
|
latency_waitable_object,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,6 +525,54 @@ impl Dx12Compiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether and how to use a waitable handle obtained from `GetFrameLatencyWaitableObject`.
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub enum Dx12UseFrameLatencyWaitableObject {
|
||||||
|
/// Do not obtain a waitable handle and do not wait for it. The swapchain will
|
||||||
|
/// be created without the `DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT` flag.
|
||||||
|
None,
|
||||||
|
/// Obtain a waitable handle and wait for it before acquiring the next swapchain image.
|
||||||
|
#[default]
|
||||||
|
Wait,
|
||||||
|
/// Create the swapchain with the `DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT` flag and
|
||||||
|
/// obtain a waitable handle, but do not wait for it before acquiring the next swapchain image.
|
||||||
|
/// This is useful if the application wants to wait for the waitable object itself.
|
||||||
|
DontWait,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Dx12UseFrameLatencyWaitableObject {
|
||||||
|
/// Choose whether to use a frame latency waitable object from the environment variable `WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT`.
|
||||||
|
///
|
||||||
|
/// Valid values, case insensitive:
|
||||||
|
/// - `None`
|
||||||
|
/// - `Wait`
|
||||||
|
/// - `DontWait`
|
||||||
|
#[must_use]
|
||||||
|
pub fn from_env() -> Option<Self> {
|
||||||
|
let value = crate::env::var("WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT")
|
||||||
|
.as_deref()?
|
||||||
|
.to_lowercase();
|
||||||
|
match value.as_str() {
|
||||||
|
"none" => Some(Self::None),
|
||||||
|
"wait" => Some(Self::Wait),
|
||||||
|
"dontwait" => Some(Self::DontWait),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Takes the given setting, modifies it based on the `WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT` environment variable, and returns the result.
|
||||||
|
///
|
||||||
|
/// See `from_env` for more information.
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_env(self) -> Self {
|
||||||
|
if let Some(compiler) = Self::from_env() {
|
||||||
|
compiler
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Selects which OpenGL ES 3 minor version to request.
|
/// Selects which OpenGL ES 3 minor version to request.
|
||||||
///
|
///
|
||||||
/// When using ANGLE as an OpenGL ES/EGL implementation, explicitly requesting `Version1` can provide a non-conformant ES 3.1 on APIs like D3D11.
|
/// When using ANGLE as an OpenGL ES/EGL implementation, explicitly requesting `Version1` can provide a non-conformant ES 3.1 on APIs like D3D11.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user