diff options
Diffstat (limited to 'third_party/rust/wgpu-hal/src/gles')
-rw-r--r-- | third_party/rust/wgpu-hal/src/gles/adapter.rs | 33 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/gles/conv.rs | 1 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/gles/device.rs | 37 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/gles/egl.rs | 74 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/gles/mod.rs | 1 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/gles/queue.rs | 71 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/gles/wgl.rs | 2 |
7 files changed, 148 insertions, 71 deletions
diff --git a/third_party/rust/wgpu-hal/src/gles/adapter.rs b/third_party/rust/wgpu-hal/src/gles/adapter.rs index b9d044337c..052c77006b 100644 --- a/third_party/rust/wgpu-hal/src/gles/adapter.rs +++ b/third_party/rust/wgpu-hal/src/gles/adapter.rs @@ -104,7 +104,7 @@ impl super::Adapter { } } - fn make_info(vendor_orig: String, renderer_orig: String) -> wgt::AdapterInfo { + fn make_info(vendor_orig: String, renderer_orig: String, version: String) -> wgt::AdapterInfo { let vendor = vendor_orig.to_lowercase(); let renderer = renderer_orig.to_lowercase(); @@ -179,13 +179,33 @@ impl super::Adapter { 0 }; + let driver; + let driver_info; + if version.starts_with("WebGL ") || version.starts_with("OpenGL ") { + let es_sig = " ES"; + match version.find(es_sig) { + Some(pos) => { + driver = version[..pos + es_sig.len()].to_owned(); + driver_info = version[pos + es_sig.len() + 1..].to_owned(); + } + None => { + let pos = version.find(' ').unwrap(); + driver = version[..pos].to_owned(); + driver_info = version[pos + 1..].to_owned(); + } + } + } else { + driver = "OpenGL".to_owned(); + driver_info = version; + } + wgt::AdapterInfo { name: renderer_orig, vendor: vendor_id, device: 0, device_type: inferred_device_type, - driver: String::new(), - driver_info: String::new(), + driver, + driver_info, backend: wgt::Backend::Gl, } } @@ -507,8 +527,7 @@ impl super::Adapter { let has_etc = if cfg!(any(webgl, Emscripten)) { extensions.contains("WEBGL_compressed_texture_etc") } else { - // This is a required part of GLES3, but not part of Desktop GL at all. - es_ver.is_some() + es_ver.is_some() || extensions.contains("GL_ARB_ES3_compatibility") }; features.set(wgt::Features::TEXTURE_COMPRESSION_ETC2, has_etc); @@ -728,6 +747,8 @@ impl super::Adapter { } else { !0 }, + min_subgroup_size: 0, + max_subgroup_size: 0, max_push_constant_size: super::MAX_PUSH_CONSTANTS as u32 * 4, min_uniform_buffer_offset_alignment, min_storage_buffer_offset_alignment, @@ -825,7 +846,7 @@ impl super::Adapter { max_msaa_samples: max_samples, }), }, - info: Self::make_info(vendor, renderer), + info: Self::make_info(vendor, renderer, version), features, capabilities: crate::Capabilities { limits, diff --git a/third_party/rust/wgpu-hal/src/gles/conv.rs b/third_party/rust/wgpu-hal/src/gles/conv.rs index bde69b8629..a6c924f162 100644 --- a/third_party/rust/wgpu-hal/src/gles/conv.rs +++ b/third_party/rust/wgpu-hal/src/gles/conv.rs @@ -212,6 +212,7 @@ pub(super) fn describe_vertex_format(vertex_format: wgt::VertexFormat) -> super: Vf::Uint32x4 => (4, glow::UNSIGNED_INT, Vak::Integer), Vf::Sint32x4 => (4, glow::INT, Vak::Integer), Vf::Float32x4 => (4, glow::FLOAT, Vak::Float), + Vf::Unorm10_10_10_2 => (4, glow::UNSIGNED_INT_10_10_10_2, Vak::Float), Vf::Float64 | Vf::Float64x2 | Vf::Float64x3 | Vf::Float64x4 => unimplemented!(), }; diff --git a/third_party/rust/wgpu-hal/src/gles/device.rs b/third_party/rust/wgpu-hal/src/gles/device.rs index 50c07f3ff0..a1e2736aa6 100644 --- a/third_party/rust/wgpu-hal/src/gles/device.rs +++ b/third_party/rust/wgpu-hal/src/gles/device.rs @@ -220,9 +220,17 @@ impl super::Device { multiview: context.multiview, }; - let shader = &stage.module.naga; - let entry_point_index = shader - .module + let (module, info) = naga::back::pipeline_constants::process_overrides( + &stage.module.naga.module, + &stage.module.naga.info, + stage.constants, + ) + .map_err(|e| { + let msg = format!("{e}"); + crate::PipelineError::Linkage(map_naga_stage(naga_stage), msg) + })?; + + let entry_point_index = module .entry_points .iter() .position(|ep| ep.name.as_str() == stage.entry_point) @@ -247,11 +255,23 @@ impl super::Device { }; let mut output = String::new(); + let needs_temp_options = stage.zero_initialize_workgroup_memory + != context.layout.naga_options.zero_initialize_workgroup_memory; + let mut temp_options; + let naga_options = if needs_temp_options { + // We use a conditional here, as cloning the naga_options could be expensive + // That is, we want to avoid doing that unless we cannot avoid it + temp_options = context.layout.naga_options.clone(); + temp_options.zero_initialize_workgroup_memory = stage.zero_initialize_workgroup_memory; + &temp_options + } else { + &context.layout.naga_options + }; let mut writer = glsl::Writer::new( &mut output, - &shader.module, - &shader.info, - &context.layout.naga_options, + &module, + &info, + naga_options, &pipeline_options, policies, ) @@ -269,8 +289,8 @@ impl super::Device { context.consume_reflection( gl, - &shader.module, - shader.info.get_entry_point(entry_point_index), + &module, + info.get_entry_point(entry_point_index), reflection_info, naga_stage, program, @@ -297,6 +317,7 @@ impl super::Device { naga_stage: naga_stage.to_owned(), shader_id: stage.module.id, entry_point: stage.entry_point.to_owned(), + zero_initialize_workgroup_memory: stage.zero_initialize_workgroup_memory, }); } let mut guard = self diff --git a/third_party/rust/wgpu-hal/src/gles/egl.rs b/third_party/rust/wgpu-hal/src/gles/egl.rs index b166f4f102..00ef70ba88 100644 --- a/third_party/rust/wgpu-hal/src/gles/egl.rs +++ b/third_party/rust/wgpu-hal/src/gles/egl.rs @@ -526,28 +526,51 @@ impl Inner { } let (config, supports_native_window) = choose_config(&egl, display, srgb_kind)?; - egl.bind_api(khronos_egl::OPENGL_ES_API).unwrap(); + + let supports_opengl = if version >= (1, 4) { + let client_apis = egl + .query_string(Some(display), khronos_egl::CLIENT_APIS) + .unwrap() + .to_string_lossy(); + client_apis + .split(' ') + .any(|client_api| client_api == "OpenGL") + } else { + false + }; + egl.bind_api(if supports_opengl { + khronos_egl::OPENGL_API + } else { + khronos_egl::OPENGL_ES_API + }) + .unwrap(); let needs_robustness = true; let mut khr_context_flags = 0; let supports_khr_context = display_extensions.contains("EGL_KHR_create_context"); - //TODO: make it so `Device` == EGL Context - let mut context_attributes = vec![ - khronos_egl::CONTEXT_MAJOR_VERSION, - 3, // Request GLES 3.0 or higher - ]; - - if force_gles_minor_version != wgt::Gles3MinorVersion::Automatic { + let mut context_attributes = vec![]; + if supports_opengl { + context_attributes.push(khronos_egl::CONTEXT_MAJOR_VERSION); + context_attributes.push(3); 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!(), - }); + context_attributes.push(3); + if force_gles_minor_version != wgt::Gles3MinorVersion::Automatic { + log::warn!("Ignoring specified GLES minor version as OpenGL is used"); + } + } else { + context_attributes.push(khronos_egl::CONTEXT_MAJOR_VERSION); + context_attributes.push(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::Automatic => unreachable!(), + wgt::Gles3MinorVersion::Version0 => 0, + wgt::Gles3MinorVersion::Version1 => 1, + wgt::Gles3MinorVersion::Version2 => 2, + }); + } } - if flags.contains(wgt::InstanceFlags::DEBUG) { if version >= (1, 5) { log::debug!("\tEGL context: +debug"); @@ -577,8 +600,6 @@ impl Inner { // because it's for desktop GL only, not GLES. log::warn!("\tEGL context: -robust access"); } - - //TODO do we need `khronos_egl::CONTEXT_OPENGL_NOTIFICATION_STRATEGY_EXT`? } if khr_context_flags != 0 { context_attributes.push(EGL_CONTEXT_FLAGS_KHR); @@ -977,6 +998,7 @@ impl crate::Instance for Instance { srgb_kind: inner.srgb_kind, }) } + unsafe fn destroy_surface(&self, _surface: Surface) {} unsafe fn enumerate_adapters(&self) -> Vec<crate::ExposedAdapter<super::Api>> { @@ -993,6 +1015,12 @@ impl crate::Instance for Instance { }) }; + // In contrast to OpenGL ES, OpenGL requires explicitly enabling sRGB conversions, + // as otherwise the user has to do the sRGB conversion. + if !matches!(inner.srgb_kind, SrgbFrameBufferKind::None) { + unsafe { gl.enable(glow::FRAMEBUFFER_SRGB) }; + } + if self.flags.contains(wgt::InstanceFlags::DEBUG) && gl.supports_debug() { log::debug!("Max label length: {}", unsafe { gl.get_parameter_i32(glow::MAX_LABEL_LENGTH) @@ -1106,6 +1134,13 @@ impl Surface { unsafe { gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None) }; unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(sc.framebuffer)) }; + + if !matches!(self.srgb_kind, SrgbFrameBufferKind::None) { + // Disable sRGB conversions for `glBlitFramebuffer` as behavior does diverge between + // drivers and formats otherwise and we want to ensure no sRGB conversions happen. + unsafe { gl.disable(glow::FRAMEBUFFER_SRGB) }; + } + // Note the Y-flipping here. GL's presentation is not flipped, // but main rendering is. Therefore, we Y-flip the output positions // in the shader, and also this blit. @@ -1123,6 +1158,11 @@ impl Surface { glow::NEAREST, ) }; + + if !matches!(self.srgb_kind, SrgbFrameBufferKind::None) { + unsafe { gl.enable(glow::FRAMEBUFFER_SRGB) }; + } + unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None) }; self.egl diff --git a/third_party/rust/wgpu-hal/src/gles/mod.rs b/third_party/rust/wgpu-hal/src/gles/mod.rs index 6f41f7c000..0fcb09be46 100644 --- a/third_party/rust/wgpu-hal/src/gles/mod.rs +++ b/third_party/rust/wgpu-hal/src/gles/mod.rs @@ -602,6 +602,7 @@ struct ProgramStage { naga_stage: naga::ShaderStage, shader_id: ShaderId, entry_point: String, + zero_initialize_workgroup_memory: bool, } #[derive(PartialEq, Eq, Hash)] diff --git a/third_party/rust/wgpu-hal/src/gles/queue.rs b/third_party/rust/wgpu-hal/src/gles/queue.rs index 29dfb79d04..7c728d3978 100644 --- a/third_party/rust/wgpu-hal/src/gles/queue.rs +++ b/third_party/rust/wgpu-hal/src/gles/queue.rs @@ -213,12 +213,27 @@ impl super::Queue { instance_count, ref first_instance_location, } => { - match base_vertex { - 0 => { - unsafe { - gl.uniform_1_u32(first_instance_location.as_ref(), first_instance) - }; + let supports_full_instancing = self + .shared + .private_caps + .contains(PrivateCapabilities::FULLY_FEATURED_INSTANCING); + if supports_full_instancing { + unsafe { + gl.draw_elements_instanced_base_vertex_base_instance( + topology, + index_count as i32, + index_type, + index_offset as i32, + instance_count as i32, + base_vertex, + first_instance, + ) + } + } else { + unsafe { gl.uniform_1_u32(first_instance_location.as_ref(), first_instance) }; + + if base_vertex == 0 { unsafe { // Don't use `gl.draw_elements`/`gl.draw_elements_base_vertex` for `instance_count == 1`. // Angle has a bug where it doesn't consider the instance divisor when `DYNAMIC_DRAW` is used in `gl.draw_elements`/`gl.draw_elements_base_vertex`. @@ -231,41 +246,17 @@ impl super::Queue { instance_count as i32, ) } - } - _ => { - let supports_full_instancing = self - .shared - .private_caps - .contains(PrivateCapabilities::FULLY_FEATURED_INSTANCING); - - if supports_full_instancing { - unsafe { - gl.draw_elements_instanced_base_vertex_base_instance( - topology, - index_count as i32, - index_type, - index_offset as i32, - instance_count as i32, - base_vertex, - first_instance, - ) - } - } else { - unsafe { - gl.uniform_1_u32(first_instance_location.as_ref(), first_instance) - }; - - // If we've gotten here, wgpu-core has already validated that this function exists via the DownlevelFlags::BASE_VERTEX feature. - unsafe { - gl.draw_elements_instanced_base_vertex( - topology, - index_count as _, - index_type, - index_offset as i32, - instance_count as i32, - base_vertex, - ) - } + } else { + // If we've gotten here, wgpu-core has already validated that this function exists via the DownlevelFlags::BASE_VERTEX feature. + unsafe { + gl.draw_elements_instanced_base_vertex( + topology, + index_count as _, + index_type, + index_offset as i32, + instance_count as i32, + base_vertex, + ) } } } diff --git a/third_party/rust/wgpu-hal/src/gles/wgl.rs b/third_party/rust/wgpu-hal/src/gles/wgl.rs index 2564892969..aae70478b4 100644 --- a/third_party/rust/wgpu-hal/src/gles/wgl.rs +++ b/third_party/rust/wgpu-hal/src/gles/wgl.rs @@ -507,6 +507,8 @@ impl crate::Instance for Instance { .supported_extensions() .contains("GL_ARB_framebuffer_sRGB"); + // In contrast to OpenGL ES, OpenGL requires explicitly enabling sRGB conversions, + // as otherwise the user has to do the sRGB conversion. if srgb_capable { unsafe { gl.enable(glow::FRAMEBUFFER_SRGB) }; } |