iris: stop requesting compute-shader limits nothing uses

adapter.request_device asked for Limits::default(), which requests
desktop-tier compute-shader limits unconditionally even though nothing in
iris/iris-core creates a ComputePipeline or writes a @compute stage. That
crashed device creation outright on a downlevel GL adapter reporting
OpenGL ES 3.0 (no compute at all) -- the Android emulator's
EMU_GPU=software/force-gles path, and any real GLES-3.0-only device.

New iris_core::device_limits(), shared by both platform backends, zeros
exactly the six max_compute_* fields rather than switching to a downlevel
Limits preset -- downlevel_webgl2_defaults() also zeros
max_storage_buffers_per_shader_stage, which shader.wgsl's vertex stage
needs. rigs/gpu-probe's own mirrored limits were updated to match.

Not verified against the actual SwiftShader-ES-3.0 crash on-device this
pass: the cold boot needed would have force-restarted this checkout's
emulator while another session had its own app running on it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Fable 5.1 committed 2026-09-05 21:18:30 -04:00
1 parent e6924298bc
commit d01c105037
8 files changed
+222 -13

No files matched your search

+29 -4
View File
@@ -35,6 +35,34 @@ fn iris_features() -> Features {
/// kept for the big storage buffers behind rects/glyphs.
const IRIS_MAX_BUFFER_SIZE: u64 = 1 << 30;
/// Mirrors `iris_core::device_limits()` (`iris/core/src/render/mod.rs`) --
/// cannot call it directly, since this rig is deliberately its own crate,
/// not a workspace member (this file's own Cargo.toml comment). Keep the
/// two in sync by hand when one changes; this rig's whole purpose is "does
/// the device iris actually builds come back," so a stale copy here would
/// silently stop answering that question. Zeroed rather than left at
/// `Limits::default()`'s desktop-tier values because nothing in iris
/// creates a `ComputePipeline` or a `@compute` shader stage -- found by
/// grepping the whole `iris`/`iris-core` tree before this rig's comment was
/// written -- and the unconditional default request is what crashed
/// `request_device` on the Android emulator's software GL path
/// (`EMU_GPU=software`, `force-gles`: SwiftShader's GL reports itself as
/// OpenGL ES 3.0, which has no compute shaders at all, so the adapter's
/// real limit is 0). The same would happen on a real GLES-3.0-only Android
/// device.
fn iris_limits() -> Limits {
Limits {
max_buffer_size: IRIS_MAX_BUFFER_SIZE,
max_compute_workgroup_storage_size: 0,
max_compute_invocations_per_workgroup: 0,
max_compute_workgroup_size_x: 0,
max_compute_workgroup_size_y: 0,
max_compute_workgroup_size_z: 0,
max_compute_workgroups_per_dimension: 0,
..Default::default()
}
}
fn main() {
vk::report();
@@ -104,10 +132,7 @@ fn main() {
// limits requested, this is expected to succeed everywhere -- this rig
// is what turned that from an assumption into a measurement, first on
// this emulator's software Vulkan.
let wanted = Limits {
max_buffer_size: IRIS_MAX_BUFFER_SIZE,
..Default::default()
};
let wanted = iris_limits();
match pollster::block_on(adapter.request_device(&DeviceDescriptor {
required_features: iris_features(),
required_limits: wanted,