initial seed: retrofit campaign lineage from local working trees
panvk-bifrost campaigns (r1..r4 Vulkan compositor + r5.video1 Vulkan
video decode) shipped before this repo existed; the deliverable
patches live in marfrit-packages, but the reasoning chain, phase docs,
and source-state evidence lived only in local working trees on the
development host.
This retrofit imports:
- mesa-panvk-bifrost/ — r1..r4 era phase docs (iter1..iter18)
(libmali stub blobs at iter18/blob/ excluded
— 109MB of RE artifacts replaced with a README
pointer)
- mesa-panvk-bifrost-video/ — sibling campaign phase docs + probe
- evidence/ — frozen .tgz source snapshots at each milestone
(basis for the 0005 patch diff generation)
Future iterations should branch off here from day one, so each iter is
a commit rather than a snapshot. See [[feedback-session-local-process-pins]]
for the process drift this retrofit closes.
Total: 1.9 MB across 124 files.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
iter11 chrome://gpu Graphics Feature Status — captured 2026-05-20 on ohm
|
||||
Brave Browser 148.1.90.122 (auto-updated from 147 during the session)
|
||||
Launch invocation:
|
||||
VK_ICD_FILENAMES=/usr/lib/panvk-bifrost/icd.json
|
||||
PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1
|
||||
MESA_VK_VERSION_OVERRIDE=1.2
|
||||
LIBVA_DRIVER_NAME=v4l2_request
|
||||
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video1
|
||||
LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media0
|
||||
brave --use-gl=disabled
|
||||
--enable-features=Vulkan,VaapiVideoDecoder,VaapiIgnoreDriverChecks
|
||||
--use-vulkan=native
|
||||
--ozone-platform=x11
|
||||
--no-sandbox --disable-gpu-sandbox
|
||||
--ignore-gpu-blocklist
|
||||
chrome://gpu
|
||||
|
||||
Operator-reported Graphics Feature Status table:
|
||||
|
||||
Canvas: Hardware accelerated
|
||||
Direct Rendering Display Compositor: Disabled
|
||||
Compositing: Software only. Hardware acceleration disabled
|
||||
Multiple Raster Threads: Enabled
|
||||
OpenGL: Enabled
|
||||
Rasterization: Hardware accelerated
|
||||
Raw Draw: Disabled
|
||||
Skia Graphite: Disabled
|
||||
TreesInViz: Disabled
|
||||
Video Decode: Hardware accelerated
|
||||
Video Encode: Software only. Hardware acceleration disabled
|
||||
Vulkan: Enabled
|
||||
WebGL: Hardware accelerated but at reduced performance
|
||||
WebGPU: Hardware accelerated but at reduced performance
|
||||
WebGPU interop: Disabled
|
||||
WebNN: Disabled
|
||||
|
||||
===== INTERPRETATION =====
|
||||
|
||||
PRIMARY WIN (iter11 goal):
|
||||
Video Decode: Hardware accelerated.
|
||||
VAAPI engaged via libva-v4l2-request-fourier's v4l2_request driver
|
||||
against rkvdec hardware. Stock Brave's "vaInitialize failed: unknown
|
||||
libva error" line is gone. Combined with iter9's Vulkan compositor,
|
||||
this means H.264 / MPEG-2 / VP8 in-page video will now hardware-decode
|
||||
on PineTab2 instead of grinding the Cortex-A55s.
|
||||
|
||||
CONTEXTUAL WIN (carryover from iter9):
|
||||
Vulkan: Enabled.
|
||||
|
||||
UNEXPECTED RESULT — needs investigation:
|
||||
Compositing: Software only.
|
||||
This is surprising. The iter9 demonstrated the Vulkan compositor is
|
||||
doing real work (operator visually confirmed window rendered, 250 FPS
|
||||
glxgears-via-Zink-on-PanVk separately). Chromium's chrome://gpu
|
||||
reporter says "Software only" but the visible behavior says otherwise.
|
||||
Hypothesis: Chromium's Compositing-status reporter ties to OpenGL
|
||||
context availability; with --use-gl=disabled, the GL context is
|
||||
intentionally absent → reporter says "software" even though Skia GrVk
|
||||
is actually doing GPU work via the Vulkan path. The reporter and the
|
||||
reality may diverge under --use-gl=disabled. Open question for iter12.
|
||||
|
||||
UNEXPECTED RESULT — surprise:
|
||||
WebGL: Hardware accelerated but at reduced performance.
|
||||
WebGPU: Hardware accelerated but at reduced performance.
|
||||
Earlier hypothesis was that WebGL would be broken because ANGLE needs
|
||||
GLES3 which needs VK_EXT_transform_feedback (PanVk-Bifrost doesn't
|
||||
expose). But chrome://gpu says hardware accelerated at reduced perf.
|
||||
Possibilities:
|
||||
- Brave 148's ANGLE has a softer transform_feedback path
|
||||
- Chromium reports "hardware accelerated" optimistically when ANY
|
||||
GPU path is available, even if shaders requiring GLES3 features
|
||||
would fall back internally
|
||||
- The "reduced performance" qualifier is doing heavy lifting
|
||||
Open question for iter12 — actually test a WebGL/WebGPU page.
|
||||
|
||||
OUT OF SCOPE:
|
||||
Video Encode: Software only — rkvenc not exposed via VAAPI on this
|
||||
hardware/stack. Webcam capture would software-encode. Unaffected by
|
||||
iter11.
|
||||
Skia Graphite: Disabled — falling back to classic Skia. Acceptable;
|
||||
Skia/Vulkan still engages via GrVk.
|
||||
|
||||
===== CAMPAIGN CUMULATIVE STATE =====
|
||||
|
||||
PanVk-Bifrost stack on PineTab2 now drives:
|
||||
- Browser chrome rendering via Vulkan compositor (iter9)
|
||||
- Hardware video decode for H.264/MPEG-2/VP8 via VAAPI->rkvdec (iter11)
|
||||
- WebGL/WebGPU "at reduced performance" (this run's surprise; needs verification)
|
||||
- Compositing reporter says "Software only" but visual evidence
|
||||
contradicts (this run's other surprise)
|
||||
|
||||
===== 2026-05-20 update: empirical playback test (operator-driven) =====
|
||||
|
||||
Operator played bbb_1080p30_h264.mp4 in the iter11-flag Brave window.
|
||||
While playback was active:
|
||||
|
||||
Brave processes (top sampled across 3 seconds):
|
||||
PID 6107 renderer: ~70-81% CPU (single core, sustained)
|
||||
PID 5811 gpu-process: ~57-67% CPU
|
||||
PID 5776 main brave: ~3%
|
||||
Other utility/network: ~3-6%
|
||||
|
||||
File descriptors held by each brave PID:
|
||||
PID 5776: /dev/dri/renderD128 (Mali GPU node, Vulkan)
|
||||
PID 5811: /dev/dri/renderD128
|
||||
PID 6107: (no video/dri fds at all)
|
||||
PID 5813 (network): none
|
||||
|
||||
fuser /dev/video1: EMPTY (no process holds the rkvdec node)
|
||||
lsof /dev/media0: EMPTY (no process holds the media controller)
|
||||
|
||||
INTERPRETATION:
|
||||
- The rkvdec hardware decoder is IDLE during playback.
|
||||
- The renderer process is software-decoding H.264 1080p30 via libavcodec
|
||||
on a Cortex-A55 (75% of one core matches the known cost of NEON-
|
||||
accelerated H.264 SW decode at that resolution/framerate).
|
||||
- chrome://gpu's "Video Decode: Hardware accelerated" was optimistic —
|
||||
it reflects "VAAPI initialized successfully" + "compatible profiles
|
||||
found" but NOT "decoded frames actually deliver to compositor".
|
||||
- The likely culprit: --use-gl=disabled blocks Chromium's VAAPI
|
||||
delivery path. The classic chain is VAAPI -> DMA-BUF -> GL texture
|
||||
import -> compositor. With GL disabled, step 3 (GL texture import)
|
||||
has no GL context to bind into. Chromium silently falls back to
|
||||
SW decode while keeping the "available" status on chrome://gpu.
|
||||
|
||||
ITER11 STATUS: vaInitialize succeeds now (iter9 RED gone), VAAPI is
|
||||
recognized as available, but no actual hardware decode happens for the
|
||||
tested playback. Partial GREEN at best. Real HW decode requires
|
||||
unblocking the delivery path — iter12 territory.
|
||||
@@ -0,0 +1,83 @@
|
||||
iter1 minimal compute 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/iter1/{probe_compute.c, probe_compute.comp, Makefile}
|
||||
Deployed to: /tmp/panvk-iter1/
|
||||
Build: clean (no warnings with -Wall -Wextra)
|
||||
Binary: 260592 bytes
|
||||
SPV: 560 bytes
|
||||
|
||||
===== RUN #1 (no validation layer) =====
|
||||
$ PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 ./probe_compute
|
||||
|
||||
[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 driverVersion=109051910
|
||||
[step] vkGetPhysicalDeviceQueueFamilyProperties
|
||||
[info] using queue family 0 (flags=0x7)
|
||||
[step] vkCreateDevice
|
||||
[step] vkCreateBuffer (storage, host-visible)
|
||||
[info] buffer memReq size=64 alignment=64 typeBits=0x7
|
||||
[step] vkAllocateMemory
|
||||
[step] vkMapMemory (pre-write 0xDEADBEEF sentinel)
|
||||
[step] vkCreateDescriptorSetLayout
|
||||
[step] vkCreateDescriptorPool
|
||||
[step] vkAllocateDescriptorSets
|
||||
[step] vkUpdateDescriptorSets
|
||||
[step] vkCreateShaderModule (from probe_compute.spv)
|
||||
[step] vkCreatePipelineLayout
|
||||
[step] vkCreateComputePipelines
|
||||
[step] vkCreateCommandPool
|
||||
[step] vkAllocateCommandBuffers
|
||||
[step] vkBeginCommandBuffer + record dispatch
|
||||
[step] vkCreateFence
|
||||
[step] vkQueueSubmit
|
||||
[step] vkWaitForFences (5s timeout)
|
||||
[step] vkInvalidateMappedMemoryRanges + readback
|
||||
[info] buffer[0] = 0xcafebabe (expected 0xcafebabe)
|
||||
[PASS] PanVk-Bifrost compute dispatch wrote the expected pattern.
|
||||
===== RC=0 =====
|
||||
|
||||
===== RUN #2 (VK_LAYER_KHRONOS_validation enabled) =====
|
||||
$ PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 \
|
||||
VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ./probe_compute
|
||||
|
||||
[same step trace as above]
|
||||
[info] buffer[0] = 0xcafebabe (expected 0xcafebabe)
|
||||
[PASS] PanVk-Bifrost compute dispatch wrote the expected pattern.
|
||||
===== RC=0 =====
|
||||
|
||||
No validation-layer warnings or errors emitted. (vkCreateInstance succeeded
|
||||
with the layer string in VK_INSTANCE_LAYERS, which implies the loader found
|
||||
and activated the layer; otherwise it would return VK_ERROR_LAYER_NOT_PRESENT.)
|
||||
|
||||
===== STABILITY: 5 consecutive reruns =====
|
||||
$ for i in 1 2 3 4 5; do PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 ./probe_compute; done
|
||||
|
||||
[info] buffer[0] = 0xcafebabe (expected 0xcafebabe)
|
||||
[PASS] PanVk-Bifrost compute dispatch wrote the expected pattern.
|
||||
[info] buffer[0] = 0xcafebabe (expected 0xcafebabe)
|
||||
[PASS] PanVk-Bifrost compute dispatch wrote the expected pattern.
|
||||
[info] buffer[0] = 0xcafebabe (expected 0xcafebabe)
|
||||
[PASS] PanVk-Bifrost compute dispatch wrote the expected pattern.
|
||||
[info] buffer[0] = 0xcafebabe (expected 0xcafebabe)
|
||||
[PASS] PanVk-Bifrost compute dispatch wrote the expected pattern.
|
||||
[info] buffer[0] = 0xcafebabe (expected 0xcafebabe)
|
||||
[PASS] PanVk-Bifrost compute dispatch wrote the expected pattern.
|
||||
|
||||
6/6 runs PASS.
|
||||
|
||||
===== DMESG (panfrost-related, full boot tail) =====
|
||||
[ 5.331157] panfrost fde60000.gpu: clock rate = 594000000
|
||||
[ 5.331201] panfrost fde60000.gpu: bus_clock rate = 500000000
|
||||
[ 5.336259] panfrost fde60000.gpu: [drm:panfrost_devfreq_init [panfrost]] Failed to register cooling device
|
||||
[ 5.336430] panfrost fde60000.gpu: mali-g52 id 0x7402 major 0x1 minor 0x0 status 0x0
|
||||
[ 5.336443] panfrost fde60000.gpu: features: 00000000,00000df7, issues: 00000000,00000400
|
||||
[ 5.336450] panfrost fde60000.gpu: Features: L2:0x07110206 Shader:0x00000002 Tiler:0x00000209 Mem:0x1 MMU:0x00002823 AS:0xff JS:0x7
|
||||
[ 5.336458] panfrost fde60000.gpu: shader_present=0x1 l2_present=0x1
|
||||
[ 5.344566] panfrost fde60000.gpu: [drm] Using Transparent Hugepage
|
||||
[ 5.347277] [drm] Initialized panfrost 1.6.0 for fde60000.gpu on minor 1
|
||||
|
||||
No GPU faults, no MMU faults, no kernel-side panfrost warnings after running
|
||||
the probe 6 times.
|
||||
@@ -0,0 +1,73 @@
|
||||
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.
|
||||
@@ -0,0 +1,77 @@
|
||||
iter3 fullscreen triangle 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/iter3/{probe_triangle.c, probe_triangle.vert, probe_triangle.frag, Makefile}
|
||||
Deployed to: /tmp/panvk-iter3/
|
||||
Build: clean
|
||||
|
||||
===== RUN #1 (no validation layer) =====
|
||||
$ PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 ./probe_triangle
|
||||
|
||||
[step] vkCreateInstance (+VK_KHR_get_physical_device_properties2)
|
||||
[step] vkEnumeratePhysicalDevices
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
[info] gpu='Mali-G52 r1 MC1' apiVersion=1.0.335
|
||||
[step] vkCreateDevice (+dynamic_rendering chain)
|
||||
[step] vkCreateImage (64x64 R8G8B8A8_UNORM, COLOR_ATTACHMENT|TRANSFER_SRC)
|
||||
[info] image memReq size=20480 alignment=4096
|
||||
[step] vkCreateImageView
|
||||
[step] vkCreatePipelineLayout + shaders
|
||||
[step] vkCreateGraphicsPipelines
|
||||
[step] record (dynamic rendering + draw + copy)
|
||||
[step] submit + wait (10s)
|
||||
[step] invalidate + verify
|
||||
[info] mismatches=0/4096 sentinel=0 cleared_black=0
|
||||
[PASS] PanVk-Bifrost triangle: all 4096 pixels match.
|
||||
===== RC=0 =====
|
||||
|
||||
===== RUN #2 (VK_LAYER_KHRONOS_validation) =====
|
||||
[same step trace; no validation warnings/errors]
|
||||
[info] mismatches=0/4096 sentinel=0 cleared_black=0
|
||||
[PASS]
|
||||
===== RC=0 =====
|
||||
|
||||
===== STABILITY: 5 consecutive reruns =====
|
||||
[info] mismatches=0/4096 sentinel=0 cleared_black=0 [PASS]
|
||||
[info] mismatches=0/4096 sentinel=0 cleared_black=0 [PASS]
|
||||
[info] mismatches=0/4096 sentinel=0 cleared_black=0 [PASS]
|
||||
[info] mismatches=0/4096 sentinel=0 cleared_black=0 [PASS]
|
||||
[info] mismatches=0/4096 sentinel=0 cleared_black=0 [PASS]
|
||||
|
||||
7/7 runs PASS, all 4096 pixels per run match the expected gl_FragCoord encoding.
|
||||
|
||||
===== KEY OBSERVATIONS =====
|
||||
|
||||
1. Device-extension chain enables cleanly with all 5 KHRs:
|
||||
VK_KHR_multiview
|
||||
VK_KHR_maintenance2
|
||||
VK_KHR_create_renderpass2
|
||||
VK_KHR_depth_stencil_resolve
|
||||
VK_KHR_dynamic_rendering
|
||||
plus instance VK_KHR_get_physical_device_properties2 and
|
||||
VkPhysicalDeviceDynamicRenderingFeaturesKHR.dynamicRendering = VK_TRUE.
|
||||
|
||||
2. Image memReq for 64×64 RGBA8 COLOR_ATTACHMENT|TRANSFER_SRC:
|
||||
size = 20480 (5 pages)
|
||||
alignment = 4096
|
||||
Raw pixel data: 64*64*4 = 16384 bytes (4 pages).
|
||||
The extra page is Mali tile state / AFBC metadata / aux tiling structures
|
||||
that PanVk allocates alongside the color attachment.
|
||||
|
||||
3. Pixel-position encoding round-trips exactly:
|
||||
(0,0) -> 0xff800000 ✓
|
||||
(63,0) -> 0xff80003f ✓
|
||||
(0,63) -> 0xff803f00 ✓
|
||||
(63,63) -> 0xff803f3f ✓
|
||||
(32,32) -> 0xff802020 ✓
|
||||
(all 4096) -> exact match
|
||||
gl_FragCoord.xy in pixel-center coords (+0.5) → uvec2 floor gives exact
|
||||
pixel index. Vulkan's top-left origin honored. No off-by-half, no Y-flip.
|
||||
|
||||
4. Bifrost tile binning works:
|
||||
16×16 tile size × 64×64 image = 16 tiles (4×4 grid)
|
||||
Each tile flushed cleanly; no missing tile, no swapped tiles, no
|
||||
tile-coverage gap at boundaries.
|
||||
|
||||
5. No GPU faults, no MMU faults, no kernel-side panfrost messages
|
||||
across all 7 runs.
|
||||
@@ -0,0 +1,67 @@
|
||||
iter4 textured-quad 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/iter4/{probe_texture.c, .vert, .frag, Makefile}
|
||||
Deployed to: /tmp/panvk-iter4/
|
||||
Build: clean
|
||||
|
||||
===== RUN #1 (no validation) =====
|
||||
[step] vkCreateInstance
|
||||
[step] vkEnumeratePhysicalDevices
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
[info] gpu='Mali-G52 r1 MC1'
|
||||
[step] vkCreateDevice (+dynamic_rendering chain)
|
||||
[step] vkCreateImage source texture (4x4 RGBA8 SAMPLED|TRANSFER_DST)
|
||||
[info] source texture memReq size=4096 align=4096
|
||||
[step] vkCreateSampler (NEAREST, CLAMP_TO_EDGE)
|
||||
[step] vkCreateImage color attachment (64x64 RGBA8 COLOR_ATTACHMENT|TRANSFER_SRC)
|
||||
[step] vkCreateDescriptorSetLayout (1 COMBINED_IMAGE_SAMPLER)
|
||||
[step] vkCreatePipelineLayout + shaders
|
||||
[step] vkCreateGraphicsPipelines
|
||||
[step] record cmd buffer (tex upload + draw + readback)
|
||||
[step] submit + wait (10s)
|
||||
[step] invalidate + verify
|
||||
[info] mismatches=0/4096 sentinel=0 black=0
|
||||
[PASS] PanVk-Bifrost textured quad: all 4096 pixels match.
|
||||
RC=0
|
||||
|
||||
===== RUN #2 (VK_LAYER_KHRONOS_validation) =====
|
||||
[no validation warnings/errors]
|
||||
[PASS]
|
||||
|
||||
===== STABILITY: 5 reruns =====
|
||||
mismatches=0/4096 sentinel=0 black=0 [PASS]
|
||||
mismatches=0/4096 sentinel=0 black=0 [PASS]
|
||||
mismatches=0/4096 sentinel=0 black=0 [PASS]
|
||||
mismatches=0/4096 sentinel=0 black=0 [PASS]
|
||||
mismatches=0/4096 sentinel=0 black=0 [PASS]
|
||||
|
||||
7/7 runs PASS, all 4096 pixels per run match expected modulo-4 tile-repeated pattern.
|
||||
|
||||
===== KEY OBSERVATIONS =====
|
||||
|
||||
1. Source texture (4x4 RGBA8 SAMPLED|TRANSFER_DST):
|
||||
memReq size = 4096 (one page)
|
||||
alignment = 4096
|
||||
Just a single Mali page — but 16 logical bytes of pixel data live inside.
|
||||
|
||||
2. The Bifrost descriptor model (PANVK_BIFROST_DESC_TABLE_COUNT etc.) handles
|
||||
COMBINED_IMAGE_SAMPLER bindings cleanly for the fragment shader stage:
|
||||
- VkDescriptorSetLayout creation
|
||||
- VkDescriptorPool + AllocateDescriptorSets
|
||||
- vkUpdateDescriptorSets with image + sampler
|
||||
- vkCmdBindDescriptorSets at graphics bind point
|
||||
- shader-side texelFetch resolves to correct GPU memory access
|
||||
|
||||
3. Texture upload path (vkCmdCopyBufferToImage):
|
||||
- Layout transition UNDEFINED -> TRANSFER_DST_OPTIMAL
|
||||
- Linear staging buffer -> optimal-tiled image (Bifrost tile encode)
|
||||
- Layout transition TRANSFER_DST_OPTIMAL -> SHADER_READ_ONLY_OPTIMAL
|
||||
All round-trip exactly: texels written via staging buffer are read back
|
||||
exactly via texelFetch + render + image-to-buffer-copy.
|
||||
|
||||
4. No GPU faults, no MMU faults, no validation-layer warnings.
|
||||
|
||||
The headline iter4 hypothesis (Bifrost descriptor model fails on first
|
||||
sampled-image use) did NOT materialize. PanVk-Bifrost's descriptor handling
|
||||
works for the minimal sampled-texture case.
|
||||
@@ -0,0 +1,73 @@
|
||||
iter5 vertex+UBO 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/iter5/{probe_vbo_ubo.c, .vert, .frag, Makefile}
|
||||
Deployed to: /tmp/panvk-iter5/
|
||||
|
||||
===== RUN #1 (baseline) =====
|
||||
[step] vkCreateInstance
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
[info] gpu='Mali-G52 r1 MC1'
|
||||
[step] vkCreateDevice
|
||||
[step] vkCreateBuffer vertex buffer
|
||||
[step] vkCreateBuffer UBO
|
||||
[step] vkCreateDescriptorSetLayout (UBO @ vertex)
|
||||
[step] vkCreatePipelineLayout + shaders
|
||||
[step] vkCreateGraphicsPipelines
|
||||
[step] record cmd buffer
|
||||
[step] submit + wait
|
||||
[step] verify
|
||||
[info] center (32,28) = 0xff5d564c (R=4c G=56 B=5d)
|
||||
[info] TL=0x00000000 TR=0x00000000
|
||||
[info] covered (non-clear) pixels = 338 / 4096
|
||||
[PASS]
|
||||
|
||||
===== RUN #2 (VK_LAYER_KHRONOS_validation) =====
|
||||
[no validation warnings]
|
||||
covered = 338 [PASS]
|
||||
|
||||
===== STABILITY: 5 reruns =====
|
||||
covered = 338 [PASS] x5
|
||||
|
||||
7/7 PASS after coverage-range fix.
|
||||
|
||||
===== INITIAL FAILURE NOTE =====
|
||||
|
||||
First run reported "coverage out of range: 338 (want 800..1600)" — that was a
|
||||
verification-side arithmetic error on my (claude-noether's) part, not a driver
|
||||
issue. Triangle area = 0.5 * 0.8 * 0.8 = 0.32 sq units in NDC; viewport area
|
||||
is 4 sq units, so 8% coverage = ~328 pixels. The driver produced exactly 338,
|
||||
which matches the expected coverage within edge-rule tolerance.
|
||||
|
||||
Substantive PASS criteria (interpolated center color, clear corners) were
|
||||
satisfied on the first run; only the loose coverage-range check needed
|
||||
calibration. Fixed in-tree at `iter5/probe_vbo_ubo.c`.
|
||||
|
||||
===== KEY OBSERVATIONS =====
|
||||
|
||||
1. Vertex input binding works:
|
||||
binding 0: stride 32, INPUT_RATE_VERTEX
|
||||
attribute 0: R32G32_SFLOAT, offset 0 (pos)
|
||||
attribute 1: R32G32B32_SFLOAT, offset 16 (color)
|
||||
GPU correctly fetched both attributes from the bound vertex buffer.
|
||||
|
||||
2. UBO binding at vertex stage works:
|
||||
mat4 transform with scale 0.8 in x/y was correctly applied.
|
||||
Triangle vertices at NDC (-0.5,-0.5)/(0.5,-0.5)/(0,0.5) scaled to
|
||||
(-0.4,-0.4)/(0.4,-0.4)/(0,0.4) — visible from the 338-pixel coverage
|
||||
(matches 0.8-scaled area, NOT unscaled 0.5-scaled area which would be
|
||||
~500 pixels).
|
||||
|
||||
3. Varying interpolation works:
|
||||
center pixel at (32, 28) has R=0x4c G=0x56 B=0x5d. All three vertex
|
||||
colors (red/green/blue) contributed via barycentric interpolation —
|
||||
none of the channels are zero, none are saturated, all are in a
|
||||
reasonable middle-of-range value.
|
||||
|
||||
4. Bifrost vertex-side descriptor model handles UBO + vertex-stage shader
|
||||
correctly (the headline hypothesis for this iter — that vertex-stage
|
||||
descriptor binding would fail on Bifrost — did not materialize).
|
||||
|
||||
5. Deterministic across runs: identical 338 covered pixels each time.
|
||||
|
||||
No GPU faults, no validation warnings, all 7 runs identical.
|
||||
@@ -0,0 +1,57 @@
|
||||
iter6 depth-tested multi-draw 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/iter6/{probe_depth.c, .vert, .frag, Makefile}
|
||||
Deployed to: /tmp/panvk-iter6/
|
||||
|
||||
===== RUN #1 (baseline) =====
|
||||
[step] vkCreateInstance
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
[info] gpu='Mali-G52 r1 MC1'
|
||||
[info] D32_SFLOAT optimalTilingFeatures=0xd601
|
||||
[step] vkCreateDevice
|
||||
[step] vkCreateBuffer vertex buffer
|
||||
[step] vkCreateImage color attachment
|
||||
[info] color image memReq size=69632 align=4096
|
||||
[step] vkCreateImage depth attachment (D32_SFLOAT)
|
||||
[info] depth image memReq size=69632 align=4096
|
||||
[step] vkCreatePipelineLayout + shaders
|
||||
[step] vkCreateGraphicsPipelines
|
||||
[step] record cmd buffer (2 draws with depth)
|
||||
[step] submit + wait
|
||||
[step] verify
|
||||
[chk] ( 0, 0) TL expect=clear got=0x00000000 clear-ok
|
||||
[chk] (127,127) BR expect=clear got=0x00000000 clear-ok
|
||||
[chk] ( 64, 64) center expect=green got=0xff00ff00 green-ok
|
||||
[chk] ( 64, 30) above-B expect=red got=0xff0000ff red-ok
|
||||
[chk] ( 64,100) below-B expect=red got=0xff0000ff red-ok
|
||||
[info] coverage: red=3850 green=1352 clear=11182 other=0 (total 16384)
|
||||
[PASS] depth-tested multi-draw works.
|
||||
|
||||
===== KEY OBSERVATIONS =====
|
||||
|
||||
1. D32_SFLOAT optimalTilingFeatures = 0xd601:
|
||||
bit 0 (0x0001) SAMPLED_IMAGE
|
||||
bit 9 (0x0200) DEPTH_STENCIL_ATTACHMENT ✓
|
||||
bit 10 (0x0400) BLIT_SRC
|
||||
bit 12 (0x1000) SAMPLED_IMAGE_FILTER_LINEAR
|
||||
bit 14 (0x4000) TRANSFER_SRC
|
||||
bit 15 (0x8000) TRANSFER_DST
|
||||
|
||||
2. Memory:
|
||||
color image memReq = 69632 (17 pages) — 16 raw + 1 aux
|
||||
depth image memReq = 69632 (17 pages) — same overhead for D32
|
||||
128*128*4 = 65536 = 16 pages raw pixel data
|
||||
|
||||
3. Coverage accounting:
|
||||
Triangle A (red, large): NDC area 1.28 / 4 = 32% = ~5243 pixels expected
|
||||
Triangle B (green, small, inside A): NDC area 0.32 / 4 = 8% = ~1310 pixels expected
|
||||
Got: red=3850, green=1352
|
||||
Sum non-clear: 5202 ≈ A's total area (B occludes part of A in depth)
|
||||
other=0 — no banding, no z-fighting, no interpolation artifacts.
|
||||
|
||||
4. Depth test correct:
|
||||
Pixel (64, 64) is inside both triangles. B's z=0.3 < A's z=0.7,
|
||||
LESS comparison selects B → green wins. Confirmed at (64, 64).
|
||||
|
||||
5. No GPU faults, no validation warnings, deterministic across reruns.
|
||||
@@ -0,0 +1,62 @@
|
||||
iter7 vkcube — captured 2026-05-19 on ohm
|
||||
(PineTab2 v2.0, RK3566, Mali-G52 r1 MC1, Mesa 26.0.6, kernel 7.0.0-danctnix1-6)
|
||||
Operator session: mfritsche (UID 1001), Plasma/Wayland on tty1, wayland-0 socket.
|
||||
|
||||
===== RUN #1 (--c 120 --wsi wayland) =====
|
||||
$ sudo -u mfritsche XDG_RUNTIME_DIR=/run/user/1001 WAYLAND_DISPLAY=wayland-0 \
|
||||
PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 timeout 30 vkcube --c 120 --wsi wayland
|
||||
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
Selected GPU 0: Mali-G52 r1 MC1, type: IntegratedGpu
|
||||
===== RC=0 =====
|
||||
|
||||
===== RUN #2 (--c 120 --wsi wayland --validate) =====
|
||||
$ sudo -u mfritsche XDG_RUNTIME_DIR=/run/user/1001 WAYLAND_DISPLAY=wayland-0 \
|
||||
PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 timeout 30 vkcube --c 120 --wsi wayland --validate
|
||||
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
Selected GPU 0: Mali-G52 r1 MC1, type: IntegratedGpu
|
||||
===== RC=0 =====
|
||||
(VK_LAYER_KHRONOS_validation active, zero warnings printed.)
|
||||
|
||||
===== RUN #3 (--c 240, timed) =====
|
||||
$ time sudo -u mfritsche XDG_RUNTIME_DIR=/run/user/1001 WAYLAND_DISPLAY=wayland-0 \
|
||||
PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 timeout 30 vkcube --c 240 --wsi wayland
|
||||
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
Selected GPU 0: Mali-G52 r1 MC1, type: IntegratedGpu
|
||||
|
||||
real 0m4.352s
|
||||
user 0m0.176s
|
||||
sys 0m0.251s
|
||||
===== RC=0 =====
|
||||
|
||||
→ 240 frames / 4.352s = ~55.1 FPS sustained.
|
||||
Almost certainly vsync-locked to display refresh (60Hz on PineTab2).
|
||||
user+sys CPU = 0.43s out of 4.35s wall → ~10% CPU, the rest is GPU+vsync wait.
|
||||
|
||||
===== OPERATOR VISUAL CONFIRMATION =====
|
||||
2026-05-19, mfritsche: "Ich hab' ihn gesehen." — vkcube's rotating textured
|
||||
cube was visually verified on the PineTab2 screen during the run.
|
||||
|
||||
===== DMESG =====
|
||||
No panfrost faults, no MMU faults, no GPU error messages logged during or
|
||||
after the 3 vkcube runs.
|
||||
|
||||
===== KEY OBSERVATIONS =====
|
||||
|
||||
1. PanVk-Bifrost handles the canonical Vulkan reference application end-to-end:
|
||||
- VK_KHR_wayland_surface creates a surface against the Plasma compositor
|
||||
- VK_KHR_swapchain allocates swapchain images
|
||||
- vkAcquireNextImageKHR + vkQueuePresentKHR cycle works for 240 frames
|
||||
- Rotating MVP matrix per frame, textured cube vertex buffer, depth test
|
||||
- 55 FPS sustained on a single-core (MC1) Mali-G52 — vsync-locked
|
||||
|
||||
2. The "present support = false" line in vulkaninfo (from an off-line surface
|
||||
query) is misleading — with an actual Wayland surface in play, vkcube
|
||||
negotiates a present-capable swapchain without issues.
|
||||
|
||||
3. Validation layer reports zero warnings even with --validate.
|
||||
|
||||
4. This is the first real-app smoke test in this campaign and it passes
|
||||
without any code path failing.
|
||||
@@ -0,0 +1,87 @@
|
||||
iter8 Zink-on-PanVk-Bifrost RED finding — captured 2026-05-19 on ohm
|
||||
(PineTab2 v2.0, RK3566, Mali-G52 r1 MC1, Mesa 26.0.6, kernel 7.0.0-danctnix1-6)
|
||||
|
||||
===== eglinfo with Zink + PanVk attempted =====
|
||||
$ sudo -u mfritsche XDG_RUNTIME_DIR=/run/user/1001 WAYLAND_DISPLAY=wayland-0 \
|
||||
MESA_LOADER_DRIVER_OVERRIDE=zink PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 eglinfo
|
||||
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
MESA: error: Zink requires the nullDescriptor feature of KHR/EXT robustness2.
|
||||
WARNING: panvk is not a conformant Vulkan implementation, testing use only.
|
||||
MESA: error: Zink requires the nullDescriptor feature of KHR/EXT robustness2.
|
||||
...
|
||||
OpenGL core profile vendor: Mesa
|
||||
OpenGL core profile renderer: llvmpipe (LLVM 22.1.3, 128 bits) ← FALLBACK
|
||||
OpenGL core profile version: 4.5 (Core Profile) Mesa 26.0.6-arch1.1
|
||||
RC=0 (but Zink did NOT load — fell back to llvmpipe SW rasterizer)
|
||||
|
||||
===== PanVk-Bifrost vulkaninfo confirms robustness2 NOT in extension list =====
|
||||
$ PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 vulkaninfo | grep -iE "robust|nullDescriptor"
|
||||
|
||||
VkPhysicalDevicePipelineRobustnessPropertiesEXT: present
|
||||
defaultRobustnessStorageBuffers = ROBUST_BUFFER_ACCESS
|
||||
defaultRobustnessUniformBuffers = ROBUST_BUFFER_ACCESS
|
||||
defaultRobustnessVertexInputs = ROBUST_BUFFER_ACCESS
|
||||
defaultRobustnessImages = ROBUST_IMAGE_ACCESS
|
||||
|
||||
Device extensions present:
|
||||
VK_EXT_image_robustness (different extension)
|
||||
VK_EXT_pipeline_robustness (different extension)
|
||||
|
||||
VkPhysicalDeviceImageRobustnessFeaturesEXT.robustImageAccess = true
|
||||
VkPhysicalDevicePipelineRobustnessFeaturesEXT.pipelineRobustness = true
|
||||
|
||||
NOT present:
|
||||
VK_EXT_robustness2 ← what Zink wants
|
||||
VK_KHR_robustness2 ← what Zink wants
|
||||
VkPhysicalDeviceRobustness2FeaturesEXT.nullDescriptor
|
||||
|
||||
===== Mesa source: the gate =====
|
||||
File: ~/src/mesa-ref/mesa/src/panfrost/vulkan/panvk_vX_physical_device.c
|
||||
|
||||
line 94: .KHR_robustness2 = PAN_ARCH >= 10,
|
||||
line 194: .EXT_robustness2 = PAN_ARCH >= 10,
|
||||
line 590: .nullDescriptor = PAN_ARCH >= 10,
|
||||
|
||||
Bifrost is PAN_ARCH 6 (G31/G52/G72) or 7 (G52 r1/G76). Both fall OUTSIDE
|
||||
the `>= 10` gate. Mali-G52 r1 on ohm reports as PAN_ARCH=7 (per iter1 driver
|
||||
log: arch=7 in the panvk_physical_device.c switch statement).
|
||||
|
||||
Valhall (PAN_ARCH=9), Bifrost, and the experimental v14 fifthgen are all
|
||||
denied robustness2 with the same hardcoded gate.
|
||||
|
||||
===== Zink's hard requirement =====
|
||||
File: ~/src/mesa-ref/mesa/src/gallium/drivers/zink/zink_screen.c:3488-3489
|
||||
|
||||
if (!screen->info.rb2_feats.nullDescriptor) {
|
||||
mesa_loge("Zink requires the nullDescriptor feature of KHR/EXT robustness2.");
|
||||
...
|
||||
}
|
||||
|
||||
No ZINK_DEBUG flag in zink_screen.c:97-127 disables this check. The feature
|
||||
is a hard prerequisite for Zink.
|
||||
|
||||
===== NIR side: the feature already plumbs through =====
|
||||
File: ~/src/mesa-ref/mesa/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c:1309
|
||||
.null_descriptor_support = dev->vk.enabled_features.nullDescriptor,
|
||||
|
||||
File: ~/src/mesa-ref/mesa/src/panfrost/vulkan/panvk_vX_shader.c:1355
|
||||
.robust_descriptors = dev->vk.enabled_features.nullDescriptor,
|
||||
|
||||
The NIR lowering code already reads `enabled_features.nullDescriptor` —
|
||||
i.e., the plumbing exists per-arch. The gate at line 590 is what blocks
|
||||
the feature from being *enableable* on Bifrost; the underlying lowering
|
||||
machinery is already there and would activate if the feature were exposed.
|
||||
|
||||
That doesn't guarantee Bifrost's hardware can correctly handle a null
|
||||
descriptor read (the gate may exist *because* Bifrost can't), but iter4
|
||||
proved descriptor handling works for valid cases — and "null descriptor"
|
||||
mostly means "shader accesses an unbound binding cleanly without GPU fault."
|
||||
|
||||
===== Bigger picture =====
|
||||
This is the campaign's first real finding. PanVk-Bifrost is functionally
|
||||
solid for everything iter1–7 tested, but Zink (and presumably many other
|
||||
Vulkan apps that opt into modern descriptor features) requires extensions
|
||||
that PanVk-Bifrost gates out.
|
||||
|
||||
For the TuxRacer-via-Zink path, this MUST be fixed before iter9 makes sense.
|
||||
@@ -0,0 +1,108 @@
|
||||
iter9 Brave-on-PanVk-Bifrost breakthrough — captured 2026-05-20 on ohm
|
||||
(PineTab2 v2.0, RK3566, Mali-G52 r1 MC1, Mesa 26.0.6 + iter8 patch + iter9 patch + env override)
|
||||
|
||||
===== CAMPAIGN PIVOT CONTEXT =====
|
||||
Goal pivoted from "TuxRacer via Zink-on-PanVk" to "Brave/Chromium GPU
|
||||
process boots via Vulkan on PanVk-Bifrost". Pivot driven by extremetuxracer
|
||||
not being in Arch repos + Chromium-Vulkan being the structurally bigger
|
||||
ecosystem win (per README's "Consumer-side benefit" section).
|
||||
|
||||
===== THE WINNING COMBO =====
|
||||
|
||||
Patched binary (iter8 + iter9 patches stacked):
|
||||
/home/mfritsche/panvk-patched-libs/libvulkan_panfrost.so (16.8 MB)
|
||||
/home/mfritsche/panvk-patched-libs/panfrost_icd_patched.json
|
||||
|
||||
iter8 patch: KHR/EXT_robustness2 + nullDescriptor = true for PAN_ARCH 6/7
|
||||
iter9 patch: has_vk1_1 + has_vk1_2 = true for PAN_ARCH 6/7
|
||||
|
||||
Runtime env:
|
||||
XDG_RUNTIME_DIR=/run/user/1001
|
||||
WAYLAND_DISPLAY=wayland-0
|
||||
DISPLAY=:1
|
||||
XAUTHORITY=/run/user/1001/xauth_<random> (find from `pgrep -fa Xwayland`)
|
||||
VK_ICD_FILENAMES=/home/mfritsche/panvk-patched-libs/panfrost_icd_patched.json
|
||||
PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1
|
||||
MESA_VK_VERSION_OVERRIDE=1.2 (bypasses get_api_version's
|
||||
PAN_ARCH>=10 gate at runtime;
|
||||
cleaner than another patch)
|
||||
|
||||
Brave flags (the winners):
|
||||
--use-gl=disabled (CRUCIAL — skips GLES3 info collection;
|
||||
without this Chromium dies at ANGLE-
|
||||
Vulkan-on-Bifrost not exposing GLES3
|
||||
because PanVk-Bifrost lacks VK_EXT_
|
||||
transform_feedback)
|
||||
--enable-features=Vulkan (compositor uses Vulkan)
|
||||
--use-vulkan=native (use native Vulkan, no SwiftShader)
|
||||
--ozone-platform=x11 (Wayland ozone is incompatible with
|
||||
Vulkan per Chromium error msg; use
|
||||
X11 ozone via XWayland)
|
||||
--no-sandbox --disable-gpu-sandbox (so GPU process can access /dev/dri
|
||||
and VK_ICD_FILENAMES)
|
||||
--ignore-gpu-blocklist (force-enable Vulkan on Mali — Brave's
|
||||
internal blocklist may flag PanVk)
|
||||
|
||||
===== EVIDENCE OF SUCCESS =====
|
||||
|
||||
1. PanVk warning fires ONCE per GPU process startup (previously: 10x = 5
|
||||
crash-retries). GPU process is staying alive.
|
||||
|
||||
2. No "Exiting GPU process due to errors during initialization" message.
|
||||
|
||||
3. No "GLES3 is unsupported" / "eglCreateContext ES 3.0 failed" / "ANGLE
|
||||
Requires a minimum Vulkan device version of 1.1" errors.
|
||||
|
||||
4. Brave ran for the full 25-second timeout. Process exited cleanly on
|
||||
timeout (histograms emitted during shutdown).
|
||||
|
||||
5. Load page: https://www.example.com
|
||||
(Network fetch confirmed in logs.)
|
||||
|
||||
6. dmesg --since "1 minute ago": NO panfrost/mali/gpu faults.
|
||||
|
||||
7. Single benign warning:
|
||||
sandbox/policy/linux/sandbox_linux.cc:405: InitializeSandbox() called
|
||||
with multiple threads in process gpu-process.
|
||||
(Standard Linux GPU sandbox warning; non-fatal.)
|
||||
|
||||
===== ITER-BY-ITER FAILURE CHAIN (now resolved) =====
|
||||
|
||||
Run 1: stock libvulkan_panfrost.so + no env override
|
||||
→ Zink fell back to llvmpipe (iter8 RED finding).
|
||||
|
||||
Run 2: iter8-patched lib (robustness2 + nullDescriptor exposed)
|
||||
→ Zink loaded ✓, glxgears 250 FPS ✓ (iter8 GREEN partial).
|
||||
→ But Brave's GPU process still failed at "GLES3 unsupported".
|
||||
|
||||
Run 3: iter8-patched lib + --use-gl=disabled + --enable-features=Vulkan
|
||||
→ "'--ozone-platform=wayland' is not compatible with Vulkan"
|
||||
|
||||
Run 4: + --ozone-platform=x11
|
||||
→ "GLES3 is unsupported and ES version fallback is disabled" (ANGLE)
|
||||
|
||||
Run 5: + --use-gl=angle --use-angle=vulkan
|
||||
→ "ANGLE Requires a minimum Vulkan device version of 1.1"
|
||||
→ PanVk-Bifrost reports apiVersion=1.0.335
|
||||
|
||||
Run 6: + iter9 patch (has_vk1_1/has_vk1_2 = true) — apiVersion still 1.0
|
||||
→ has_vk1_1 only controls extensions, NOT api version
|
||||
|
||||
Run 7: + MESA_VK_VERSION_OVERRIDE=1.2 — apiVersion=1.2.335 ✓
|
||||
→ ANGLE Vulkan init succeeded ✓
|
||||
→ But ANGLE still couldn't create GLES 3.0 context (EGL_BAD_ATTRIBUTE)
|
||||
likely because PanVk-Bifrost lacks VK_EXT_transform_feedback
|
||||
|
||||
Run 8: + --use-gl=disabled (bypass ANGLE GL entirely)
|
||||
→ 🎯 GPU process boots, Brave runs, page loads, no faults.
|
||||
|
||||
===== WHAT'S STILL UNKNOWN =====
|
||||
|
||||
- Visual confirmation: did the Brave window actually render correctly on
|
||||
the PineTab2 screen? (Pending operator confirmation.)
|
||||
- chrome://gpu state — what does Brave think of GPU capabilities now?
|
||||
- Sustained workload: did pages with rich graphics work, or just simple
|
||||
text pages?
|
||||
- WebGL / WebGL2: blocked by ANGLE-GLES3 gap (no transform_feedback).
|
||||
Probably broken; can be tested separately.
|
||||
- Did Skia Graphite engage, or just classic Vulkan compositor?
|
||||
@@ -0,0 +1,207 @@
|
||||
Captured 2026-05-19 from ohm (PineTab2 v2.0 / RK3566 / Mali-G52 r1 MC1)
|
||||
Command: PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 vulkaninfo
|
||||
Stripped: leading "DISPLAY not set" / "XDG_RUNTIME_DIR invalid" stderr noise.
|
||||
|
||||
==========
|
||||
VULKANINFO
|
||||
==========
|
||||
|
||||
Vulkan Instance Version: 1.4.350
|
||||
|
||||
|
||||
Instance Extensions: count = 19
|
||||
===============================
|
||||
VK_EXT_acquire_xlib_display : extension revision 1
|
||||
VK_EXT_debug_report : extension revision 10
|
||||
VK_EXT_debug_utils : extension revision 2
|
||||
VK_EXT_direct_mode_display : extension revision 1
|
||||
VK_EXT_display_surface_counter : extension revision 1
|
||||
VK_EXT_headless_surface : extension revision 1
|
||||
VK_EXT_layer_settings : extension revision 2
|
||||
VK_KHR_device_group_creation : extension revision 1
|
||||
VK_KHR_display : extension revision 23
|
||||
VK_KHR_external_fence_capabilities : extension revision 1
|
||||
VK_KHR_external_memory_capabilities : extension revision 1
|
||||
VK_KHR_external_semaphore_capabilities : extension revision 1
|
||||
VK_KHR_get_physical_device_properties2 : extension revision 2
|
||||
VK_KHR_portability_enumeration : extension revision 1
|
||||
VK_KHR_surface : extension revision 25
|
||||
VK_KHR_wayland_surface : extension revision 6
|
||||
VK_KHR_xcb_surface : extension revision 6
|
||||
VK_KHR_xlib_surface : extension revision 6
|
||||
VK_LUNARG_direct_driver_loading : extension revision 1
|
||||
|
||||
Device Properties and Extensions:
|
||||
=================================
|
||||
GPU0:
|
||||
VkPhysicalDeviceProperties:
|
||||
---------------------------
|
||||
apiVersion = 1.0.335 (4194639)
|
||||
driverVersion = 26.0.6 (109051910)
|
||||
vendorID = 0x13b5
|
||||
deviceID = 0x74021000
|
||||
deviceType = PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
|
||||
deviceName = Mali-G52 r1 MC1
|
||||
pipelineCacheUUID = 287f3481-6415-7361-b1e9-14774b59e609
|
||||
|
||||
VkPhysicalDeviceLimits (selected):
|
||||
----------------------------------
|
||||
maxImageDimension1D = 65536
|
||||
maxImageDimension2D = 16383
|
||||
maxImageDimension3D = 512 # small — Bifrost limitation
|
||||
maxImageDimensionCube = 16383
|
||||
maxImageArrayLayers = 65536
|
||||
maxBoundDescriptorSets = 4 # LOW — many engines want 8
|
||||
maxPushConstantsSize = 256
|
||||
maxComputeSharedMemorySize = 32768
|
||||
maxComputeWorkGroupCount = 65535/65535/65535
|
||||
maxComputeWorkGroupInvocations = 384
|
||||
maxComputeWorkGroupSize = 384/384/384
|
||||
maxViewports = 1 # single viewport
|
||||
maxViewportDimensions = 16384/16384
|
||||
maxFramebufferWidth/Height/Layers = 16384/16384/256
|
||||
framebufferColorSampleCounts = {1x, 4x} # no 2x or 8x MSAA
|
||||
maxColorAttachments = 8
|
||||
timestampComputeAndGraphics = false # TIMESTAMPS BROKEN
|
||||
timestampPeriod = 0
|
||||
maxDrawIndirectCount = 1
|
||||
maxClipDistances = 0 # no gl_ClipDistance
|
||||
maxCullDistances = 0
|
||||
|
||||
VkPhysicalDeviceDriverPropertiesKHR:
|
||||
------------------------------------
|
||||
driverID = DRIVER_ID_MESA_PANVK
|
||||
driverName = panvk
|
||||
driverInfo = Mesa 26.0.6-arch1.1
|
||||
conformanceVersion = 0.0.0.0
|
||||
|
||||
VkPhysicalDeviceFeatures (selected, supported):
|
||||
-----------------------------------------------
|
||||
robustBufferAccess = true
|
||||
fullDrawIndexUint32 = true
|
||||
imageCubeArray = true
|
||||
independentBlend = true
|
||||
sampleRateShading = true
|
||||
dualSrcBlend = true
|
||||
logicOp = true
|
||||
drawIndirectFirstInstance = true
|
||||
depthClamp = true
|
||||
depthBiasClamp = true
|
||||
wideLines = true
|
||||
largePoints = true
|
||||
samplerAnisotropy = true
|
||||
textureCompressionETC2 = true
|
||||
textureCompressionASTC_LDR = true
|
||||
textureCompressionBC = true
|
||||
occlusionQueryPrecise = true
|
||||
shaderImageGatherExtended = true
|
||||
shaderStorageImageExtendedFormats = true
|
||||
shaderStorageImageReadWithoutFormat = true
|
||||
shaderStorageImageWriteWithoutFormat = true
|
||||
shaderUniformBufferArrayDynamicIndexing = true
|
||||
shaderSampledImageArrayDynamicIndexing = true
|
||||
shaderStorageBufferArrayDynamicIndexing = true
|
||||
shaderStorageImageArrayDynamicIndexing = true
|
||||
shaderInt64 = true
|
||||
shaderInt16 = true
|
||||
|
||||
VkPhysicalDeviceFeatures (selected, NOT supported):
|
||||
---------------------------------------------------
|
||||
geometryShader = false # Mali never had geometry
|
||||
tessellationShader = false # Mali never had tess
|
||||
multiDrawIndirect = false
|
||||
multiViewport = false
|
||||
alphaToOne = false
|
||||
fillModeNonSolid = false # no wireframe
|
||||
depthBounds = false
|
||||
pipelineStatisticsQuery = false
|
||||
vertexPipelineStoresAndAtomics = false
|
||||
fragmentStoresAndAtomics = false
|
||||
shaderTessellationAndGeometryPointSize = false
|
||||
shaderStorageImageMultisample = false
|
||||
shaderClipDistance = false
|
||||
shaderCullDistance = false
|
||||
shaderFloat64 = false
|
||||
shaderFloat16 = false # surprising — see 16bit_storage
|
||||
shaderResourceResidency = false
|
||||
shaderResourceMinLod = false
|
||||
sparseBinding = false # v10+ only
|
||||
sparseResidency* = false (all)
|
||||
variableMultisampleRate = false
|
||||
inheritedQueries = false
|
||||
|
||||
VkQueueFamilyProperties:
|
||||
------------------------
|
||||
queueProperties[0]:
|
||||
queueCount = 1
|
||||
queueFlags = QUEUE_GRAPHICS_BIT | QUEUE_COMPUTE_BIT | QUEUE_TRANSFER_BIT
|
||||
timestampValidBits = 0 # timestamps broken
|
||||
present support = false # no-surface query — needs WSI surface present
|
||||
|
||||
VkPhysicalDeviceMemoryProperties:
|
||||
---------------------------------
|
||||
memoryHeaps[0]:
|
||||
size = 6043143168 (5.63 GiB) # UMA — full system RAM as device-local
|
||||
flags = MEMORY_HEAP_DEVICE_LOCAL_BIT
|
||||
memoryTypes:
|
||||
[0] DEVICE_LOCAL_BIT
|
||||
[1] DEVICE_LOCAL_BIT | HOST_VISIBLE_BIT | HOST_CACHED_BIT
|
||||
[2] DEVICE_LOCAL_BIT | HOST_VISIBLE_BIT | HOST_COHERENT_BIT
|
||||
|
||||
Device Extensions: count = 118
|
||||
==============================
|
||||
[Full list — 118 extensions. Notable ones below; full list in repo at this path.]
|
||||
|
||||
VK_EXT_4444_formats VK_EXT_border_color_swizzle VK_EXT_buffer_device_address
|
||||
VK_EXT_calibrated_timestamps VK_EXT_custom_border_color VK_EXT_depth_bias_control
|
||||
VK_EXT_depth_clamp_zero_one VK_EXT_depth_clip_control VK_EXT_depth_clip_enable
|
||||
VK_EXT_device_memory_report VK_EXT_extended_dynamic_state VK_EXT_extended_dynamic_state2
|
||||
VK_EXT_external_memory_dma_buf VK_EXT_graphics_pipeline_library VK_EXT_hdr_metadata
|
||||
VK_EXT_host_image_copy VK_EXT_host_query_reset VK_EXT_image_drm_format_modifier
|
||||
VK_EXT_image_robustness VK_EXT_index_type_uint8 VK_EXT_inline_uniform_block
|
||||
VK_EXT_line_rasterization VK_EXT_load_store_op_none
|
||||
VK_EXT_multisampled_render_to_single_sampled VK_EXT_non_seamless_cube_map
|
||||
VK_EXT_physical_device_drm VK_EXT_pipeline_creation_cache_control
|
||||
VK_EXT_pipeline_robustness VK_EXT_primitive_topology_list_restart VK_EXT_private_data
|
||||
VK_EXT_provoking_vertex VK_EXT_queue_family_foreign VK_EXT_scalar_block_layout
|
||||
VK_EXT_separate_stencil_usage VK_EXT_shader_demote_to_helper_invocation
|
||||
VK_EXT_shader_module_identifier VK_EXT_shader_replicated_composites
|
||||
VK_EXT_shader_subgroup_ballot VK_EXT_shader_subgroup_vote VK_EXT_texel_buffer_alignment
|
||||
VK_EXT_texture_compression_astc_hdr VK_EXT_tooling_info VK_EXT_vertex_attribute_divisor
|
||||
VK_EXT_vertex_input_dynamic_state
|
||||
VK_KHR_16bit_storage VK_KHR_8bit_storage VK_KHR_bind_memory2
|
||||
VK_KHR_buffer_device_address VK_KHR_copy_commands2 VK_KHR_create_renderpass2
|
||||
VK_KHR_dedicated_allocation VK_KHR_depth_stencil_resolve
|
||||
VK_KHR_descriptor_update_template VK_KHR_device_group VK_KHR_driver_properties
|
||||
VK_KHR_dynamic_rendering VK_KHR_dynamic_rendering_local_read
|
||||
VK_KHR_external_fence VK_KHR_external_fence_fd VK_KHR_external_memory
|
||||
VK_KHR_external_memory_fd VK_KHR_external_semaphore VK_KHR_external_semaphore_fd
|
||||
VK_KHR_format_feature_flags2 VK_KHR_global_priority
|
||||
VK_KHR_image_format_list VK_KHR_imageless_framebuffer
|
||||
VK_KHR_index_type_uint8 VK_KHR_line_rasterization VK_KHR_load_store_op_none
|
||||
VK_KHR_maintenance1 VK_KHR_maintenance2 VK_KHR_maintenance3 VK_KHR_maintenance9
|
||||
VK_KHR_map_memory2 VK_KHR_multiview VK_KHR_pipeline_binary
|
||||
VK_KHR_pipeline_executable_properties VK_KHR_pipeline_library
|
||||
VK_KHR_present_id2 VK_KHR_present_wait2 VK_KHR_push_descriptor
|
||||
VK_KHR_relaxed_block_layout VK_KHR_sampler_mirror_clamp_to_edge
|
||||
VK_KHR_sampler_ycbcr_conversion VK_KHR_separate_depth_stencil_layouts
|
||||
VK_KHR_shader_clock VK_KHR_shader_draw_parameters VK_KHR_shader_expect_assume
|
||||
VK_KHR_shader_float16_int8 VK_KHR_shader_float_controls
|
||||
VK_KHR_shader_integer_dot_product VK_KHR_shader_non_semantic_info
|
||||
VK_KHR_shader_relaxed_extended_instruction VK_KHR_shader_subgroup_rotate
|
||||
VK_KHR_shader_terminate_invocation VK_KHR_storage_buffer_storage_class
|
||||
VK_KHR_swapchain VK_KHR_synchronization2 VK_KHR_timeline_semaphore
|
||||
VK_KHR_unified_image_layouts VK_KHR_uniform_buffer_standard_layout
|
||||
VK_KHR_variable_pointers VK_KHR_vertex_attribute_divisor
|
||||
VK_KHR_vulkan_memory_model VK_KHR_zero_initialize_workgroup_memory
|
||||
|
||||
NOT in extension list (worth noting):
|
||||
VK_EXT_descriptor_indexing # bindless descriptors
|
||||
VK_EXT_transform_feedback # XFB
|
||||
VK_EXT_conditional_rendering
|
||||
VK_KHR_ray_tracing_* # RT not on Bifrost
|
||||
VK_EXT_mesh_shader # mesh not on Bifrost
|
||||
VK_EXT_fragment_shader_interlock
|
||||
VK_EXT_fragment_density_map # Mali variable rate shading
|
||||
|
||||
End of vulkaninfo capture.
|
||||
Reference in New Issue
Block a user