From f95d1c55e3e05febb95e27a7b93ee649d9005256 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 11 Oct 2023 19:39:04 +0200 Subject: [PATCH] Expose Instance flags (#4230) Co-authored-by: Connor Fitzgerald --- CHANGELOG.md | 1 + deno_webgpu/lib.rs | 1 + examples/common/src/framework.rs | 1 + examples/timestamp-queries/src/main.rs | 1 + player/tests/test.rs | 1 + tests/src/lib.rs | 1 + tests/tests/instance.rs | 2 + wgpu-core/src/instance.rs | 7 +-- wgpu-hal/examples/halmark/main.rs | 6 +- wgpu-hal/src/auxil/dxgi/factory.rs | 4 +- wgpu-hal/src/dx12/adapter.rs | 4 +- wgpu-hal/src/dx12/instance.rs | 2 +- wgpu-hal/src/dx12/mod.rs | 4 +- wgpu-hal/src/dx12/shader_compilation.rs | 4 +- wgpu-hal/src/gles/egl.rs | 14 ++--- wgpu-hal/src/lib.rs | 13 +---- wgpu-hal/src/vulkan/adapter.rs | 2 +- wgpu-hal/src/vulkan/instance.rs | 8 +-- wgpu-hal/src/vulkan/mod.rs | 2 +- wgpu-types/src/lib.rs | 73 +++++++++++++++++++++++++ wgpu/src/lib.rs | 2 +- 21 files changed, 107 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f29283d8..d5096cddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -113,6 +113,7 @@ By @teoxoy in [#4185](https://github.com/gfx-rs/wgpu/pull/4185) - Add trace-level logging for most entry points in wgpu-core By @nical in [4183](https://github.com/gfx-rs/wgpu/pull/4183) - Add `Rgb10a2Uint` format. By @teoxoy in [4199](https://github.com/gfx-rs/wgpu/pull/4199) - Validate that resources are used on the right device. By @nical in [4207](https://github.com/gfx-rs/wgpu/pull/4207) +- Expose instance flags. By @nical in [4230](https://github.com/gfx-rs/wgpu/pull/4230) #### Vulkan diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 27ff0680c..3109164ba 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -404,6 +404,7 @@ pub async fn op_webgpu_request_adapter( wgpu_core::identity::IdentityManagerFactory, wgpu_types::InstanceDescriptor { backends, + flags: wgpu_types::InstanceFlags::from_build_config(), dx12_shader_compiler: wgpu_types::Dx12Compiler::Fxc, gles_minor_version: wgpu_types::Gles3MinorVersion::default(), }, diff --git a/examples/common/src/framework.rs b/examples/common/src/framework.rs index a897367b9..bedcc2dfe 100644 --- a/examples/common/src/framework.rs +++ b/examples/common/src/framework.rs @@ -160,6 +160,7 @@ async fn setup(title: &str) -> Setup { let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends, + flags: wgpu::InstanceFlags::from_build_config().with_env(), dx12_shader_compiler, gles_minor_version, }); diff --git a/examples/timestamp-queries/src/main.rs b/examples/timestamp-queries/src/main.rs index b3939e281..9e53a7a2e 100644 --- a/examples/timestamp-queries/src/main.rs +++ b/examples/timestamp-queries/src/main.rs @@ -179,6 +179,7 @@ async fn run() { let backends = wgpu::util::backend_bits_from_env().unwrap_or_else(wgpu::Backends::all); let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends, + flags: wgpu::InstanceFlags::from_build_config().with_env(), dx12_shader_compiler: wgpu::Dx12Compiler::default(), gles_minor_version: wgpu::Gles3MinorVersion::default(), }); diff --git a/player/tests/test.rs b/player/tests/test.rs index cd1302777..987adc266 100644 --- a/player/tests/test.rs +++ b/player/tests/test.rs @@ -184,6 +184,7 @@ impl Corpus { IdentityPassThroughFactory, wgt::InstanceDescriptor { backends: corpus.backends, + flags: wgt::InstanceFlags::debugging(), dx12_shader_compiler: wgt::Dx12Compiler::Fxc, gles_minor_version: wgt::Gles3MinorVersion::default(), }, diff --git a/tests/src/lib.rs b/tests/src/lib.rs index c50612670..6887e392f 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -517,6 +517,7 @@ pub fn initialize_instance() -> Instance { let gles_minor_version = wgpu::util::gles_minor_version_from_env().unwrap_or_default(); Instance::new(wgpu::InstanceDescriptor { backends, + flags: wgpu::InstanceFlags::debugging().with_env(), dx12_shader_compiler, gles_minor_version, }) diff --git a/tests/tests/instance.rs b/tests/tests/instance.rs index b231e8d87..bd2045298 100644 --- a/tests/tests/instance.rs +++ b/tests/tests/instance.rs @@ -5,6 +5,7 @@ use wasm_bindgen_test::*; fn initialize() { let _ = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::util::backend_bits_from_env().unwrap_or_else(wgpu::Backends::all), + flags: wgpu::InstanceFlags::debugging().with_env(), dx12_shader_compiler: wgpu::util::dx12_shader_compiler_from_env().unwrap_or_default(), gles_minor_version: wgpu::util::gles_minor_version_from_env().unwrap_or_default(), }); @@ -13,6 +14,7 @@ fn initialize() { fn request_adapter_inner(power: wgt::PowerPreference) { let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::util::backend_bits_from_env().unwrap_or_else(wgpu::Backends::all), + flags: wgpu::InstanceFlags::debugging().with_env(), dx12_shader_compiler: wgpu::util::dx12_shader_compiler_from_env().unwrap_or_default(), gles_minor_version: wgpu::util::gles_minor_version_from_env().unwrap_or_default(), }); diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 374ea1a15..4ce84eb90 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -73,14 +73,9 @@ impl Instance { pub fn new(name: &str, instance_desc: wgt::InstanceDescriptor) -> Self { fn init(_: A, instance_desc: &wgt::InstanceDescriptor) -> Option { if instance_desc.backends.contains(A::VARIANT.into()) { - let mut flags = hal::InstanceFlags::empty(); - if cfg!(debug_assertions) { - flags |= hal::InstanceFlags::VALIDATION; - flags |= hal::InstanceFlags::DEBUG; - } let hal_desc = hal::InstanceDescriptor { name: "wgpu", - flags, + flags: instance_desc.flags, dx12_shader_compiler: instance_desc.dx12_shader_compiler.clone(), gles_minor_version: instance_desc.gles_minor_version, }; diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 5518cdaf4..b751a85e9 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -89,11 +89,7 @@ impl Example { fn init(window: &winit::window::Window) -> Result> { let instance_desc = hal::InstanceDescriptor { name: "example", - flags: if cfg!(debug_assertions) { - hal::InstanceFlags::all() - } else { - hal::InstanceFlags::empty() - }, + flags: wgt::InstanceFlags::from_build_config().with_env(), // Can't rely on having DXC available, so use FXC instead dx12_shader_compiler: wgt::Dx12Compiler::Fxc, gles_minor_version: wgt::Gles3MinorVersion::default(), diff --git a/wgpu-hal/src/auxil/dxgi/factory.rs b/wgpu-hal/src/auxil/dxgi/factory.rs index 7ae6e745f..1e0847d2c 100644 --- a/wgpu-hal/src/auxil/dxgi/factory.rs +++ b/wgpu-hal/src/auxil/dxgi/factory.rs @@ -94,7 +94,7 @@ pub fn enumerate_adapters(factory: d3d12::DxgiFactory) -> Vec Result<(d3d12::DxgiLib, d3d12::DxgiFactory), crate::InstanceError> { let lib_dxgi = d3d12::DxgiLib::new().map_err(|e| { crate::InstanceError::with_source(String::from("failed to load dxgi.dll"), e) @@ -102,7 +102,7 @@ pub fn create_factory( let mut factory_flags = d3d12::FactoryCreationFlags::empty(); - if instance_flags.contains(crate::InstanceFlags::VALIDATION) { + if instance_flags.contains(wgt::InstanceFlags::VALIDATION) { // The `DXGI_CREATE_FACTORY_DEBUG` flag is only allowed to be passed to // `CreateDXGIFactory2` if the debug interface is actually available. So // we check for whether it exists first. diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 269dcd267..e59de6878 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -15,7 +15,7 @@ impl Drop for super::Adapter { && self .private_caps .instance_flags - .contains(crate::InstanceFlags::VALIDATION) + .contains(wgt::InstanceFlags::VALIDATION) { unsafe { self.report_live_objects(); @@ -47,7 +47,7 @@ impl super::Adapter { pub(super) fn expose( adapter: d3d12::DxgiAdapter, library: &Arc, - instance_flags: crate::InstanceFlags, + instance_flags: wgt::InstanceFlags, dx12_shader_compiler: &wgt::Dx12Compiler, ) -> Option> { // Create the device so that we can get the capabilities. diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 32d6f1690..5476eb141 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -16,7 +16,7 @@ impl crate::Instance for super::Instance { crate::InstanceError::with_source(String::from("failed to load d3d12.dll"), e) })?; - if desc.flags.contains(crate::InstanceFlags::VALIDATION) { + if desc.flags.contains(wgt::InstanceFlags::VALIDATION) { // Enable debug layer match lib_main.get_debug_interface() { Ok(pair) => match pair.into_result() { diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 4568ca34d..6563b2249 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -94,7 +94,7 @@ pub struct Instance { library: Arc, supports_allow_tearing: bool, _lib_dxgi: d3d12::DxgiLib, - flags: crate::InstanceFlags, + flags: wgt::InstanceFlags, dx12_shader_compiler: wgt::Dx12Compiler, } @@ -185,7 +185,7 @@ enum MemoryArchitecture { #[derive(Debug, Clone, Copy)] struct PrivateCapabilities { - instance_flags: crate::InstanceFlags, + instance_flags: wgt::InstanceFlags, #[allow(unused)] heterogeneous_resource_heaps: bool, memory_architecture: MemoryArchitecture, diff --git a/wgpu-hal/src/dx12/shader_compilation.rs b/wgpu-hal/src/dx12/shader_compilation.rs index 55a8f595d..8dd62303f 100644 --- a/wgpu-hal/src/dx12/shader_compilation.rs +++ b/wgpu-hal/src/dx12/shader_compilation.rs @@ -28,7 +28,7 @@ pub(super) fn compile_fxc( if device .private_caps .instance_flags - .contains(crate::InstanceFlags::DEBUG) + .contains(wgt::InstanceFlags::DEBUG) { compile_flags |= d3dcompiler::D3DCOMPILE_DEBUG | d3dcompiler::D3DCOMPILE_SKIP_OPTIMIZATION; } @@ -148,7 +148,7 @@ mod dxc { if device .private_caps .instance_flags - .contains(crate::InstanceFlags::DEBUG) + .contains(wgt::InstanceFlags::DEBUG) { compile_flags.push("-Zi"); // d3dcompiler::D3DCOMPILE_SKIP_OPTIMIZATION compile_flags.push("-Od"); // d3dcompiler::D3DCOMPILE_DEBUG diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index 5d153cc78..d65ac18a6 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -493,7 +493,7 @@ struct Inner { impl Inner { fn create( - flags: crate::InstanceFlags, + flags: wgt::InstanceFlags, egl: Arc, display: khronos_egl::Display, force_gles_minor_version: wgt::Gles3MinorVersion, @@ -567,7 +567,7 @@ impl Inner { }); } - if flags.contains(crate::InstanceFlags::DEBUG) { + if flags.contains(wgt::InstanceFlags::DEBUG) { if version >= (1, 5) { log::info!("\tEGL context: +debug"); context_attributes.push(khronos_egl::CONTEXT_OPENGL_DEBUG); @@ -689,7 +689,7 @@ struct WindowSystemInterface { pub struct Instance { wsi: WindowSystemInterface, - flags: crate::InstanceFlags, + flags: wgt::InstanceFlags, inner: Mutex, } @@ -817,7 +817,7 @@ impl crate::Instance for Instance { EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE as khronos_egl::Attrib, EGL_PLATFORM_X11_KHR as khronos_egl::Attrib, EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED as khronos_egl::Attrib, - usize::from(desc.flags.contains(crate::InstanceFlags::VALIDATION)), + usize::from(desc.flags.contains(wgt::InstanceFlags::VALIDATION)), khronos_egl::ATTRIB_NONE, ]; let display = unsafe { @@ -848,7 +848,7 @@ impl crate::Instance for Instance { (display, None, WindowKind::Unknown) }; - if desc.flags.contains(crate::InstanceFlags::VALIDATION) + if desc.flags.contains(wgt::InstanceFlags::VALIDATION) && client_ext_str.contains("EGL_KHR_debug") { log::info!("Enabling EGL debug output"); @@ -1005,13 +1005,13 @@ impl crate::Instance for Instance { }) }; - if self.flags.contains(crate::InstanceFlags::DEBUG) && gl.supports_debug() { + if self.flags.contains(wgt::InstanceFlags::DEBUG) && gl.supports_debug() { log::info!("Max label length: {}", unsafe { gl.get_parameter_i32(glow::MAX_LABEL_LENGTH) }); } - if self.flags.contains(crate::InstanceFlags::VALIDATION) && gl.supports_debug() { + if self.flags.contains(wgt::InstanceFlags::VALIDATION) && gl.supports_debug() { log::info!("Enabling GLES debug output"); unsafe { gl.enable(glow::DEBUG_OUTPUT) }; unsafe { gl.debug_message_callback(gl_debug_message_callback) }; diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 0b9fc4cca..5b4d0f45f 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -608,17 +608,6 @@ pub trait CommandEncoder: WasmNotSend + WasmNotSync + fmt::Debug { unsafe fn dispatch_indirect(&mut self, buffer: &A::Buffer, offset: wgt::BufferAddress); } -bitflags!( - /// Instance initialization flags. - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub struct InstanceFlags: u32 { - /// Generate debug information in shaders and objects. - const DEBUG = 1 << 0; - /// Enable validation, if possible. - const VALIDATION = 1 << 1; - } -); - bitflags!( /// Pipeline layout creation flags. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -834,7 +823,7 @@ bitflags::bitflags! { #[derive(Clone, Debug)] pub struct InstanceDescriptor<'a> { pub name: &'a str, - pub flags: InstanceFlags, + pub flags: wgt::InstanceFlags, pub dx12_shader_compiler: wgt::Dx12Compiler, pub gles_minor_version: wgt::Gles3MinorVersion, } diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 298677702..2224dbcc2 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1267,7 +1267,7 @@ impl super::Adapter { let mut flags = spv::WriterFlags::empty(); flags.set( spv::WriterFlags::DEBUG, - self.instance.flags.contains(crate::InstanceFlags::DEBUG), + self.instance.flags.contains(wgt::InstanceFlags::DEBUG), ); flags.set( spv::WriterFlags::LABEL_VARYINGS, diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 2dda7a2c3..05218ba07 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -207,7 +207,7 @@ impl super::Instance { pub fn desired_extensions( entry: &ash::Entry, _driver_api_version: u32, - flags: crate::InstanceFlags, + flags: wgt::InstanceFlags, ) -> Result, crate::InstanceError> { let instance_extensions = entry .enumerate_instance_extension_properties(None) @@ -251,7 +251,7 @@ impl super::Instance { extensions.push(ash::vk::KhrPortabilityEnumerationFn::name()); } - if flags.contains(crate::InstanceFlags::DEBUG) { + if flags.contains(wgt::InstanceFlags::DEBUG) { // VK_EXT_debug_utils extensions.push(ext::DebugUtils::name()); } @@ -297,7 +297,7 @@ impl super::Instance { android_sdk_version: u32, debug_utils_user_data: Option, extensions: Vec<&'static CStr>, - flags: crate::InstanceFlags, + flags: wgt::InstanceFlags, has_nv_optimus: bool, drop_guard: Option, ) -> Result { @@ -639,7 +639,7 @@ impl crate::Instance for super::Instance { // Request validation layer if asked. let mut debug_callback_user_data = None; - if desc.flags.contains(crate::InstanceFlags::VALIDATION) { + if desc.flags.contains(wgt::InstanceFlags::VALIDATION) { let validation_layer_name = CStr::from_bytes_with_nul(b"VK_LAYER_KHRONOS_validation\0").unwrap(); if let Some(layer_properties) = find_layer(&instance_layers, validation_layer_name) { diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 9f13b12d6..e08e27d48 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -106,7 +106,7 @@ pub struct InstanceShared { raw: ash::Instance, extensions: Vec<&'static CStr>, drop_guard: Option, - flags: crate::InstanceFlags, + flags: wgt::InstanceFlags, debug_utils: Option, get_physical_device_properties: Option, entry: ash::Entry, diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 3352e58ef..c525d73de 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -818,6 +818,76 @@ impl Features { } } +bitflags::bitflags! { + /// Instance debugging flags. + /// + /// These are not part of the webgpu standard. + /// + /// Defaults to enabling debugging-related flags if the build configuration has `debug_assertions`. + #[repr(transparent)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub struct InstanceFlags: u32 { + /// Generate debug information in shaders and objects. + const DEBUG = 1 << 0; + /// Enable validation, if possible. + const VALIDATION = 1 << 1; + } +} + +impl Default for InstanceFlags { + fn default() -> Self { + Self::from_build_config() + } +} + +impl InstanceFlags { + /// Enable debugging and validation flags. + pub fn debugging() -> Self { + InstanceFlags::DEBUG | InstanceFlags::VALIDATION + } + + /// Infer good defaults from the build type + /// + /// Returns the default flags and add debugging flags if the build configuration has `debug_assertions`. + pub fn from_build_config() -> Self { + if cfg!(debug_assertions) { + return InstanceFlags::debugging(); + } + + InstanceFlags::empty() + } + + /// Returns this set of flags, affected by environment variables. + /// + /// The presence of an environment variable implies that the corresponding flag should be set + /// unless the value is "0" in which case the flag is unset. If the environment variable is + /// not present, then the flag is unaffected. + /// + /// For example `let flags = InstanceFlags::debugging().with_env();` with `WGPU_VALIDATION=0` + /// does not contain `InstanceFlags::VALIDATION`. + /// + /// The environment variables are named after the flags prefixed with "WGPU_". For example: + /// - WGPU_DEBUG + /// - WGPU_VALIDATION + pub fn with_env(mut self) -> Self { + fn env(key: &str) -> Option { + std::env::var(key).ok().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); + } + + self + } +} + /// Represents the sets of limits an adapter/device supports. /// /// We provide three different defaults. @@ -6496,6 +6566,8 @@ pub enum Gles3MinorVersion { pub struct InstanceDescriptor { /// Which `Backends` to enable. pub backends: Backends, + /// Flags to tune the behavior of the instance. + pub flags: InstanceFlags, /// Which DX12 shader compiler to use. pub dx12_shader_compiler: Dx12Compiler, /// Which OpenGL ES 3 minor version to request. @@ -6506,6 +6578,7 @@ impl Default for InstanceDescriptor { fn default() -> Self { Self { backends: Backends::all(), + flags: InstanceFlags::default(), dx12_shader_compiler: Dx12Compiler::default(), gles_minor_version: Gles3MinorVersion::default(), } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 0e6037e49..4c499254d 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -34,7 +34,7 @@ pub use wgt::{ CommandBufferDescriptor, CompareFunction, CompositeAlphaMode, DepthBiasState, DepthStencilState, DeviceType, DownlevelCapabilities, DownlevelFlags, Dx12Compiler, DynamicOffset, Extent3d, Face, Features, FilterMode, FrontFace, Gles3MinorVersion, - ImageDataLayout, ImageSubresourceRange, IndexFormat, InstanceDescriptor, Limits, + ImageDataLayout, ImageSubresourceRange, IndexFormat, InstanceDescriptor, InstanceFlags, Limits, MultisampleState, Origin2d, Origin3d, PipelineStatisticsTypes, PolygonMode, PowerPreference, PredefinedColorSpace, PresentMode, PresentationTimestamp, PrimitiveState, PrimitiveTopology, PushConstantRange, QueryType, RenderBundleDepthStencil, SamplerBindingType, SamplerBorderColor,