diff --git a/CHANGELOG.md b/CHANGELOG.md index 8514eb4c52..635fde6f58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,10 +64,15 @@ let render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { By @Valaphee in [#3402](https://github.com/gfx-rs/wgpu/pull/3402) +### Added/New Features + +- Add `gles_minor_version` field to `wgpu::InstanceDescriptor`. By @PJB3005 in [#3998](https://github.com/gfx-rs/wgpu/pull/3998) + ### Changes - Omit texture store bound checks since they are no-ops if out of bounds on all APIs. By @teoxoy in [#3975](https://github.com/gfx-rs/wgpu/pull/3975) + ### Bug Fixes #### General diff --git a/README.md b/README.md index c2b62daf93..dfdb3a5a8e 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ All testing and example infrastructure shares the same set of environment variab - `WGPU_BACKEND` with a comma separated list of the backends you want to use (`vulkan`, `metal`, `dx12`, `dx11`, or `gl`). - `WGPU_POWER_PREF` with the power preference to choose when a specific adapter name isn't specified (`high` or `low`) - `WGPU_DX12_COMPILER` with the DX12 shader compiler you wish to use (`dxc` or `fxc`, note that `dxc` requires `dxil.dll` and `dxcompiler.dll` to be in the working directory otherwise it will fall back to `fxc`) +- `WGPU_GLES_MINOR_VERSION` with the minor OpenGL ES 3 version number to request (`0`, `1`, `2` or `automatic`). When running the CTS, use the variables `DENO_WEBGPU_ADAPTER_NAME`, `DENO_WEBGPU_BACKEND`, `DENO_WEBGPU_POWER_PREFERENCE`. diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index f475723682..92a6a51334 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -406,6 +406,7 @@ pub async fn op_webgpu_request_adapter( wgpu_types::InstanceDescriptor { backends, dx12_shader_compiler: wgpu_types::Dx12Compiler::Fxc, + gles_minor_version: wgpu_types::Gles3MinorVersion::default(), }, ))); state.borrow::() diff --git a/examples/capture/src/main.rs b/examples/capture/src/main.rs index 5990f76587..452da530a9 100644 --- a/examples/capture/src/main.rs +++ b/examples/capture/src/main.rs @@ -40,6 +40,7 @@ async fn create_red_image_with_dimensions( let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends, dx12_shader_compiler: wgpu::Dx12Compiler::default(), + gles_minor_version: wgpu::Gles3MinorVersion::default(), }); let adapter = instance .request_adapter(&wgpu::RequestAdapterOptions::default()) diff --git a/examples/common/src/framework.rs b/examples/common/src/framework.rs index f26e136d81..06db6092f7 100644 --- a/examples/common/src/framework.rs +++ b/examples/common/src/framework.rs @@ -155,10 +155,12 @@ async fn setup(title: &str) -> Setup { let backends = wgpu::util::backend_bits_from_env().unwrap_or_else(wgpu::Backends::all); let dx12_shader_compiler = wgpu::util::dx12_shader_compiler_from_env().unwrap_or_default(); + let gles_minor_version = wgpu::util::gles_minor_version_from_env().unwrap_or_default(); let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends, dx12_shader_compiler, + gles_minor_version, }); let (size, surface) = unsafe { let size = window.inner_size(); diff --git a/examples/timestamp-queries/src/main.rs b/examples/timestamp-queries/src/main.rs index b28926c027..3479122c79 100644 --- a/examples/timestamp-queries/src/main.rs +++ b/examples/timestamp-queries/src/main.rs @@ -179,6 +179,7 @@ async fn run() { let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends, dx12_shader_compiler: wgpu::Dx12Compiler::default(), + gles_minor_version: wgpu::Gles3MinorVersion::default(), }); // `request_adapter` instantiates the general connection to the GPU diff --git a/player/tests/test.rs b/player/tests/test.rs index bbaa66cc4e..cd1302777e 100644 --- a/player/tests/test.rs +++ b/player/tests/test.rs @@ -185,6 +185,7 @@ impl Corpus { wgt::InstanceDescriptor { backends: corpus.backends, dx12_shader_compiler: wgt::Dx12Compiler::Fxc, + gles_minor_version: wgt::Gles3MinorVersion::default(), }, ); for &backend in BACKENDS { diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 949afb48a0..fb57d2a5a8 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -348,9 +348,11 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te fn initialize_adapter() -> (Adapter, SurfaceGuard) { let backends = wgpu::util::backend_bits_from_env().unwrap_or_else(Backends::all); let dx12_shader_compiler = wgpu::util::dx12_shader_compiler_from_env().unwrap_or_default(); + let gles_minor_version = wgpu::util::gles_minor_version_from_env().unwrap_or_default(); let instance = Instance::new(wgpu::InstanceDescriptor { backends, dx12_shader_compiler, + gles_minor_version, }); let surface_guard; let compatible_surface; diff --git a/tests/tests/instance.rs b/tests/tests/instance.rs index e9ff6afff0..b231e8d879 100644 --- a/tests/tests/instance.rs +++ b/tests/tests/instance.rs @@ -6,6 +6,7 @@ fn initialize() { let _ = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::util::backend_bits_from_env().unwrap_or_else(wgpu::Backends::all), 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 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), 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(), }); let _adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index cf28777dc6..ae1a395d85 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -82,6 +82,7 @@ impl Instance { name: "wgpu", flags, dx12_shader_compiler: instance_desc.dx12_shader_compiler.clone(), + gles_minor_version: instance_desc.gles_minor_version, }; unsafe { hal::Instance::init(&hal_desc).ok() } } else { diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 21289b18e5..c6b739bf17 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -96,6 +96,7 @@ impl Example { }, // Can't rely on having DXC available, so use FXC instead dx12_shader_compiler: wgt::Dx12Compiler::Fxc, + gles_minor_version: wgt::Gles3MinorVersion::default(), }; let instance = unsafe { A::Instance::init(&instance_desc)? }; let mut surface = unsafe { diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index 0c8e754971..b904dffee9 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -482,6 +482,8 @@ struct Inner { config: khronos_egl::Config, #[cfg_attr(target_os = "emscripten", allow(dead_code))] wl_display: Option<*mut raw::c_void>, + #[cfg_attr(target_os = "emscripten", allow(dead_code))] + force_gles_minor_version: wgt::Gles3MinorVersion, /// Method by which the framebuffer should support srgb srgb_kind: SrgbFrameBufferKind, } @@ -491,6 +493,7 @@ impl Inner { flags: crate::InstanceFlags, egl: Arc, display: khronos_egl::Display, + force_gles_minor_version: wgt::Gles3MinorVersion, ) -> Result { let version = egl.initialize(display).map_err(|_| crate::InstanceError)?; let vendor = egl @@ -542,9 +545,20 @@ impl Inner { //TODO: make it so `Device` == EGL Context let mut context_attributes = vec![ - khronos_egl::CONTEXT_CLIENT_VERSION, + khronos_egl::CONTEXT_MAJOR_VERSION, 3, // Request GLES 3.0 or higher ]; + + if force_gles_minor_version != wgt::Gles3MinorVersion::Automatic { + context_attributes.push(khronos_egl::CONTEXT_MINOR_VERSION); + context_attributes.push(match force_gles_minor_version { + wgt::Gles3MinorVersion::Version0 => 0, + wgt::Gles3MinorVersion::Version1 => 1, + wgt::Gles3MinorVersion::Version2 => 2, + _ => unreachable!(), + }); + } + if flags.contains(crate::InstanceFlags::DEBUG) { if version >= (1, 5) { log::info!("\tEGL context: +debug"); @@ -627,6 +641,7 @@ impl Inner { config, wl_display: None, srgb_kind, + force_gles_minor_version, }) } } @@ -836,7 +851,7 @@ impl crate::Instance for Instance { unsafe { (function)(Some(egl_debug_proc), attributes.as_ptr()) }; } - let inner = Inner::create(desc.flags, egl, display)?; + let inner = Inner::create(desc.flags, egl, display, desc.gles_minor_version)?; Ok(Instance { wsi: WindowSystemInterface { @@ -918,9 +933,13 @@ impl crate::Instance for Instance { ) .unwrap(); - let new_inner = - Inner::create(self.flags, Arc::clone(&inner.egl.instance), display) - .map_err(|_| crate::InstanceError)?; + let new_inner = Inner::create( + self.flags, + Arc::clone(&inner.egl.instance), + display, + inner.force_gles_minor_version, + ) + .map_err(|_| crate::InstanceError)?; let old_inner = std::mem::replace(inner.deref_mut(), new_inner); inner.wl_display = Some(display_handle.display); diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 1248ee9030..020c665709 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -787,6 +787,7 @@ pub struct InstanceDescriptor<'a> { pub name: &'a str, pub flags: InstanceFlags, pub dx12_shader_compiler: wgt::Dx12Compiler, + pub gles_minor_version: wgt::Gles3MinorVersion, } #[derive(Clone, Debug)] diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index a3dc1906c6..1b8e5553a5 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6400,12 +6400,33 @@ pub enum Dx12Compiler { }, } +/// 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. +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)] +pub enum Gles3MinorVersion { + /// No explicit minor version is requested, the driver automatically picks the highest available. + #[default] + Automatic, + + /// Request an ES 3.0 context. + Version0, + + /// Request an ES 3.1 context. + Version1, + + /// Request an ES 3.2 context. + Version2, +} + /// Options for creating an instance. pub struct InstanceDescriptor { /// Which `Backends` to enable. pub backends: Backends, /// Which DX12 shader compiler to use. pub dx12_shader_compiler: Dx12Compiler, + /// Which OpenGL ES 3 minor version to request. + pub gles_minor_version: Gles3MinorVersion, } impl Default for InstanceDescriptor { @@ -6413,6 +6434,7 @@ impl Default for InstanceDescriptor { Self { backends: Backends::all(), dx12_shader_compiler: Dx12Compiler::default(), + gles_minor_version: Gles3MinorVersion::default(), } } } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 7674bcb69a..8d55bc0c2c 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -34,12 +34,12 @@ pub use wgt::{ BufferBindingType, BufferSize, BufferUsages, Color, ColorTargetState, ColorWrites, CommandBufferDescriptor, CompareFunction, CompositeAlphaMode, DepthBiasState, DepthStencilState, DeviceType, DownlevelCapabilities, DownlevelFlags, Dx12Compiler, - DynamicOffset, Extent3d, Face, Features, FilterMode, FrontFace, ImageDataLayout, - ImageSubresourceRange, IndexFormat, InstanceDescriptor, Limits, MultisampleState, Origin2d, - Origin3d, PipelineStatisticsTypes, PolygonMode, PowerPreference, PredefinedColorSpace, - PresentMode, PresentationTimestamp, PrimitiveState, PrimitiveTopology, PushConstantRange, - QueryType, RenderBundleDepthStencil, SamplerBindingType, SamplerBorderColor, ShaderLocation, - ShaderModel, ShaderStages, StencilFaceState, StencilOperation, StencilState, + DynamicOffset, Extent3d, Face, Features, FilterMode, FrontFace, Gles3MinorVersion, + ImageDataLayout, ImageSubresourceRange, IndexFormat, InstanceDescriptor, Limits, + MultisampleState, Origin2d, Origin3d, PipelineStatisticsTypes, PolygonMode, PowerPreference, + PredefinedColorSpace, PresentMode, PresentationTimestamp, PrimitiveState, PrimitiveTopology, + PushConstantRange, QueryType, RenderBundleDepthStencil, SamplerBindingType, SamplerBorderColor, + ShaderLocation, ShaderModel, ShaderStages, StencilFaceState, StencilOperation, StencilState, StorageTextureAccess, SurfaceCapabilities, SurfaceStatus, TextureAspect, TextureDimension, TextureFormat, TextureFormatFeatureFlags, TextureFormatFeatures, TextureSampleType, TextureUsages, TextureViewDimension, VertexAttribute, VertexFormat, VertexStepMode, diff --git a/wgpu/src/util/init.rs b/wgpu/src/util/init.rs index 9d186b685a..484bae611b 100644 --- a/wgpu/src/util/init.rs +++ b/wgpu/src/util/init.rs @@ -114,3 +114,22 @@ pub fn dx12_shader_compiler_from_env() -> Option { }, ) } + +/// Choose which minor OpenGL ES version to use from the environment variable `WGPU_GLES_MINOR_VERSION`. +/// +/// Possible values are `0`, `1`, `2` or `automatic`. Case insensitive. +pub fn gles_minor_version_from_env() -> Option { + Some( + match std::env::var("WGPU_GLES_MINOR_VERSION") + .as_deref() + .map(str::to_lowercase) + .as_deref() + { + Ok("automatic") => wgt::Gles3MinorVersion::Automatic, + Ok("0") => wgt::Gles3MinorVersion::Version0, + Ok("1") => wgt::Gles3MinorVersion::Version1, + Ok("2") => wgt::Gles3MinorVersion::Version2, + _ => return None, + }, + ) +}