summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wgpu-hal/src/gles
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wgpu-hal/src/gles')
-rw-r--r--third_party/rust/wgpu-hal/src/gles/adapter.rs33
-rw-r--r--third_party/rust/wgpu-hal/src/gles/conv.rs1
-rw-r--r--third_party/rust/wgpu-hal/src/gles/device.rs37
-rw-r--r--third_party/rust/wgpu-hal/src/gles/egl.rs74
-rw-r--r--third_party/rust/wgpu-hal/src/gles/mod.rs1
-rw-r--r--third_party/rust/wgpu-hal/src/gles/queue.rs71
-rw-r--r--third_party/rust/wgpu-hal/src/gles/wgl.rs2
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) };
}