a4e7d8ab90
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>
72 lines
4.5 KiB
Markdown
72 lines
4.5 KiB
Markdown
# Iteration 2 close — GREEN
|
||
|
||
Closed **2026-05-19** by mfritsche + claude-noether, same session as iter1 close.
|
||
|
||
## Locked question
|
||
|
||
(From [phase0_findings_iter2.md](phase0_findings_iter2.md))
|
||
|
||
> Get a minimal Vulkan image-side workload to execute end-to-end on PanVk-Bifrost: create a 4×4 `VK_FORMAT_R8G8B8A8_UNORM` image, transition UNDEFINED → TRANSFER_DST, `vkCmdClearColorImage` to 0x11223344, transition TRANSFER_DST → TRANSFER_SRC, `vkCmdCopyImageToBuffer` to host-visible staging, fence-wait, verify all 16 pixels read back as 0x44332211.
|
||
|
||
## Result: GREEN
|
||
|
||
7/7 runs PASS (1 baseline + 1 with `VK_LAYER_KHRONOS_validation` + 5 stability). All 16 pixels match exactly. No GPU faults, no MMU faults, no kernel-side panfrost messages, no validation-layer warnings or errors.
|
||
|
||
Evidence: [`phase0_evidence/iter2_image_clear_run.txt`](phase0_evidence/iter2_image_clear_run.txt).
|
||
|
||
## What the close tells us
|
||
|
||
Four image-side hypotheses from [phase0_findings_iter2.md](phase0_findings_iter2.md) were tested. All four work:
|
||
|
||
| Hypothesis | Status at iter2 |
|
||
|---|---|
|
||
| H1: image creation + memory binding | ✗ no — `vkCreateImage` + `vkGetImageMemoryRequirements` + bind work for 4×4 RGBA8 optimal-tiled (4096-byte aligned allocation) |
|
||
| H2: layout transitions | ✗ no — UNDEFINED→TRANSFER_DST and TRANSFER_DST→TRANSFER_SRC both clean |
|
||
| H3: `vkCmdClearColorImage` lowering | ✗ no — clear lands in image correctly |
|
||
| H4: `vkCmdCopyImageToBuffer` + Bifrost tile decode | ✗ no — all 16 pixels round-trip with no shuffling, no rounding error |
|
||
|
||
The image-side transfer path on PanVk-Bifrost is functional for this minimal case. Combined with iter1, we now know the following work end-to-end:
|
||
|
||
- Vulkan instance + physical device + logical device + queue
|
||
- Buffer create + alloc + bind + map (host-visible)
|
||
- Image create + alloc + bind (device-local)
|
||
- Image layout transitions via `vkCmdPipelineBarrier`
|
||
- `vkCmdClearColorImage` (transfer-op level, not via shader)
|
||
- `vkCmdCopyImageToBuffer` with Bifrost tile-layout decode
|
||
- Compute pipeline: shader module + pipeline layout + compute pipeline + dispatch
|
||
- Command buffer recording + submit + fence wait + memory barriers (memory + image + buffer)
|
||
|
||
What we still **don't know works**: graphics pipeline (vertex + fragment + rasterizer + render pass / dynamic rendering).
|
||
|
||
## iter2 in-tree artifacts
|
||
|
||
- [`iter2/probe_image_clear.c`](iter2/probe_image_clear.c) — ~340 LoC, pure Vulkan 1.0 core
|
||
- [`iter2/Makefile`](iter2/Makefile) — `make` builds, `make run` / `make run-validation`
|
||
|
||
## Deferred to iter3+ (not in iter2 scope)
|
||
|
||
- Vertex + fragment shaders
|
||
- Render pass and/or dynamic rendering
|
||
- Graphics pipeline state (rasterizer, viewport, blend, depth)
|
||
- Larger images, mipmaps, layered images, MSAA
|
||
- Other formats (R32G32B32A32_SFLOAT, BC/ETC2/ASTC compressed, depth/stencil)
|
||
- WSI / swapchain (iter4+)
|
||
- TuxRacer / Zink-on-PanVk
|
||
|
||
## Next iter — iter3 lock proposal
|
||
|
||
Smallest viable graphics workload that exercises the **rasterizer + shaders**:
|
||
|
||
> **Render a single full-screen triangle into a 64×64 R8G8B8A8_UNORM color attachment via dynamic rendering (`VK_KHR_dynamic_rendering`), using a trivial vertex shader (no vertex buffer — emit positions from `gl_VertexIndex`) and a trivial fragment shader (output constant color `gl_FragCoord`-encoded so we can detect rasterizer correctness). Copy attachment to host-visible buffer. Verify: (a) some pixels are written (not all sentinel), (b) at least one pixel has the encoded `gl_FragCoord` value matching its position.**
|
||
|
||
Justifications:
|
||
- 64×64 (not 4×4) so multiple tiles get exercised — Bifrost is a tile-based rasterizer, so single-tile workloads might side-step real tile binning.
|
||
- Dynamic rendering instead of render pass — simpler API surface, no framebuffer object, no subpass dependencies. Render pass / framebuffer can be iter3.5 if needed.
|
||
- Fullscreen triangle from `gl_VertexIndex` so no vertex buffer needed — exercises pipeline-state but not vertex-input-state.
|
||
- Trivial fragment shader (no textures, no UBO, no SSBO) — exercises rasterization + frag shader output but not descriptor lookups (proven in iter1 anyway).
|
||
- `gl_FragCoord`-encoded color so a wrong-rasterization bug (e.g. swapped-Y framebuffer convention, off-by-pixel) is detectable from pixel data.
|
||
|
||
If iter3 turns up the first real failure, that's the campaign's first interesting bug. If iter3 also passes, iter4 adds vertex buffer + UBO + a texture sample, and we're well into "actually exercising PanVk-Bifrost" territory.
|
||
|
||
Pacing: same 8-phase cadence. iter3 phase 0 substrate lock when the operator opens.
|