From b33f539957ede2964c7de8c1f77b4c2530513054 Mon Sep 17 00:00:00 2001 From: Hesperus Date: Thu, 27 Aug 2026 02:46:02 -0700 Subject: [PATCH] Web shell: don't self-clamp maxStorageBuffersPerShaderStage to the WebGPU default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WebGPU shell's wantedLimits hardcoded maxStorageBuffersPerShaderStage at 8 — exactly the WebGPU default — so Math.min(wanted, adapter) could never grant more even on adapters offering 16+. The Mobile renderer's scene shader binds 10 storage buffers in the vertex stage, so every lit 3D scene failed CreatePipelineLayout with a GPUValidationError naming this limit, and rendered black. (Unshaded scenes stay under the limit, which is why the samples that render are the unshaded ones.) Request the adapter's own maximum for this limit instead, matching the policy the engine.js device path already uses. Measured on Windows/Dawn (adapter max 16): the pipeline-layout errors disappear and all Mobile scene pipelines create cleanly. Note this does not yet produce lit pixels: with the limit fixed and zero remaining validation errors, the Mobile lit path still renders black (verified against an unshaded control at luma 35 through the same harness, under both directional and pure-ambient lighting). The limit clamp was the first, self-inflicted blocker; a second, silent one remains and is now cleanly reproducible. Co-Authored-By: Claude Fable 5 --- misc/dist/html/webgpu-full-size.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/misc/dist/html/webgpu-full-size.html b/misc/dist/html/webgpu-full-size.html index e257d44d7c5cc..aa18f0162a3ca 100644 --- a/misc/dist/html/webgpu-full-size.html +++ b/misc/dist/html/webgpu-full-size.html @@ -167,7 +167,12 @@ maxDynamicStorageBuffersPerPipelineLayout: 4, maxSampledTexturesPerShaderStage: 16, maxSamplersPerShaderStage: 16, - maxStorageBuffersPerShaderStage: 8, + // The Mobile renderer's scene shader binds 10 storage buffers in the + // vertex stage; the WebGPU default limit is 8, so a hardcoded 8 here + // self-clamps below what the renderer needs even on adapters that + // offer more. Request the adapter's own maximum instead (same policy + // as the engine.js device path). + maxStorageBuffersPerShaderStage: adapter.limits.maxStorageBuffersPerShaderStage || 8, maxStorageTexturesPerShaderStage: 4, maxUniformBuffersPerShaderStage: 12, maxUniformBufferBindingSize: 65536,