Phase 10: iGPU passthrough — render/video group GID detection (0.10.0)
- gpu_service: detect host render/video group GIDs from /dev/dri node ownership (render node → render GID, paired card node → video GID); added to GPUInfo + exposed via /api/system/gpus. inject_dri now emits numeric group_add entries (e.g. ["991","44"]) when GIDs are known, falling back to names otherwise; remove_gpu strips those GIDs + LIBVA_DRIVER_NAME; dri_group_gids() for cleanup. - editor set-gpu passes render_gid/video_gid through; GPUSelector shows detected GIDs, defaults video group on, and sends them. Verified: py_compile, unit check (inject→["991","44"] then clean removal), frontend tsc build, image imports. Live iGPU verify is on the user's hardware. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a4e26f880a
commit
ec7e3e706f
@@ -23,11 +23,15 @@ export function GPUSelector({
|
||||
// dri
|
||||
const [vendor, setVendor] = useState<"intel" | "amd">("intel");
|
||||
const [renderGroup, setRenderGroup] = useState(true);
|
||||
const [videoGroup, setVideoGroup] = useState(false);
|
||||
const [videoGroup, setVideoGroup] = useState(true);
|
||||
const [libva, setLibva] = useState(false);
|
||||
|
||||
const nvidia = (gpus ?? []).filter((g) => g.vendor === "nvidia");
|
||||
const dri = (gpus ?? []).filter((g) => g.vendor !== "nvidia");
|
||||
// GIDs come from the matching detected GPU (host /dev/dri ownership).
|
||||
const driGpu = dri.find((g) => g.vendor === vendor) ?? dri[0];
|
||||
const renderGid = driGpu?.render_gid ?? null;
|
||||
const videoGid = driGpu?.video_gid ?? null;
|
||||
|
||||
const toggleCap = (c: string) =>
|
||||
setCaps((prev) => (prev.includes(c) ? prev.filter((x) => x !== c) : [...prev, c]));
|
||||
@@ -46,6 +50,8 @@ export function GPUSelector({
|
||||
add_render_group: renderGroup,
|
||||
add_video_group: videoGroup,
|
||||
set_libva: libva,
|
||||
render_gid: renderGid,
|
||||
video_gid: videoGid,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -134,11 +140,22 @@ export function GPUSelector({
|
||||
{dri.map((g) => `${g.name} → ${g.device_path}`).join(", ")}
|
||||
</p>
|
||||
)}
|
||||
{(renderGid != null || videoGid != null) ? (
|
||||
<p className="text-xs text-slate-500">
|
||||
Detected host GIDs — render: <span className="font-mono">{renderGid ?? "?"}</span>, video:{" "}
|
||||
<span className="font-mono">{videoGid ?? "?"}</span>. These are added as numeric{" "}
|
||||
<code>group_add</code> entries.
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-xs text-slate-400">
|
||||
No iGPU detected — render/video groups will be added by name.
|
||||
</p>
|
||||
)}
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
<input type="checkbox" checked={renderGroup} onChange={(e) => setRenderGroup(e.target.checked)} /> add render group
|
||||
<input type="checkbox" checked={renderGroup} onChange={(e) => setRenderGroup(e.target.checked)} /> add render group{renderGid != null ? ` (${renderGid})` : ""}
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
<input type="checkbox" checked={videoGroup} onChange={(e) => setVideoGroup(e.target.checked)} /> add video group
|
||||
<input type="checkbox" checked={videoGroup} onChange={(e) => setVideoGroup(e.target.checked)} /> add video group{videoGid != null ? ` (${videoGid})` : ""}
|
||||
</label>
|
||||
{vendor === "intel" && (
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
|
||||
Reference in New Issue
Block a user