iter2 minimal image-clear probe — captured 2026-05-19 on ohm
(PineTab2 v2.0, RK3566, Mali-G52 r1 MC1, Mesa 26.0.6, kernel 7.0.0-danctnix1-6)

Source: panvk-bifrost/iter2/{probe_image_clear.c, Makefile}
Deployed to: /tmp/panvk-iter2/
Build: clean (no warnings with -Wall -Wextra)

===== RUN #1 (no validation layer) =====
$ PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 ./probe_image_clear

[step] vkCreateInstance
[step] vkEnumeratePhysicalDevices
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
[info] gpu='Mali-G52 r1 MC1' apiVersion=1.0.335
[info] R8G8B8A8_UNORM optimalTilingFeatures=0x8000dd83
[step] vkCreateDevice
[step] vkCreateImage (4x4 R8G8B8A8_UNORM optimal-tiled)
[info] image memReq size=4096 alignment=4096 typeBits=0x7
[step] vkAllocateMemory + vkBindImageMemory (device-local)
[step] vkCreateBuffer (staging, host-visible)
[step] vkBeginCommandBuffer + record image clear + copy
[step] vkQueueSubmit + vkWaitForFences (5s timeout)
[step] vkInvalidateMappedMemoryRanges + readback
[info] expected pixel = 0x44332211 (R=0x11 G=0x22 B=0x33 A=0x44)
[info] mismatches = 0 / 16
[PASS] PanVk-Bifrost image clear+copy: all 16 pixels match.
===== RC=0 =====

===== RUN #2 (VK_LAYER_KHRONOS_validation enabled) =====
[same step trace, no validation warnings/errors emitted]
[PASS] PanVk-Bifrost image clear+copy: all 16 pixels match.
===== RC=0 =====

===== STABILITY: 5 consecutive reruns =====
[info] mismatches = 0 / 16    [PASS]
[info] mismatches = 0 / 16    [PASS]
[info] mismatches = 0 / 16    [PASS]
[info] mismatches = 0 / 16    [PASS]
[info] mismatches = 0 / 16    [PASS]

7/7 runs PASS.

===== KEY OBSERVATIONS =====

1. R8G8B8A8_UNORM optimalTilingFeatures = 0x8000dd83:
     bit 0  (0x0001) SAMPLED_IMAGE
     bit 1  (0x0002) STORAGE_IMAGE
     bit 7  (0x0080) COLOR_ATTACHMENT
     bit 8  (0x0100) COLOR_ATTACHMENT_BLEND
     bit 10 (0x0400) BLIT_SRC
     bit 11 (0x0800) BLIT_DST
     bit 12 (0x1000) SAMPLED_IMAGE_FILTER_LINEAR
     bit 14 (0x4000) TRANSFER_SRC
     bit 15 (0x8000) TRANSFER_DST
     bit 31 (0x80000000) — extended/disjoint flag

2. Image memReq size=4096, alignment=4096 for a 4x4 RGBA8 image.
   Logical pixel size: 4*4*4 = 64 bytes.
   Allocated:          4096 bytes (one Mali page).
   So Bifrost pages the image out to a full page even for tiny images. Expected.

3. UNORM float→byte conversion is exact:
     R = 17.0f/255.0f → 0x11   ✓
     G = 34.0f/255.0f → 0x22   ✓
     B = 51.0f/255.0f → 0x33   ✓
     A = 68.0f/255.0f → 0x44   ✓
   No rounding error in any of the 16 pixels.

4. Bifrost optimal-tiling → linear-buffer detile correct:
   All 16 pixels read back as 0x44332211 with no shuffling.
   The vkCmdCopyImageToBuffer path handles the Bifrost tile layout transform.

No GPU faults, no MMU faults, no kernel-side panfrost messages across 7 runs.
