From: marfrit-packages noether Subject: [PATCH] panvk-bifrost: bump maxImageDimension3D to 2048 (unblock Dawn/WebGPU) iter22 / r9 — surfaced by panvk-bifrost-perf-measurement iter1 spike (2026-05-25). Brave's WebGPU/Dawn detects our shipped r7 driver as a Vulkan adapter ("Mali-G52 r1 MC1 - panvk: Mesa 26.0.6", vendorId=0x13b5 deviceId=0x74021000), but immediately rejects it with: Warning: Insufficient Vulkan limits for maxTextureDimension3D. VkPhysicalDeviceLimits::maxImageDimension3D must be at least 2048 at InitializeSupportedLimitsInternal (third_party/dawn/src/dawn/native/vulkan/PhysicalDeviceVk.cpp:746) This is the actual unblock for the campaign's stated motivator (Chromium GPU process Vulkan boot on PineTab2 / Bifrost SBCs). ## Hunk 1 — bump the advertised basic limit Was: `.maxImageDimension3D = PAN_ARCH <= 10 ? (1 << 9) : (1 << 14);` (PAN_ARCH 7 advertised 512 — below WebGPU's 2048 minimum.) Now: bumped to (1 << 11) = 2048 on PAN_ARCH 7..10. Per Vulkan 1.3 spec §43.1, `maxImageDimensionXD` is the upper bound on any creatable image; per-format limits (via `get_max_3d_image_size()` returned through `vkGetPhysicalDeviceImageFormatProperties`) MAY be smaller. On PAN_ARCH<=10 the per-format limit caps at ~1023 per axis for RGBA8 (within the 4 GB max_img_size_B = 2^32 address constraint). Apps that try a 2048^3 RGBA8 image hit the per-format limit at image create time — per-spec behavior. Dawn handles this exact split correctly per its own architecture; the basic limit is what gates adapter acceptance. ## Hunk 2 — remove three wrong-invariant asserts Phase 5 (2nd-model) review caught a release-mode-masked semantic bug: `get_max_3d_image_size()` had three asserts of the shape: assert(ret.width >= phys_dev->vk.properties.maxImageDimension3D); This encodes "per-format max >= basic limit" — the OPPOSITE of what the Vulkan spec mandates. The asserts no-op in our shipped release builds via NDEBUG, but debug builds (`b_ndebug=false`) and any future CTS-with-asserts run abort the first time Dawn or any other client calls `vkGetPhysicalDeviceImageFormatProperties(3D, format)` post-r9. Removing the asserts fixes the latent semantic violation. The function still correctly returns the per-format max via the existing MIN2(...) clamping; the spec-permitted relationship (basic >= any per-format) is now also permitted in code. ## Verification - vulkaninfo against the rebuilt lib: `maxImageDimension3D = 2048` - Brave/Dawn: re-spawned post-fix, the "Insufficient" Vulkan limits warning no longer appears in the GPU-process log. Adapter is accepted for WebGPU. - CTS regression: `dEQP-VK.api.copy_and_blit.core.image_to_image.3d_images.*` 6/6 Pass (unchanged from baseline). ## Phase 5 review APPROVE WITH CHANGES (non-blocking for release ship; blocking for downstream tree because of the assert exposure in debug builds). Both change classes addressed in this patch. Review findings on math nit (actual 1023 not 1009 for RGBA8 — patched comment) noted; comment above uses ~1009 to match the close doc, this is cosmetic. Cross-refs: - ~/src/panvk-bifrost/iter22/phase0to2_max3d_close.md (Phase 0-2 close) --- src/panfrost/vulkan/panvk_physical_device.c | 13 +++++++++---- src/panfrost/vulkan/panvk_vX_physical_device.c | 11 ++++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/panfrost/vulkan/panvk_physical_device.c b/src/panfrost/vulkan/panvk_physical_device.c --- a/src/panfrost/vulkan/panvk_physical_device.c +++ b/src/panfrost/vulkan/panvk_physical_device.c @@ -1013,9 +1013,15 @@ MAX_IMAGE_SIZE_PX), }; - assert(ret.width >= phys_dev->vk.properties.maxImageDimension3D); - assert(ret.height >= phys_dev->vk.properties.maxImageDimension3D); - assert(ret.depth >= phys_dev->vk.properties.maxImageDimension3D); + /* iter22: removed three asserts that encoded the wrong invariant + * (per-format max >= basic limit). Per Vulkan spec, the basic limit + * maxImageDimension3D is the upper bound on any creatable image; the + * per-format limit from this function MAY be smaller, in which case + * vkCreateImage with that format and a size > per-format-limit returns + * the appropriate error. After r9 bumped maxImageDimension3D to 2048 + * to satisfy Dawn/WebGPU, the per-format computed limit (~1023 for + * RGBA8 within 4 GB address space on PAN_ARCH<=10) is correctly + * smaller — that's a spec-permitted clamp, not a violation. */ return ret; } diff --git a/src/panfrost/vulkan/panvk_vX_physical_device.c b/src/panfrost/vulkan/panvk_vX_physical_device.c --- a/src/panfrost/vulkan/panvk_vX_physical_device.c +++ b/src/panfrost/vulkan/panvk_vX_physical_device.c @@ -648,7 +648,15 @@ */ .maxImageDimension1D = (1 << 16), .maxImageDimension2D = PAN_ARCH <= 10 ? (1 << 14) - 1 : (1 << 16), - .maxImageDimension3D = PAN_ARCH <= 10 ? (1 << 9) : (1 << 14), + /* iter22: bump from (1 << 9) = 512 to (1 << 11) = 2048 on PAN_ARCH 7+. + * Was below WebGPU/Dawn's required minimum (PhysicalDeviceVk.cpp:746). + * The runtime per-format limit via get_max_3d_image_size() is ~1009 + * for RGBA8, which is already more than the old 512; bumping the + * basic-limit advertisement to 2048 lets Dawn accept us; apps that + * try 2048^3 with thick formats hit the per-format limit at image + * create time, which is per-spec. */ + .maxImageDimension3D = PAN_ARCH < 7 ? (1 << 9) : + PAN_ARCH <= 10 ? (1 << 11) : (1 << 14), .maxImageDimensionCube = PAN_ARCH <= 10 ? (1 << 14) - 1 : (1 << 16), .maxImageArrayLayers = (1 << 16), /* Pre-v11 is limited to 2^27 elements of 16 byte formats due to