.nornir/assets/osm-fly-gpu-path.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1320 560" font-family="'DejaVu Sans', 'Segoe UI', sans-serif">
<defs>
<linearGradient id="board" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#0b1c2e"/><stop offset="1" stop-color="#06111d"/>
</linearGradient>
<linearGradient id="chip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#14384f"/><stop offset="1" stop-color="#0e2a3e"/>
</linearGradient>
<linearGradient id="newchip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#1d6f4f"/><stop offset="1" stop-color="#10402f"/>
</linearGradient>
<linearGradient id="road" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#3a3550"/><stop offset="1" stop-color="#241f36"/>
</linearGradient>
<linearGradient id="bug" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#6f2330"/><stop offset="1" stop-color="#401018"/>
</linearGradient>
<marker id="arrow" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto">
<path d="M0,0 L7,3 L0,6 Z" fill="#6fd3f5"/>
</marker>
</defs>
<rect x="0" y="0" width="1320" height="560" fill="url(#board)"/>
<g stroke="#143a52" stroke-width="1"><line x1="0" y1="92" x2="1320" y2="92"/><line x1="0" y1="470" x2="1320" y2="470"/></g>
<g fill="#16415c"><circle cx="40" cy="40" r="2"/><circle cx="1280" cy="40" r="2"/><circle cx="40" cy="520" r="2"/><circle cx="1280" cy="520" r="2"/></g>
<!-- title -->
<text x="40" y="42" fill="#eaf6ff" font-size="22" font-weight="700">OSM-Fly · where the flight pixels go</text>
<text x="470" y="42" fill="#9fc9e0" font-size="14">the fix: <tspan fill="#7be3ad" font-weight="700">force the discrete RTX 5080</tspan>, not llvmpipe</text>
<g font-size="12">
<rect x="40" y="62" width="26" height="13" rx="3" fill="url(#newchip)"/><text x="72" y="73" fill="#cfe6f5">NEW (the fix)</text>
<rect x="200" y="62" width="26" height="13" rx="3" fill="url(#chip)"/><text x="232" y="73" fill="#cfe6f5">existing step</text>
<rect x="360" y="62" width="26" height="13" rx="3" fill="url(#road)"/><text x="392" y="73" fill="#cfe6f5">roadmapped (not landed)</text>
<line x1="600" y1="69" x2="636" y2="69" stroke="#6fd3f5" stroke-width="3" marker-end="url(#arrow)"/><text x="644" y="73" fill="#cfe6f5">data flow (shape on edge)</text>
</g>
<!-- LANDED lane (row 1) -->
<g text-anchor="middle">
<!-- 1 FlyWorld -->
<rect x="44" y="150" width="170" height="92" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="129" y="180" fill="#eaf6ff" font-size="13" font-weight="700">1 FlyWorld</text>
<text x="129" y="199" fill="#9fc9e0" font-size="10">terrain + buildings +</text>
<text x="129" y="213" fill="#9fc9e0" font-size="10">roads + 6DOF camera</text>
<text x="129" y="231" fill="#7fb0cc" font-size="9.5">facett-map3d-flight (CPU)</text>
<!-- 2 paint_world -->
<rect x="254" y="150" width="170" height="92" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="339" y="180" fill="#eaf6ff" font-size="13" font-weight="700">2 paint_world</text>
<text x="339" y="199" fill="#9fc9e0" font-size="10">CPU project + shade +</text>
<text x="339" y="213" fill="#9fc9e0" font-size="10">depth-sort → egui Mesh</text>
<text x="339" y="231" fill="#7fb0cc" font-size="9.5">osm_fly::paint_world</text>
<!-- 3 eframe wgpu -->
<rect x="464" y="150" width="170" height="92" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="549" y="180" fill="#eaf6ff" font-size="13" font-weight="700">3 eframe wgpu</text>
<text x="549" y="199" fill="#9fc9e0" font-size="10">upload mesh + draw</text>
<text x="549" y="213" fill="#9fc9e0" font-size="10">on the chosen adapter</text>
<text x="549" y="231" fill="#7fb0cc" font-size="9.5">egui_wgpu backend</text>
<!-- 4 gpu_select NEW -->
<rect x="674" y="150" width="190" height="92" rx="10" fill="url(#newchip)" stroke="#27a36f" stroke-width="2.2"/>
<text x="769" y="178" fill="#eaf6ff" font-size="13" font-weight="700">4 gpu_select (the fix)</text>
<text x="769" y="197" fill="#bfe7d4" font-size="10">Vulkan-only, reject Cpu</text>
<text x="769" y="211" fill="#bfe7d4" font-size="10">rasteriser; prefer Discrete</text>
<text x="769" y="231" fill="#7be3ad" font-size="9.5">REUSED from the main demo</text>
</g>
<g stroke="#6fd3f5" stroke-width="2.5" fill="none">
<line x1="214" y1="196" x2="250" y2="196" marker-end="url(#arrow)"/>
<line x1="424" y1="196" x2="460" y2="196" marker-end="url(#arrow)"/>
<line x1="634" y1="196" x2="670" y2="196" marker-end="url(#arrow)"/>
</g>
<g fill="#7fb0cc" font-size="9" text-anchor="middle">
<text x="232" y="190">scene</text><text x="442" y="190">mesh</text><text x="652" y="190">adapter?</text>
</g>
<!-- outcome: RTX -->
<rect x="924" y="150" width="360" height="92" rx="10" fill="url(#newchip)" stroke="#6fd3f5" stroke-width="2.2"/>
<text x="1104" y="180" fill="#eaf6ff" font-size="14" font-weight="700" text-anchor="middle">⚡ NVIDIA GeForce RTX 5080</text>
<text x="1104" y="200" fill="#bfe7d4" font-size="11" text-anchor="middle">[DiscreteGpu / Vulkan] — smooth flight</text>
<text x="1104" y="219" fill="#bfe7d4" font-size="10" text-anchor="middle">nvidia-smi util rises on the flight view</text>
<text x="1104" y="235" fill="#7be3ad" font-size="9.5" text-anchor="middle">logged at startup, verifiable</text>
<line x1="864" y1="196" x2="920" y2="196" stroke="#6fd3f5" stroke-width="2.5" marker-end="url(#arrow)"/>
<!-- BEFORE strike-through: llvmpipe -->
<rect x="674" y="270" width="190" height="52" rx="8" fill="url(#bug)" fill-opacity="0.35" stroke="#e0667a" stroke-width="1.6" stroke-dasharray="5 4"/>
<text x="769" y="292" fill="#f3c2cd" font-size="11" font-weight="700" text-anchor="middle">BEFORE: default pick</text>
<text x="769" y="309" fill="#ffd0db" font-size="10" text-anchor="middle">llvmpipe / iGPU ≈ 0.1 fps</text>
<line x1="769" y1="242" x2="769" y2="268" stroke="#e0667a" stroke-width="1.6" stroke-dasharray="4 4"/>
<!-- ROADMAP lane (row 2) -->
<text x="40" y="380" fill="#9ea0c4" font-size="13" font-weight="700">ROADMAPPED (not landed) — the true GPU flight renderer</text>
<g text-anchor="middle">
<rect x="44" y="398" width="200" height="60" rx="9" fill="url(#road)" stroke="#5a5478" stroke-width="1.8"/>
<text x="144" y="424" fill="#e7e3f5" font-size="12" font-weight="700">GPU scattering LUT</text>
<text x="144" y="442" fill="#b7b2cf" font-size="10">precompute pass (atmos)</text>
<rect x="264" y="398" width="200" height="60" rx="9" fill="url(#road)" stroke="#5a5478" stroke-width="1.8"/>
<text x="364" y="424" fill="#e7e3f5" font-size="12" font-weight="700">CDLOD terrain</text>
<text x="364" y="442" fill="#b7b2cf" font-size="10">quadtree LOD + drape</text>
<rect x="484" y="398" width="200" height="60" rx="9" fill="url(#road)" stroke="#5a5478" stroke-width="1.8"/>
<text x="584" y="424" fill="#e7e3f5" font-size="12" font-weight="700">GPU-compute extrude</text>
<text x="584" y="442" fill="#b7b2cf" font-size="10">indirect draw buildings</text>
<rect x="704" y="398" width="200" height="60" rx="9" fill="url(#road)" stroke="#5a5478" stroke-width="1.8"/>
<text x="804" y="424" fill="#e7e3f5" font-size="12" font-weight="700">out-of-core stream</text>
<text x="804" y="442" fill="#b7b2cf" font-size="10">Hilbert GeoParquet tiles</text>
</g>
<text x="924" y="432" fill="#7fb0cc" font-size="11">behind the <tspan fill="#cfe6f5" font-weight="700">facett-map3d-flight/wgpu</tspan> seam</text>
<text x="924" y="449" fill="#7fb0cc" font-size="11">(seam exists; no GPU code yet)</text>
<!-- footnote -->
<text x="40" y="502" fill="#5f93b0" font-size="11">The flight paint is still CPU (row 1, steps 1–2); the SMOOTHNESS win is step 4 — the <tspan fill="#cfe6f5">gpu_select</tspan> policy (reused, not forked) that stops eframe rasterising the egui meshes in software. Guarded RED-when-broken by <tspan fill="#cfe6f5">discrete_gpu_options_are_vulkan_create_new_highperf</tspan>.</text>
</svg>