Files
marfrit a4e7d8ab90 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>
2026-05-23 05:25:37 +02:00

88 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 0 — substrate for iter4
Opened **2026-05-19** after [iter3 close GREEN](phase8_iteration3_close.md).
## Locked research question — iter4
> **Sample a 4×4 R8G8B8A8_UNORM source texture (uploaded via staging buffer + `vkCmdCopyBufferToImage`) in a fragment shader via `texelFetch(sampler, ivec2(gl_FragCoord.xy) % 4, 0)`, into a 64×64 attachment. Verify every output pixel at (col, row) equals the source texel at (col%4, row%4) — a 16×16-tile-repeated 4×4 pattern.**
>
> Source texel encoding: `R = 0x10 + 0x40*x`, `G = 0x10 + 0x40*y`, `B = 0x80`, `A = 0xff` → texel(0,0) = `0xff801010`, texel(3,3) = `0xff80d0d0`. 16 unique values, position-identifiable.
>
> If GREEN → iter5 adds vertex buffer or UBO. If RED → first interesting bug, characterize against the Bifrost descriptor model.
## Why this shape
iter1+2+3 closed the compute, image-side, and graphics-pipeline paths. **iter4 is the first iter that exercises the Bifrost-specific descriptor model** (`PANVK_BIFROST_DESC_TABLE_COUNT`, `bifrost/panvk_vX_meta_desc_copy.c`, `panvk_vX_nir_lower_descriptors.c` Bifrost paths). This is the most-likely-to-find-bugs surface area we've encountered so far.
What iter4 adds:
- Source texture image (SAMPLED|TRANSFER_DST, 4×4 RGBA8)
- Texture upload via staging buffer + `vkCmdCopyBufferToImage`
- `VkImageView` on the texture (SHADER_READ layout target)
- `VkSampler` (NEAREST filter, CLAMP_TO_EDGE — sampler attached for descriptor binding but not exercised by `texelFetch`)
- Descriptor set layout with COMBINED_IMAGE_SAMPLER binding
- Descriptor pool + allocate set
- `vkUpdateDescriptorSets` with image+sampler
- Pipeline layout with descriptor set layout (non-empty)
- `vkCmdBindDescriptorSets` for graphics bind point
- Fragment shader with `texelFetch` from descriptor
What iter4 does *not* add: vertex buffer (still fullscreen triangle from `gl_VertexIndex`), UBO, push constants, multiple draws, mipmaps, MSAA, depth/stencil, sampler filtering (NEAREST + texelFetch == no filter), legacy render pass.
## Why `texelFetch` and not `texture()`
`texture(sampler, uv)` exercises filter logic (bilinear sampling, wrapping). Any bug there could mask whether the underlying *fetch* worked. `texelFetch` skips filtering and addressing — it's a direct memory-coordinate read. Isolates the descriptor model + image read from the sampler-state machinery.
If iter4 passes with `texelFetch`, iter5 can add `texture()` to test sampler state separately.
## Why 4×4 and not 1×1 or larger
- 1×1 would side-step any layout/tiling code in the source texture (single texel fits in one byte position).
- 4×4 fits in the smallest Mali tile (1×1 tile per Mali's accounting) but still has 16 distinct positions to verify against.
- Larger (8×8, 16×16, etc.) would add more verification work without exercising different code paths until we hit multi-tile boundaries — that's an iter6+ question.
## Hypothesis space — where iter4 may fail first
1. **Source texture upload (`vkCmdCopyBufferToImage` to TRANSFER_DST).** First time we go buffer→image (iter2 was image-clear, iter3 was image→buffer). Bifrost's tile-layout transform for *writes* into an optimal-tiled image may have bugs the read path didn't exercise.
2. **Layout transition TRANSFER_DST → SHADER_READ_ONLY_OPTIMAL.** New layout never used before. Cache-flush behavior between transfer-write and shader-read on Bifrost is implementation-specific.
3. **`VkSampler` creation.** First time. Sampler descriptor layout differs across Mali generations; Bifrost's may have stale fields the v7 path doesn't populate correctly.
4. **`VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` descriptor binding.** This is the **headline hypothesis**. Bifrost's descriptor table model (`PANVK_BIFROST_DESC_TABLE_COUNT`) is structurally different from Valhall's. iter1 used `STORAGE_BUFFER` (a simpler descriptor type), iter3 used no descriptors. This is the first test of the descriptor model on the graphics pipeline.
5. **NIR lowering for `texelFetch` on Bifrost.** `panvk_vX_nir_lower_descriptors.c` contains Bifrost-conditional paths (per the iter1 grep). If the lowering for sampled-image fetch on Bifrost is broken, we'll get a compile-time or run-time shader failure.
6. **Bifrost sampled-image read instruction emission.** Even with correct lowering, the actual ISA emission for `texelFetch` on Bifrost may have bugs. We can't easily distinguish this from H5 without `RADV_DEBUG=...`-style Mesa env vars (PanVk has `PAN_MESA_DEBUG=trace` etc. — out of scope for iter4 unless we hit a failure).
## Phase 0 deliverables
- This document.
- iter4 in scope: the textured-quad probe.
## In-scope (LOCKED 2026-05-19 for iter4)
- Hardware: ohm only.
- Source texture: 4×4 R8G8B8A8_UNORM, optimal tiling, SAMPLED|TRANSFER_DST.
- Sampler: NEAREST filter, CLAMP_TO_EDGE (attached for descriptor; not exercised by texelFetch).
- Pipeline: 1 descriptor set with 1 COMBINED_IMAGE_SAMPLER binding.
- Fragment shader: `texelFetch(tex, ivec2(gl_FragCoord.xy) % 4, 0)`.
- Verify: every pixel matches modulo-4 tile-repeated pattern.
## Out-of-scope (LOCKED 2026-05-19 for iter4)
- Vertex buffer / vertex input.
- UBO, SSBO, push constants.
- Sampler filtering (NEAREST + texelFetch == no filter).
- Mipmaps, layered textures, depth textures.
- Legacy render pass.
- MSAA.
- Multiple textures / multiple descriptor bindings.
- Image format other than RGBA8 UNORM.
- Mesa debug env vars (`PAN_MESA_DEBUG`, etc.) — defer until needed.
## Reference
- [phase0_findings.md](phase0_findings.md) — campaign substrate.
- [phase8_iteration{1,2,3}_close.md](phase8_iteration1_close.md) — prior iter closes.
- Mesa source: `src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c`, `bifrost/panvk_vX_meta_desc_copy.c`, `panvk_vX_cmd_desc_state.c`.