mirror of
https://github.com/nestriness/nestri.git
synced 2026-05-01 10:53:08 +03:00
feat: Init
This commit is contained in:
484
build/Dockerfile
Normal file
484
build/Dockerfile
Normal file
@@ -0,0 +1,484 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
# =============================================================================
|
||||
# Nestri – Unified Multi-stage Build
|
||||
# =============================================================================
|
||||
#
|
||||
# Build graph (BuildKit runs independent branches in parallel):
|
||||
#
|
||||
# initial ─► builder ──┬─► libkrunfw-build ─► libkrun-build ──┐
|
||||
# ├─► virgl-build ───────────────────────┤
|
||||
# ├─► mesa-build ─► lib32-mesa-build │
|
||||
# │ │
|
||||
# └─► rust-builder ─┬─► gst-wayland-build
|
||||
# ├─► wl-proxy-build
|
||||
# ├─► nestrisink-build
|
||||
# └─► muvm-build ◄─────┘
|
||||
#
|
||||
# initial ─► runner ◄── all build stages
|
||||
#
|
||||
# Build:
|
||||
# docker buildx build --target runner -t nestri:latest .
|
||||
#
|
||||
# Recommended .dockerignore:
|
||||
# target/
|
||||
# .git/
|
||||
# *.md
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# initial
|
||||
#******************************************************************************
|
||||
# Minimal updated Arch Linux base. Every other stage inherits from here.
|
||||
FROM docker.io/archlinux/archlinux:latest AS initial
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -Syu --noconfirm
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# builder
|
||||
#******************************************************************************
|
||||
# builder has C/C++ tooling, makepkg, and a non-root build user.
|
||||
FROM initial AS builder
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm \
|
||||
base-devel \
|
||||
clang \
|
||||
cmake \
|
||||
git \
|
||||
meson \
|
||||
ninja \
|
||||
python \
|
||||
pkg-config
|
||||
|
||||
WORKDIR /scratch
|
||||
|
||||
ENV ARTIFACTS=/artifacts
|
||||
RUN mkdir -p "$ARTIFACTS"
|
||||
|
||||
# makepkg refuses to run as root
|
||||
RUN useradd -m builder \
|
||||
&& echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
|
||||
# Maximise build parallelism
|
||||
RUN sed -i "s/#MAKEFLAGS=.*/MAKEFLAGS=\"-j$(nproc)\"/" /etc/makepkg.conf
|
||||
|
||||
# Let the builder user write to /scratch and /artifacts
|
||||
RUN chgrp builder /scratch "$ARTIFACTS" \
|
||||
&& chmod g+ws /scratch "$ARTIFACTS"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# rust-builder
|
||||
#******************************************************************************
|
||||
# rust-builder adds the Rust toolchain and common crate build deps.
|
||||
FROM builder AS rust-builder
|
||||
|
||||
ENV CARGO_HOME=/usr/local/cargo
|
||||
ENV PATH="${CARGO_HOME}/bin:${PATH}"
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm \
|
||||
rust \
|
||||
cargo \
|
||||
gstreamer \
|
||||
gst-plugins-base \
|
||||
gst-plugins-good \
|
||||
gst-plugins-bad \
|
||||
libdrm \
|
||||
libxkbcommon \
|
||||
wayland \
|
||||
wayland-protocols \
|
||||
libinput \
|
||||
libseccomp \
|
||||
libcap
|
||||
|
||||
# cargo-c is needed by gst-wayland-display (cargo cinstall)
|
||||
RUN --mount=type=cache,target=${CARGO_HOME}/registry \
|
||||
--mount=type=cache,target=${CARGO_HOME}/git \
|
||||
cargo install cargo-c
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# libkrunfw-build
|
||||
#******************************************************************************
|
||||
# Build libkrunfw package with 32-bit support.
|
||||
FROM builder AS libkrunfw-build
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm --needed \
|
||||
bc \
|
||||
python-pyelftools \
|
||||
cpio \
|
||||
curl \
|
||||
wget
|
||||
|
||||
COPY build/packages/libkrunfw/ /scratch/libkrunfw/
|
||||
WORKDIR /scratch/libkrunfw
|
||||
|
||||
RUN chown -R builder:builder .
|
||||
USER builder
|
||||
RUN makepkg --syncdeps --noconfirm --skippgpcheck \
|
||||
&& cp *.zst "$ARTIFACTS"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# libkrun-build
|
||||
#******************************************************************************
|
||||
# Build libkrun package (depends on libkrunfw).
|
||||
FROM builder AS libkrun-build
|
||||
|
||||
# Install previously-built libkrunfw
|
||||
WORKDIR /scratch
|
||||
COPY --from=libkrunfw-build /artifacts/*.zst pkgs/
|
||||
RUN pacman -U --noconfirm pkgs/*.zst && rm -rf pkgs
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm --needed \
|
||||
rust \
|
||||
cargo \
|
||||
patchelf \
|
||||
clang \
|
||||
clang18 \
|
||||
pipewire \
|
||||
virglrenderer
|
||||
|
||||
COPY build/packages/libkrun/ /scratch/libkrun/
|
||||
WORKDIR /scratch/libkrun
|
||||
|
||||
RUN chown -R builder:builder .
|
||||
USER builder
|
||||
# NOTE: clang18 required – newer versions fail to build libkrun
|
||||
RUN LIBCLANG_PATH=/usr/lib/llvm18/lib \
|
||||
makepkg --syncdeps --noconfirm --skippgpcheck \
|
||||
&& cp *.zst "$ARTIFACTS"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# virgl-build
|
||||
#******************************************************************************
|
||||
# Build virglrenderer package.
|
||||
FROM builder AS virgl-build
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm --needed \
|
||||
python-yaml \
|
||||
libepoxy \
|
||||
mesa \
|
||||
libva \
|
||||
libdrm \
|
||||
vulkan-headers \
|
||||
vulkan-icd-loader \
|
||||
libx11 \
|
||||
glu
|
||||
|
||||
COPY build/virglrenderer/ /scratch/virglrenderer/
|
||||
WORKDIR /scratch/virglrenderer
|
||||
|
||||
RUN chown -R builder:builder .
|
||||
USER builder
|
||||
RUN makepkg --syncdeps --noconfirm --skippgpcheck --skipinteg \
|
||||
&& cp *.zst "$ARTIFACTS"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# mesa-build
|
||||
#******************************************************************************
|
||||
# Build Mesa packages (64-bit).
|
||||
FROM builder AS mesa-build
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm --needed \
|
||||
git \
|
||||
python-mako \
|
||||
python-packaging \
|
||||
python-yaml \
|
||||
llvm \
|
||||
rust \
|
||||
rust-bindgen \
|
||||
cbindgen \
|
||||
clang \
|
||||
glslang \
|
||||
wayland-protocols \
|
||||
libvdpau \
|
||||
libva \
|
||||
libxrandr
|
||||
|
||||
COPY build/mesa/ /scratch/mesa/
|
||||
WORKDIR /scratch/mesa
|
||||
|
||||
RUN chown -R builder:builder .
|
||||
USER builder
|
||||
RUN makepkg --syncdeps --noconfirm --skippgpcheck --skipinteg \
|
||||
&& cp *.zst "$ARTIFACTS"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# lib32-mesa-build
|
||||
#******************************************************************************
|
||||
# Build 32-bit Mesa packages (depends on 64-bit mesa).
|
||||
FROM builder AS lib32-mesa-build
|
||||
|
||||
# Enable multilib repository for 32-bit dependencies
|
||||
RUN echo -e "\n[multilib]\nInclude = /etc/pacman.d/mirrorlist" \
|
||||
>> /etc/pacman.conf
|
||||
|
||||
# Install 64-bit mesa packages first
|
||||
WORKDIR /scratch
|
||||
COPY --from=mesa-build /artifacts/*.zst pkgs/
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -Syu --noconfirm \
|
||||
&& pacman -U --noconfirm pkgs/*.zst \
|
||||
&& rm -rf pkgs
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm --needed \
|
||||
git \
|
||||
python-mako \
|
||||
python-packaging \
|
||||
python-yaml \
|
||||
llvm \
|
||||
rust \
|
||||
rust-bindgen \
|
||||
cbindgen \
|
||||
clang \
|
||||
glslang \
|
||||
wayland-protocols \
|
||||
libvdpau \
|
||||
libva \
|
||||
libxrandr \
|
||||
lib32-gcc-libs \
|
||||
lib32-libx11 \
|
||||
lib32-libdrm \
|
||||
lib32-llvm \
|
||||
lib32-expat \
|
||||
lib32-libelf \
|
||||
lib32-zstd \
|
||||
lib32-wayland
|
||||
|
||||
COPY build/packages/lib32-mesa/ /scratch/lib32-mesa/
|
||||
WORKDIR /scratch/lib32-mesa
|
||||
|
||||
RUN chown -R builder:builder .
|
||||
USER builder
|
||||
RUN makepkg --syncdeps --noconfirm --skippgpcheck --skipinteg \
|
||||
&& cp *.zst "$ARTIFACTS"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# gst-wayland-build
|
||||
#******************************************************************************
|
||||
# Build gst-wayland-display plugin.
|
||||
FROM rust-builder AS gst-wayland-build
|
||||
|
||||
WORKDIR /scratch/gst-wayland-display
|
||||
RUN git clone https://github.com/games-on-whales/gst-wayland-display.git . \
|
||||
&& git checkout 67b1183997fd7aaf57398e4b01bd64c4d2433c45
|
||||
|
||||
RUN --mount=type=cache,target=${CARGO_HOME}/registry \
|
||||
--mount=type=cache,target=${CARGO_HOME}/git \
|
||||
--mount=type=cache,target=/scratch/gst-wayland-display/target \
|
||||
cargo cinstall --prefix="${ARTIFACTS}/usr" --release --features cuda
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# wl-proxy-build
|
||||
#******************************************************************************
|
||||
# Build wl-cross-domain-proxy.
|
||||
FROM rust-builder AS wl-proxy-build
|
||||
|
||||
WORKDIR /scratch/wl-cross-domain-proxy
|
||||
RUN git clone https://codeberg.org/drakulix/wl-cross-domain-proxy.git . \
|
||||
&& git checkout c6ce1ca89fb4d6f4f18d3aaf88324d40d4589177
|
||||
|
||||
RUN --mount=type=cache,target=${CARGO_HOME}/registry \
|
||||
--mount=type=cache,target=${CARGO_HOME}/git \
|
||||
--mount=type=cache,target=/scratch/wl-cross-domain-proxy/target \
|
||||
cargo build --release \
|
||||
&& install -Dm755 target/release/wl-cross-domain-proxy \
|
||||
"${ARTIFACTS}/usr/bin/wl-cross-domain-proxy"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# nestrisink-build
|
||||
#******************************************************************************
|
||||
# Build nestri GStreamer sink plugin.
|
||||
FROM rust-builder AS nestrisink-build
|
||||
|
||||
WORKDIR /scratch/nestrisink
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY crates/ ./crates/
|
||||
COPY apps/ ./apps/
|
||||
|
||||
RUN --mount=type=cache,target=${CARGO_HOME}/registry \
|
||||
--mount=type=cache,target=${CARGO_HOME}/git \
|
||||
--mount=type=cache,target=/scratch/nestrisink/target \
|
||||
cargo build -p nestri-gst --release \
|
||||
&& mkdir -p "${ARTIFACTS}/usr/lib/gstreamer-1.0" \
|
||||
&& cp target/release/libgstnestri.so \
|
||||
"${ARTIFACTS}/usr/lib/gstreamer-1.0/"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# muvm-build
|
||||
#******************************************************************************
|
||||
# Build muvm binary (depends on libkrun + virgl packages).
|
||||
FROM rust-builder AS muvm-build
|
||||
|
||||
# Install custom-built packages that muvm links against
|
||||
WORKDIR /scratch
|
||||
COPY --from=libkrunfw-build /artifacts/*.zst pkgs/
|
||||
COPY --from=libkrun-build /artifacts/*.zst pkgs/
|
||||
COPY --from=virgl-build /artifacts/*.zst pkgs/
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm --needed pipewire \
|
||||
&& pacman -U --noconfirm pkgs/*.zst \
|
||||
&& rm -rf pkgs
|
||||
|
||||
WORKDIR /scratch/muvm
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY crates/ ./crates/
|
||||
COPY apps/ ./apps/
|
||||
COPY share/ ./share/
|
||||
|
||||
RUN --mount=type=cache,target=${CARGO_HOME}/registry \
|
||||
--mount=type=cache,target=${CARGO_HOME}/git \
|
||||
--mount=type=cache,target=/scratch/muvm/target \
|
||||
cargo build -p muvm --release \
|
||||
&& install -Dm755 target/release/muvm "${ARTIFACTS}/usr/bin/muvm" \
|
||||
&& install -Dm755 target/release/muvm-guest "${ARTIFACTS}/usr/bin/muvm-guest"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# runner
|
||||
#******************************************************************************
|
||||
# The final runtime image – kept as simple as possible.
|
||||
FROM initial AS runner
|
||||
|
||||
# ---- Enable multilib for 32-bit packages ----
|
||||
RUN echo -e "\n[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
|
||||
|
||||
# ---- Collect and install custom-built .zst packages ----
|
||||
COPY --from=mesa-build /artifacts/*.zst /tmp/pkgs/
|
||||
COPY --from=lib32-mesa-build /artifacts/*.zst /tmp/pkgs/
|
||||
COPY --from=libkrunfw-build /artifacts/*.zst /tmp/pkgs/
|
||||
COPY --from=libkrun-build /artifacts/*.zst /tmp/pkgs/
|
||||
COPY --from=virgl-build /artifacts/*.zst /tmp/pkgs/
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -Syu --noconfirm \
|
||||
&& pacman -U --noconfirm /tmp/pkgs/*.zst \
|
||||
&& rm -rf /tmp/pkgs
|
||||
|
||||
# ---- System runtime packages (single transaction for consistency) ----
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman/pkg \
|
||||
pacman -S --noconfirm \
|
||||
# Core
|
||||
base systemd sudo bash \
|
||||
# Steam & Gaming
|
||||
steam gamescope mangohud seatd \
|
||||
# Vulkan / Mesa / VA-API
|
||||
vulkan-icd-loader vulkan-tools lib32-vulkan-icd-loader \
|
||||
libva-mesa-driver libva-utils \
|
||||
# Wayland / X
|
||||
wayland libdrm libxkbcommon \
|
||||
xorg-xwayland xwayland-satellite \
|
||||
libinput \
|
||||
# Audio
|
||||
pipewire pipewire-pulse pipewire-alsa wireplumber \
|
||||
lib32-libpulse \
|
||||
# GStreamer runtime plugins
|
||||
gstreamer gst-plugins-base \
|
||||
gst-plugins-good gst-plugins-bad \
|
||||
gst-plugin-isobmff gst-plugin-va \
|
||||
gst-plugin-pipewire gst-plugin-qsv \
|
||||
# Video acceleration
|
||||
vpl-gpu-rt \
|
||||
# GUI / Fonts
|
||||
gtk3 lib32-gtk3 \
|
||||
ttf-liberation noto-fonts-cjk \
|
||||
# Networking & System
|
||||
dbus curl passt openssh hwdata \
|
||||
jq pacman-contrib lib32-libvdpau
|
||||
|
||||
# ---- Copy artifacts from Rust build stages ----
|
||||
COPY --from=wl-proxy-build /artifacts/usr/ /usr/
|
||||
COPY --from=gst-wayland-build /artifacts/usr/ /usr/
|
||||
COPY --from=nestrisink-build /artifacts/usr/ /usr/
|
||||
COPY --from=muvm-build /artifacts/usr/ /usr/
|
||||
|
||||
# ---- muvm-guest multi-call symlinks ----
|
||||
RUN mkdir -p /opt/bin \
|
||||
&& ln -sf /usr/bin/muvm-guest /opt/bin/muvm-remote \
|
||||
&& ln -sf /usr/bin/muvm-guest /opt/bin/muvm-configure-network \
|
||||
&& ln -sf /usr/bin/muvm-guest /opt/bin/muvm-pwbridge
|
||||
|
||||
# ---- User setup ----
|
||||
ARG NESTRI_USER_PWD=""
|
||||
ENV NESTRI_USER="nestri" \
|
||||
NESTRI_UID=1000 \
|
||||
NESTRI_GID=1000 \
|
||||
NESTRI_LANG=en_US.UTF-8 \
|
||||
NESTRI_XDG_RUNTIME_DIR=/run/user/1000 \
|
||||
NESTRI_HOME=/home/nestri \
|
||||
NVIDIA_DRIVER_CAPABILITIES=all
|
||||
|
||||
RUN mkdir -p "/home/${NESTRI_USER}" \
|
||||
&& groupadd -g "${NESTRI_GID}" "${NESTRI_USER}" \
|
||||
&& useradd -d "/home/${NESTRI_USER}" \
|
||||
-u "${NESTRI_UID}" -g "${NESTRI_GID}" \
|
||||
-s /bin/bash "${NESTRI_USER}" \
|
||||
&& echo "${NESTRI_USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
|
||||
&& NESTRI_USER_PWD="${NESTRI_USER_PWD:-$(openssl rand -base64 12)}" \
|
||||
&& echo "Setting password for ${NESTRI_USER}" \
|
||||
&& echo "${NESTRI_USER}:${NESTRI_USER_PWD}" | chpasswd \
|
||||
&& mkdir -p "${NESTRI_XDG_RUNTIME_DIR}" \
|
||||
&& chown "${NESTRI_USER}:${NESTRI_USER}" "${NESTRI_XDG_RUNTIME_DIR}" \
|
||||
&& usermod -aG input,video,render,seat,wheel,systemd-journal "${NESTRI_USER}"
|
||||
|
||||
# ---- Wireplumber suspend disable ----
|
||||
RUN mkdir -p /run/dbus \
|
||||
&& sed -i -z \
|
||||
-e 's/{[[:space:]]*name = node\/suspend-node\.lua,[[:space:]]*type = script\/lua[[:space:]]*provides = hooks\.node\.suspend[[:space:]]*}[[:space:]]*//g' \
|
||||
-e '/wants = \[/{s/hooks\.node\.suspend\s*//; s/,\s*\]/]/}' \
|
||||
/usr/share/wireplumber/wireplumber.conf
|
||||
|
||||
# ---- Audio & config directories ----
|
||||
COPY etc/ /etc/
|
||||
|
||||
# ---- Steam config ----
|
||||
RUN mkdir -p "${NESTRI_HOME}/.local/share/Steam/config"
|
||||
COPY build/steam/config.vdf "${NESTRI_HOME}/.local/share/Steam/config/"
|
||||
|
||||
# ---- Mask noisy/broken services ----
|
||||
RUN systemctl mask \
|
||||
dm-event.socket \
|
||||
systemd-firstboot.service \
|
||||
systemd-homed.service \
|
||||
systemd-hwdb-update.service \
|
||||
systemd-network-generator.service \
|
||||
systemd-networkd.service \
|
||||
systemd-networkd-wait-online.service \
|
||||
systemd-remount-fs.service \
|
||||
systemd-resolved.service \
|
||||
systemd-timesyncd.service \
|
||||
systemd-userdbd.service \
|
||||
getty@tty1.service \
|
||||
serial-getty@.service
|
||||
|
||||
# ---- Systemd units ----
|
||||
RUN systemctl enable dbus.service \
|
||||
&& systemctl set-default microvm.target
|
||||
|
||||
# ---- Scripts (copied last – they change the most) ----
|
||||
COPY build/usr/bin/ /usr/bin/
|
||||
|
||||
# ---- Smoke test ----
|
||||
RUN command -v steam muvm muvm-guest wl-cross-domain-proxy \
|
||||
nestri-entry nestri-init
|
||||
|
||||
# ---- Final cleanup ----
|
||||
RUN rm -rf /tmp/*
|
||||
48
build/etc/nestri/configs/MangoHud/MangoHud.conf
Normal file
48
build/etc/nestri/configs/MangoHud/MangoHud.conf
Normal file
@@ -0,0 +1,48 @@
|
||||
legacy_layout=false
|
||||
|
||||
# common
|
||||
horizontal
|
||||
horizontal_stretch
|
||||
hud_no_margin
|
||||
no_small_font
|
||||
background_alpha=0.66
|
||||
round_corners=0
|
||||
background_color=000000
|
||||
font_size=24
|
||||
position=top-left
|
||||
engine_short_names
|
||||
|
||||
# colors
|
||||
text_color=DFDFDF
|
||||
gpu_color=FF4E00
|
||||
cpu_color=00AA00
|
||||
engine_color=00AA00
|
||||
vram_color=00AA00
|
||||
ram_color=00AA00
|
||||
frametime_color=FF4E00
|
||||
|
||||
# load colors
|
||||
cpu_load_color=DFDFDF,DF964D,DF3D3D
|
||||
gpu_load_color=DFDFDF,DF964D,DF3D3D
|
||||
|
||||
# GPU and VRAM
|
||||
gpu_text=NESTRI
|
||||
gpu_stats
|
||||
gpu_load_change
|
||||
gpu_load_value=70,90
|
||||
|
||||
vram
|
||||
|
||||
# CPU and RAM
|
||||
cpu_text=CPU
|
||||
cpu_stats
|
||||
cpu_load_change
|
||||
cpu_load_value=70,90
|
||||
|
||||
ram
|
||||
|
||||
# FPS and timing
|
||||
fps
|
||||
fps_metrics=0.01
|
||||
|
||||
frame_timing
|
||||
26
build/etc/pipewire/pipewire.conf.d/nestri-loopback.conf
Normal file
26
build/etc/pipewire/pipewire.conf.d/nestri-loopback.conf
Normal file
@@ -0,0 +1,26 @@
|
||||
context.modules = [
|
||||
{
|
||||
name = libpipewire-module-loopback
|
||||
args = {
|
||||
node.description = "Nestri Audio"
|
||||
capture.props = {
|
||||
node.name = "nestri-sink"
|
||||
media.class = "Audio/Sink"
|
||||
media.type = "Audio"
|
||||
audio.position = [FL FR]
|
||||
node.always-process = true
|
||||
session.suspend-timeout-seconds = 0
|
||||
priority.session = 10000
|
||||
priority.driver = 10000
|
||||
}
|
||||
playback.props = {
|
||||
node.name = "nestri-source"
|
||||
media.class = "Audio/Source"
|
||||
media.type = "Audio"
|
||||
audio.position = [FL FR]
|
||||
node.always-process = true
|
||||
session.suspend-timeout-seconds = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
context.properties = {
|
||||
default.clock.rate = 48000
|
||||
default.clock.allowed-rates = [48000]
|
||||
default.clock.min-quantum = 128
|
||||
default.clock.max-quantum = 1024
|
||||
default.clock.quantum = 512
|
||||
}
|
||||
4
build/etc/systemd/system/microvm.target
Normal file
4
build/etc/systemd/system/microvm.target
Normal file
@@ -0,0 +1,4 @@
|
||||
[Unit]
|
||||
Description=Nestri microVM system
|
||||
AllowIsolate=yes
|
||||
Wants=systemd-journald.socket systemd-udevd.service dbus.socket
|
||||
@@ -0,0 +1 @@
|
||||
../nestri-network.service
|
||||
@@ -0,0 +1 @@
|
||||
../nestri-pipewire-pulse.socket
|
||||
@@ -0,0 +1 @@
|
||||
../nestri-pwbridge.socket
|
||||
@@ -0,0 +1 @@
|
||||
../nestri-remote.service
|
||||
@@ -0,0 +1 @@
|
||||
../nestri-session-bus.socket
|
||||
@@ -0,0 +1 @@
|
||||
../nestri-user-session.service
|
||||
@@ -0,0 +1 @@
|
||||
../nestri-wayland-proxy.socket
|
||||
14
build/etc/systemd/system/nestri-network.service
Normal file
14
build/etc/systemd/system/nestri-network.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Configure VM network via muvm
|
||||
DefaultDependencies=no
|
||||
Before=network.target
|
||||
After=systemd-udevd.service
|
||||
Wants=microvm.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/opt/bin/muvm-configure-network
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=microvm.target
|
||||
15
build/etc/systemd/system/nestri-pipewire-pulse.service
Normal file
15
build/etc/systemd/system/nestri-pipewire-pulse.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=PipeWire PulseAudio compatibility daemon
|
||||
Requires=nestri-pipewire-pulse.socket
|
||||
After=nestri-pwbridge.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStartPre=/bin/mkdir -p /run/vm-user/pulse
|
||||
ExecStart=/usr/bin/pipewire-pulse
|
||||
Environment=XDG_RUNTIME_DIR=/run/vm-user
|
||||
Environment=PIPEWIRE_RUNTIME_DIR=/run/vm-user
|
||||
User=nestri
|
||||
Group=nestri
|
||||
Restart=on-failure
|
||||
RestartSec=1
|
||||
13
build/etc/systemd/system/nestri-pipewire-pulse.socket
Normal file
13
build/etc/systemd/system/nestri-pipewire-pulse.socket
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=PipeWire PulseAudio compatibility socket
|
||||
PartOf=nestri-pipewire-pulse.service
|
||||
After=nestri-pwbridge.socket nestri-user-session.service
|
||||
Requires=nestri-pwbridge.socket nestri-user-session.service
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/vm-user/pulse/native
|
||||
SocketUser=nestri
|
||||
SocketGroup=nestri
|
||||
|
||||
[Install]
|
||||
WantedBy=microvm.target
|
||||
12
build/etc/systemd/system/nestri-procsys-rw.service
Normal file
12
build/etc/systemd/system/nestri-procsys-rw.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Make /proc/sys writable for muvm
|
||||
DefaultDependencies=no
|
||||
Before=systemd-sysctl.service systemd-tmpfiles-setup.service
|
||||
After=local-fs-pre.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# umount the ro bind mount; exit 0 so service succeeds
|
||||
# even if there's nothing to unmount (defensive)
|
||||
ExecStart=/bin/sh -c 'umount /proc/sys 2>/dev/null || true'
|
||||
7
build/etc/systemd/system/nestri-pwbridge.service
Normal file
7
build/etc/systemd/system/nestri-pwbridge.service
Normal file
@@ -0,0 +1,7 @@
|
||||
[Unit]
|
||||
Description=PipeWire cross-domain proxy
|
||||
Requires=nestri-pwbridge.socket
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStart=/opt/bin/muvm-pwbridge
|
||||
13
build/etc/systemd/system/nestri-pwbridge.socket
Normal file
13
build/etc/systemd/system/nestri-pwbridge.socket
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=PipeWire cross-domain proxy socket
|
||||
PartOf=nestri-pwbridge.service
|
||||
After=nestri-user-session.service
|
||||
Requires=nestri-user-session.service
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/vm-user/pipewire-0
|
||||
SocketUser=nestri
|
||||
SocketGroup=nestri
|
||||
|
||||
[Install]
|
||||
WantedBy=microvm.target
|
||||
33
build/etc/systemd/system/nestri-remote.service
Normal file
33
build/etc/systemd/system/nestri-remote.service
Normal file
@@ -0,0 +1,33 @@
|
||||
[Unit]
|
||||
Description=microVM application runner
|
||||
OnFailure=exit.target
|
||||
OnSuccess=exit.target
|
||||
Wants=sockets.target
|
||||
After=sockets.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
PassEnvironment=MUVM_REMOTE_CONFIG MESA_LOADER_DRIVER_OVERRIDE TERM VK_DRIVER_FILES
|
||||
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/vm-user/dbus.sock
|
||||
Environment=XDG_RUNTIME_DIR=/run/vm-user
|
||||
Environment=WAYLAND_DISPLAY=wayland-1
|
||||
Environment=XDG_SESSION_TYPE=wayland
|
||||
Environment=PULSE_SERVER=unix:/run/vm-user/pulse/native
|
||||
Environment=SDL_AUDIO_DRIVER=pipewire
|
||||
Environment=MESA_LOADER_DRIVER_OVERRIDE=zink
|
||||
Environment=GALLIUM_DRIVER=zink
|
||||
Environment=XAUTHORITY=/run/vm-user/xauth
|
||||
Environment=MANGOHUD_CONFIGFILE=/etc/nestri/configs/MangoHud/MangoHud.conf
|
||||
#Environment=SDL_VIDEODRIVER=wayland
|
||||
Environment=PATH=/usr/bin:/usr/sbin:/bin:/sbin
|
||||
User=root
|
||||
Group=root
|
||||
ExecStartPre=+/bin/chown nestri:nestri /run/vm-user
|
||||
ExecStart=/opt/bin/muvm-remote
|
||||
StandardOutput=tty
|
||||
StandardInput=tty
|
||||
StandardError=tty
|
||||
TTYPath=/dev/hvc0
|
||||
|
||||
[Install]
|
||||
WantedBy=microvm.target
|
||||
9
build/etc/systemd/system/nestri-session-bus.service
Normal file
9
build/etc/systemd/system/nestri-session-bus.service
Normal file
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=D-Bus session bus
|
||||
Requires=nestri-session-bus.socket
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStart=/usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --syslog-only
|
||||
User=nestri
|
||||
Group=nestri
|
||||
13
build/etc/systemd/system/nestri-session-bus.socket
Normal file
13
build/etc/systemd/system/nestri-session-bus.socket
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=D-Bus session bus socket
|
||||
PartOf=nestri-session-bus.service
|
||||
After=nestri-user-session.service
|
||||
Requires=nestri-user-session.service
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/vm-user/dbus.sock
|
||||
SocketUser=nestri
|
||||
SocketGroup=nestri
|
||||
|
||||
[Install]
|
||||
WantedBy=microvm.target
|
||||
13
build/etc/systemd/system/nestri-user-session.service
Normal file
13
build/etc/systemd/system/nestri-user-session.service
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Prepare VM user runtime directory
|
||||
DefaultDependencies=no
|
||||
Before=nestri-wayland-proxy.socket nestri-pwbridge.socket nestri-session-bus.socket
|
||||
After=local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c 'mkdir -p /run/vm-user && chown 1000:1000 /run/vm-user && chmod 700 /run/vm-user'
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=microvm.target
|
||||
12
build/etc/systemd/system/nestri-wayland-proxy.service
Normal file
12
build/etc/systemd/system/nestri-wayland-proxy.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Wayland cross-domain proxy
|
||||
Requires=nestri-wayland-proxy.socket
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStartPre=+/bin/chmod 0666 /dev/dri/card0 /dev/dri/renderD128
|
||||
ExecStart=/usr/bin/wl-cross-domain-proxy --listen-fd
|
||||
User=nestri
|
||||
Group=nestri
|
||||
StandardOutput=file:/tmp/wayland-proxy.log
|
||||
StandardError=file:/tmp/wayland-proxy-err.log
|
||||
14
build/etc/systemd/system/nestri-wayland-proxy.socket
Normal file
14
build/etc/systemd/system/nestri-wayland-proxy.socket
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Wayland cross-domain proxy socket
|
||||
PartOf=nestri-wayland-proxy.service
|
||||
After=nestri-user-session.service
|
||||
Requires=nestri-user-session.service
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/vm-user/wayland-1
|
||||
SocketUser=nestri
|
||||
SocketGroup=nestri
|
||||
FileDescriptorName=wayland
|
||||
|
||||
[Install]
|
||||
WantedBy=microvm.target
|
||||
@@ -0,0 +1 @@
|
||||
../nestri-procsys-rw.service
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"wireplumber.rules": [
|
||||
{
|
||||
"description": "Global audio format and rate for audio nodes",
|
||||
"matches": [
|
||||
{ "media.class": "Audio/Sink" },
|
||||
{ "media.class": "Audio/Source" }
|
||||
],
|
||||
"apply_properties": {
|
||||
"audio.format": "F32P",
|
||||
"audio.rate": 48000,
|
||||
"audio.channels": 2,
|
||||
"session.suspend-timeout-seconds": 0
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"description": "PulseAudio bridge specific tweaks",
|
||||
"matches": [
|
||||
{ "node.name": "pulse_sink" },
|
||||
{ "node.name": "pulse_source" }
|
||||
],
|
||||
"apply_properties": {
|
||||
"pulse.min.req": 128,
|
||||
"pulse.max.req": 1024,
|
||||
"pulse.idle.timeout": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
412
build/packages/lib32-mesa/PKGBUILD
Normal file
412
build/packages/lib32-mesa/PKGBUILD
Normal file
@@ -0,0 +1,412 @@
|
||||
pkgbase=lib32-mesa
|
||||
pkgname=(
|
||||
lib32-mesa
|
||||
lib32-vulkan-intel
|
||||
lib32-vulkan-nouveau
|
||||
lib32-vulkan-radeon
|
||||
lib32-vulkan-virtio
|
||||
lib32-vulkan-mesa-layers
|
||||
lib32-vulkan-mesa-implicit-layers
|
||||
)
|
||||
pkgver=26.1.0
|
||||
_pkgver=${pkgver/[a-z]/-&}
|
||||
pkgrel=1
|
||||
epoch=1
|
||||
pkgdesc="Open-source OpenGL drivers - 32-bit"
|
||||
url="https://gitlab.freedesktop.org/mesa/mesa"
|
||||
arch=(x86_64)
|
||||
license=("MIT AND BSD-3-Clause AND SGI-B-2.0")
|
||||
makedepends=(
|
||||
lib32-clang
|
||||
lib32-directx-headers
|
||||
lib32-expat
|
||||
lib32-gcc-libs
|
||||
lib32-glibc
|
||||
lib32-libdisplay-info
|
||||
lib32-libdrm
|
||||
lib32-libelf
|
||||
lib32-libglvnd
|
||||
lib32-libpng
|
||||
lib32-libva
|
||||
lib32-libx11
|
||||
lib32-libxcb
|
||||
lib32-libxext
|
||||
lib32-libxml2
|
||||
lib32-libxrandr
|
||||
lib32-libxshmfence
|
||||
lib32-libxxf86vm
|
||||
lib32-llvm
|
||||
lib32-llvm-libs
|
||||
lib32-lm_sensors
|
||||
lib32-rust-libs
|
||||
lib32-spirv-llvm-translator
|
||||
lib32-spirv-tools
|
||||
lib32-systemd
|
||||
lib32-vulkan-icd-loader
|
||||
lib32-wayland
|
||||
lib32-xcb-util-keysyms
|
||||
lib32-zlib
|
||||
lib32-zstd
|
||||
|
||||
# shared between mesa and lib32-mesa
|
||||
cbindgen
|
||||
clang
|
||||
cmake
|
||||
elfutils
|
||||
glslang
|
||||
libclc
|
||||
meson
|
||||
python-mako
|
||||
python-packaging
|
||||
python-ply
|
||||
python-pycparser
|
||||
python-yaml
|
||||
rust-bindgen
|
||||
wayland-protocols
|
||||
xorgproto
|
||||
)
|
||||
options=(
|
||||
# GCC 14 LTO causes segfault in LLVM under si_llvm_optimize_module
|
||||
# https://gitlab.freedesktop.org/mesa/mesa/-/issues/11140
|
||||
#
|
||||
# In general, upstream considers LTO to be broken until explicit notice.
|
||||
!lto
|
||||
)
|
||||
source=("${pkgname}::git+${url}.git#branch=main")
|
||||
|
||||
# Rust crates for NVK, used as Meson subprojects
|
||||
declare -A _crates=(
|
||||
bitflags 2.9.1
|
||||
cfg-if 1.0.0
|
||||
equivalent 1.0.1
|
||||
errno 0.3.12
|
||||
hashbrown 0.14.1
|
||||
indexmap 2.2.6
|
||||
libc 0.2.171
|
||||
log 0.4.27
|
||||
once_cell 1.8.0
|
||||
paste 1.0.14
|
||||
pest 2.8.0
|
||||
pest_derive 2.8.0
|
||||
pest_generator 2.8.0
|
||||
pest_meta 2.8.0
|
||||
proc-macro2 1.0.86
|
||||
quote 1.0.35
|
||||
remain 0.2.12
|
||||
roxmltree 0.20.0
|
||||
rustc-hash 2.1.1
|
||||
rustix 1.1.2
|
||||
syn 2.0.87
|
||||
thiserror 2.0.11
|
||||
thiserror-impl 2.0.11
|
||||
ucd-trie 0.1.6
|
||||
unicode-ident 1.0.12
|
||||
windows-link 0.2.0
|
||||
windows-sys 0.61.1
|
||||
zerocopy 0.8.13
|
||||
zerocopy-derive 0.8.13
|
||||
)
|
||||
|
||||
# Used to generate the above table
|
||||
_gencrates() {
|
||||
grep '^source_url' subprojects/*-rs.wrap | \
|
||||
sed -r 's|.*crates/([^/]+)/([0-9.]+)/download|\1 \2|' | \
|
||||
column -t -S 2 | sed 's/^/ /'
|
||||
}
|
||||
|
||||
for _crate in "${!_crates[@]}"; do
|
||||
_ver="${_crates[$_crate]}"
|
||||
source+=(
|
||||
"$_crate-$_ver.tar.gz::https://crates.io/api/v1/crates/$_crate/$_ver/download"
|
||||
)
|
||||
done
|
||||
|
||||
# https://docs.mesa3d.org/relnotes.html
|
||||
sha256sums=('SKIP')
|
||||
|
||||
prepare() {
|
||||
cd lib32-mesa
|
||||
|
||||
local src
|
||||
for src in "${source[@]}"; do
|
||||
src="${src%%::*}"
|
||||
src="${src##*/}"
|
||||
src="${src%.zst}"
|
||||
[[ $src = *.patch ]] || continue
|
||||
echo "Applying patch $src..."
|
||||
patch -Np1 < "../$src"
|
||||
done
|
||||
}
|
||||
|
||||
build() {
|
||||
local meson_options=(
|
||||
--cross-file lib32
|
||||
-D amdgpu-virtio=true
|
||||
-D intel-virtio-experimental=true
|
||||
-D android-libbacktrace=disabled
|
||||
-D b_ndebug=true
|
||||
-D gallium-drivers=all
|
||||
-D gallium-extra-hud=true
|
||||
-D gallium-mediafoundation=disabled
|
||||
-D gallium-rusticl-enable-drivers=asahi,freedreno,radeonsi
|
||||
-D gallium-rusticl=true
|
||||
-D gles1=disabled
|
||||
-D html-docs=disabled
|
||||
-D intel-rt=disabled
|
||||
-D libunwind=disabled
|
||||
-D microsoft-clc=disabled
|
||||
-D sysprof=false
|
||||
-D valgrind=disabled
|
||||
-D video-codecs=all
|
||||
-D vulkan-drivers=all
|
||||
-D vulkan-layers=device-select,intel-nullhw,overlay,screenshot,anti-lag,vram-report-limit
|
||||
-D vulkan-manifest-per-architecture=false
|
||||
)
|
||||
|
||||
# Build only minimal debug info to reduce size
|
||||
CFLAGS+=" -g1"
|
||||
CXXFLAGS+=" -g1"
|
||||
|
||||
# Inject subproject packages
|
||||
export MESON_PACKAGE_CACHE_DIR="$srcdir"
|
||||
|
||||
arch-meson lib32-mesa build "${meson_options[@]}"
|
||||
meson compile -C build
|
||||
}
|
||||
|
||||
_pick() {
|
||||
local p="$1" f d; shift
|
||||
for f; do
|
||||
d="$srcdir/$p/${f#$pkgdir/}"
|
||||
mkdir -p "$(dirname "$d")"
|
||||
mv -v "$f" "$d"
|
||||
rmdir -p --ignore-fail-on-non-empty "$(dirname "$f")"
|
||||
done
|
||||
}
|
||||
|
||||
package_lib32-mesa() {
|
||||
depends=(
|
||||
lib32-expat
|
||||
lib32-gcc-libs
|
||||
lib32-glibc
|
||||
lib32-libdrm
|
||||
lib32-libelf
|
||||
lib32-libglvnd
|
||||
lib32-libx11
|
||||
lib32-libxcb
|
||||
lib32-libxext
|
||||
lib32-libxshmfence
|
||||
lib32-libxxf86vm
|
||||
lib32-llvm-libs
|
||||
lib32-lm_sensors
|
||||
lib32-spirv-tools
|
||||
lib32-wayland
|
||||
lib32-zlib
|
||||
lib32-zstd
|
||||
|
||||
mesa
|
||||
)
|
||||
optdepends=("opengl-man-pages: for the OpenGL API man pages")
|
||||
provides=(
|
||||
"lib32-libva-mesa-driver=$epoch:$pkgver-$pkgrel"
|
||||
"lib32-mesa-libgl=$epoch:$pkgver-$pkgrel"
|
||||
lib32-libva-driver
|
||||
lib32-opengl-driver
|
||||
)
|
||||
conflicts=(
|
||||
'lib32-libva-mesa-driver<1:24.2.7-1'
|
||||
'lib32-mesa-libgl<17.0.1-2'
|
||||
)
|
||||
replaces=(
|
||||
'lib32-libva-mesa-driver<1:24.2.7-1'
|
||||
'lib32-mesa-libgl<17.0.1-2'
|
||||
)
|
||||
|
||||
meson install -C build --destdir "$pkgdir" --no-rebuild
|
||||
|
||||
(
|
||||
local libdir=usr/lib32
|
||||
|
||||
cd "$pkgdir"
|
||||
|
||||
_pick vkintel $libdir/libvulkan_intel{,_hasvk}.so
|
||||
|
||||
_pick vknvidia $libdir/libvulkan_nouveau.so
|
||||
|
||||
_pick vkradeon $libdir/libvulkan_radeon.so
|
||||
|
||||
_pick vkvirtio $libdir/libvulkan_virtio.so
|
||||
|
||||
_pick vkdevice $libdir/libVkLayer_MESA_anti_lag.so
|
||||
_pick vkdevice $libdir/libVkLayer_MESA_device_select.so
|
||||
|
||||
_pick vklayer $libdir/libVkLayer_*.so
|
||||
|
||||
rm -rv etc usr/{bin,include,share}
|
||||
|
||||
# indirect rendering
|
||||
ln -sr $libdir/libGLX_{mesa,indirect}.so.0
|
||||
)
|
||||
|
||||
install -Dm644 lib32-mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_lib32-vulkan-intel() {
|
||||
pkgdesc="Open-source Vulkan driver for Intel GPUs - 32-bit"
|
||||
depends=(
|
||||
lib32-expat
|
||||
lib32-gcc-libs
|
||||
lib32-glibc
|
||||
lib32-libdisplay-info
|
||||
lib32-libdrm
|
||||
lib32-libx11
|
||||
lib32-libxcb
|
||||
lib32-libxshmfence
|
||||
lib32-spirv-tools
|
||||
lib32-systemd
|
||||
lib32-vulkan-icd-loader
|
||||
lib32-vulkan-mesa-implicit-layers
|
||||
lib32-wayland
|
||||
lib32-xcb-util-keysyms
|
||||
lib32-zlib
|
||||
lib32-zstd
|
||||
|
||||
vulkan-intel
|
||||
)
|
||||
optdepends=("lib32-vulkan-mesa-layers: additional vulkan layers")
|
||||
provides=(lib32-vulkan-driver)
|
||||
|
||||
mv vkintel/* "$pkgdir"
|
||||
|
||||
install -Dm644 lib32-mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_lib32-vulkan-nouveau() {
|
||||
pkgdesc="Open-source Vulkan driver for Nvidia GPUs - 32-bit"
|
||||
depends=(
|
||||
lib32-expat
|
||||
lib32-gcc-libs
|
||||
lib32-glibc
|
||||
lib32-libdisplay-info
|
||||
lib32-libdrm
|
||||
lib32-libx11
|
||||
lib32-libxcb
|
||||
lib32-libxshmfence
|
||||
lib32-spirv-tools
|
||||
lib32-systemd
|
||||
lib32-vulkan-icd-loader
|
||||
lib32-vulkan-mesa-implicit-layers
|
||||
lib32-wayland
|
||||
lib32-xcb-util-keysyms
|
||||
lib32-zlib
|
||||
lib32-zstd
|
||||
|
||||
vulkan-nouveau
|
||||
)
|
||||
optdepends=("lib32-vulkan-mesa-layers: additional vulkan layers")
|
||||
provides=(lib32-vulkan-driver)
|
||||
|
||||
mv vknvidia/* "$pkgdir"
|
||||
|
||||
install -Dm644 lib32-mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_lib32-vulkan-radeon() {
|
||||
pkgdesc="Open-source Vulkan driver for AMD GPUs - 32-bit"
|
||||
depends=(
|
||||
lib32-expat
|
||||
lib32-gcc-libs
|
||||
lib32-glibc
|
||||
lib32-libdisplay-info
|
||||
lib32-libdrm
|
||||
lib32-libelf
|
||||
lib32-libx11
|
||||
lib32-libxcb
|
||||
lib32-libxshmfence
|
||||
lib32-llvm-libs
|
||||
lib32-spirv-tools
|
||||
lib32-systemd
|
||||
lib32-vulkan-icd-loader
|
||||
lib32-vulkan-mesa-implicit-layers
|
||||
lib32-wayland
|
||||
lib32-xcb-util-keysyms
|
||||
lib32-zlib
|
||||
lib32-zstd
|
||||
|
||||
vulkan-radeon
|
||||
)
|
||||
optdepends=("lib32-vulkan-mesa-layers: additional vulkan layers")
|
||||
provides=(lib32-vulkan-driver)
|
||||
replaces=('lib32-amdvlk<=2025.Q2.1-1')
|
||||
|
||||
mv vkradeon/* "$pkgdir"
|
||||
|
||||
install -Dm644 lib32-mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_lib32-vulkan-virtio() {
|
||||
pkgdesc="Open-source Vulkan driver for Virtio-GPU (Venus) - 32-bit"
|
||||
depends=(
|
||||
lib32-expat
|
||||
lib32-gcc-libs
|
||||
lib32-glibc
|
||||
lib32-libdisplay-info
|
||||
lib32-libdrm
|
||||
lib32-libx11
|
||||
lib32-libxcb
|
||||
lib32-libxshmfence
|
||||
lib32-systemd
|
||||
lib32-vulkan-icd-loader
|
||||
lib32-vulkan-mesa-implicit-layers
|
||||
lib32-wayland
|
||||
lib32-xcb-util-keysyms
|
||||
lib32-zlib
|
||||
lib32-zstd
|
||||
|
||||
vulkan-virtio
|
||||
)
|
||||
optdepends=("lib32-vulkan-mesa-layers: additional vulkan layers")
|
||||
provides=(lib32-vulkan-driver)
|
||||
|
||||
mv vkvirtio/* "$pkgdir"
|
||||
|
||||
install -Dm644 lib32-mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_lib32-vulkan-mesa-layers() {
|
||||
pkgdesc="Mesa's explicit Vulkan layers - 32-bit"
|
||||
depends=(
|
||||
lib32-gcc-libs
|
||||
lib32-glibc
|
||||
lib32-libpng
|
||||
|
||||
vulkan-mesa-layers
|
||||
)
|
||||
conflicts=(lib32-vulkan-mesa-layer)
|
||||
replaces=(lib32-vulkan-mesa-layer)
|
||||
|
||||
mv vklayer/* "$pkgdir"
|
||||
|
||||
install -Dm644 lib32-mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_lib32-vulkan-mesa-implicit-layers() {
|
||||
pkgdesc="Mesa's implicit Vulkan layers - 32-bit"
|
||||
depends=(
|
||||
lib32-gcc-libs
|
||||
lib32-glibc
|
||||
lib32-libdrm
|
||||
lib32-libxcb
|
||||
lib32-wayland
|
||||
|
||||
vulkan-mesa-implicit-layers
|
||||
)
|
||||
conflicts=(lib32-vulkan-mesa-device-select)
|
||||
replaces=(lib32-vulkan-mesa-device-select)
|
||||
|
||||
mv vkdevice/* "$pkgdir"
|
||||
|
||||
install -Dm644 lib32-mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
# vim:set sw=2 sts=-1 et:
|
||||
39
build/packages/libkrun/PKGBUILD
Normal file
39
build/packages/libkrun/PKGBUILD
Normal file
@@ -0,0 +1,39 @@
|
||||
pkgname=libkrun
|
||||
pkgver=1.17.3.r0.gvalpackett
|
||||
pkgrel=1
|
||||
pkgdesc="A dynamic library providing Virtualization-based process isolation capabilities (val/vluqsysxtqrk branch)"
|
||||
url='https://github.com/valpackett/libkrun'
|
||||
arch=('x86_64')
|
||||
license=('Apache-2.0')
|
||||
makedepends=('cargo' 'patchelf' 'clang' 'git')
|
||||
depends=('glibc' 'gcc-libs' 'libkrunfw' 'pipewire' 'virglrenderer')
|
||||
# Format: 'folder_name::git+url#branch=branch_name'
|
||||
source=("${pkgname}::git+${url}.git#branch=val/vluqsysxtqrk")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$pkgname"
|
||||
# Generates a version string based on the latest tag and commit count
|
||||
git describe --long --tags | sed 's/\([^-]*-g\)/r\1/;s/-/./g;s/^v//'
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "$pkgname"
|
||||
|
||||
cargo fetch --locked --target "$(rustc --print host-tuple)"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$pkgname"
|
||||
|
||||
export ZSTD_SYS_USE_PKG_CONFIG=1
|
||||
make BLK=1 NET=1 EFI=0 GPU=1 SND=1 INPUT=1 VERBOSE=1
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$pkgname"
|
||||
|
||||
make DESTDIR="$pkgdir" PREFIX=/usr LIBDIR_Linux=lib install
|
||||
|
||||
install -Dm644 LICENSE "$pkgdir"/usr/share/licenses/$pkgname/LICENSE
|
||||
}
|
||||
51
build/packages/libkrunfw/PKGBUILD
Normal file
51
build/packages/libkrunfw/PKGBUILD
Normal file
@@ -0,0 +1,51 @@
|
||||
pkgname=libkrunfw
|
||||
_kver=6.12.68
|
||||
pkgver=5.2.1
|
||||
pkgrel=1
|
||||
pkgdesc="A dynamic library bundling the guest payload consumed by libkrun (with 32-bit support)"
|
||||
url="https://github.com/containers/libkrunfw"
|
||||
arch=('x86_64')
|
||||
license=('GPL-2.0-only' 'LGPL-2.1-only')
|
||||
depends=('glibc')
|
||||
makedepends=('bc' 'python-pyelftools' 'cpio')
|
||||
source=("https://github.com/containers/libkrunfw/archive/refs/tags/v$pkgver/$pkgname-$pkgver.tar.gz"
|
||||
"https://cdn.kernel.org/pub/linux/kernel/v${_kver%%.*}.x/linux-${_kver}.tar.xz")
|
||||
noextract=("linux-${_kver}.tar.xz")
|
||||
options=(!debug)
|
||||
sha256sums=('c7eebd7149b15e4d74d2dff9acd3137dc13eedf604adf1df2efa52d9f36fe0bb'
|
||||
'd367c7504bd4da520dd01eb08125d2d0ac088bc8af4cd56d236f2074dd4225b7')
|
||||
|
||||
build() {
|
||||
cd "$pkgname-$pkgver"
|
||||
|
||||
mkdir -p tarballs
|
||||
cp -s "$srcdir/linux-${_kver}.tar.xz" tarballs/
|
||||
|
||||
_config="config-libkrunfw_x86_64"
|
||||
|
||||
# Enable IA32 (32-bit) emulation support
|
||||
sed -i 's/# CONFIG_IA32_EMULATION is not set/CONFIG_IA32_EMULATION=y/' "$_config"
|
||||
|
||||
# Enable modify_ldt syscall (needed by many 32-bit apps including Steam)
|
||||
sed -i 's/# CONFIG_MODIFY_LDT_SYSCALL is not set/CONFIG_MODIFY_LDT_SYSCALL=y/' "$_config"
|
||||
|
||||
# Enable 32-bit time compatibility
|
||||
sed -i 's/# CONFIG_COMPAT_32BIT_TIME is not set/CONFIG_COMPAT_32BIT_TIME=y/' "$_config"
|
||||
|
||||
# Enable x32 ABI
|
||||
sed -i 's/# CONFIG_X86_X32_ABI is not set/CONFIG_X86_X32_ABI=y/' "$_config"
|
||||
|
||||
# Increase max CPU count (default 16 is low for gaming)
|
||||
sed -i 's/CONFIG_NR_CPUS=16/CONFIG_NR_CPUS=128/' "$_config"
|
||||
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$pkgname-$pkgver"
|
||||
|
||||
make DESTDIR="$pkgdir" PREFIX=/usr LIBDIR_Linux=lib install
|
||||
|
||||
install -Dm644 LICENSE-GPL-2.0-only "$pkgdir"/usr/share/licenses/$pkgname/LICENSE-GPL-2.0-only
|
||||
install -Dm644 LICENSE-LGPL-2.1-only "$pkgdir"/usr/share/licenses/$pkgname/LICENSE-LGPL-2.1-only
|
||||
}
|
||||
418
build/packages/mesa/PKGBUILD
Normal file
418
build/packages/mesa/PKGBUILD
Normal file
@@ -0,0 +1,418 @@
|
||||
pkgbase=mesa
|
||||
pkgname=(
|
||||
mesa
|
||||
vulkan-intel
|
||||
vulkan-nouveau
|
||||
vulkan-radeon
|
||||
vulkan-virtio
|
||||
vulkan-mesa-layers
|
||||
vulkan-mesa-implicit-layers
|
||||
)
|
||||
pkgver=26.1.0
|
||||
_pkgver=${pkgver/[a-z]/-&}
|
||||
pkgrel=1
|
||||
epoch=1
|
||||
pkgdesc="Open-source OpenGL drivers"
|
||||
url="https://gitlab.freedesktop.org/mesa/mesa"
|
||||
arch=(x86_64)
|
||||
license=("MIT AND BSD-3-Clause AND SGI-B-2.0")
|
||||
makedepends=(
|
||||
clang
|
||||
directx-headers
|
||||
expat
|
||||
glibc
|
||||
libdisplay-info
|
||||
libdrm
|
||||
libelf
|
||||
libgcc
|
||||
libglvnd
|
||||
libpng
|
||||
libstdc++
|
||||
libva
|
||||
libx11
|
||||
libxcb
|
||||
libxext
|
||||
libxml2
|
||||
libxrandr
|
||||
libxshmfence
|
||||
libxxf86vm
|
||||
llvm
|
||||
llvm-libs
|
||||
lm_sensors
|
||||
rust
|
||||
spirv-llvm-translator
|
||||
spirv-tools
|
||||
systemd-libs
|
||||
vulkan-icd-loader
|
||||
wayland
|
||||
xcb-util-keysyms
|
||||
zlib
|
||||
zstd
|
||||
|
||||
# shared between mesa and lib32-mesa
|
||||
cbindgen
|
||||
clang
|
||||
cmake
|
||||
elfutils
|
||||
glslang
|
||||
libclc
|
||||
meson
|
||||
python-mako
|
||||
python-packaging
|
||||
python-ply
|
||||
python-pycparser
|
||||
python-yaml
|
||||
rust-bindgen
|
||||
wayland-protocols
|
||||
xorgproto
|
||||
|
||||
# mesa-only deps
|
||||
libsysprof-capture
|
||||
valgrind
|
||||
|
||||
# html-docs
|
||||
python-sphinx
|
||||
python-sphinx-hawkmoth
|
||||
)
|
||||
options=(
|
||||
# GCC 14 LTO causes segfault in LLVM under si_llvm_optimize_module
|
||||
# https://gitlab.freedesktop.org/mesa/mesa/-/issues/11140
|
||||
#
|
||||
# In general, upstream considers LTO to be broken until explicit notice.
|
||||
!lto
|
||||
)
|
||||
source=("${pkgname}::git+${url}.git#branch=main")
|
||||
|
||||
# Rust crates for NVK, used as Meson subprojects
|
||||
declare -A _crates=(
|
||||
bitflags 2.9.1
|
||||
cfg-if 1.0.0
|
||||
equivalent 1.0.1
|
||||
errno 0.3.12
|
||||
hashbrown 0.14.1
|
||||
indexmap 2.2.6
|
||||
libc 0.2.171
|
||||
log 0.4.27
|
||||
once_cell 1.8.0
|
||||
paste 1.0.14
|
||||
pest 2.8.0
|
||||
pest_derive 2.8.0
|
||||
pest_generator 2.8.0
|
||||
pest_meta 2.8.0
|
||||
proc-macro2 1.0.86
|
||||
quote 1.0.35
|
||||
remain 0.2.12
|
||||
roxmltree 0.20.0
|
||||
rustc-hash 2.1.1
|
||||
rustix 1.1.2
|
||||
syn 2.0.87
|
||||
thiserror 2.0.11
|
||||
thiserror-impl 2.0.11
|
||||
ucd-trie 0.1.6
|
||||
unicode-ident 1.0.12
|
||||
windows-link 0.2.0
|
||||
windows-sys 0.61.1
|
||||
zerocopy 0.8.13
|
||||
zerocopy-derive 0.8.13
|
||||
)
|
||||
|
||||
# Used to generate the above table
|
||||
_gencrates() {
|
||||
grep '^source_url' subprojects/*-rs.wrap | \
|
||||
sed -r 's|.*crates/([^/]+)/([0-9.]+)/download|\1 \2|' | \
|
||||
column -t -S 2 | sed 's/^/ /'
|
||||
}
|
||||
|
||||
for _crate in "${!_crates[@]}"; do
|
||||
_ver="${_crates[$_crate]}"
|
||||
source+=(
|
||||
"$_crate-$_ver.tar.gz::https://crates.io/api/v1/crates/$_crate/$_ver/download"
|
||||
)
|
||||
done
|
||||
|
||||
# https://docs.mesa3d.org/relnotes.html
|
||||
sha256sums=('SKIP')
|
||||
|
||||
prepare() {
|
||||
cd mesa
|
||||
|
||||
local src
|
||||
for src in "${source[@]}"; do
|
||||
src="${src%%::*}"
|
||||
src="${src##*/}"
|
||||
src="${src%.zst}"
|
||||
[[ $src = *.patch ]] || continue
|
||||
echo "Applying patch $src..."
|
||||
patch -Np1 < "../$src"
|
||||
done
|
||||
}
|
||||
|
||||
build() {
|
||||
local meson_options=(
|
||||
-D amdgpu-virtio=true
|
||||
-D intel-virtio-experimental=true
|
||||
-D android-libbacktrace=disabled
|
||||
-D b_ndebug=true
|
||||
-D gallium-drivers=all
|
||||
-D gallium-extra-hud=true
|
||||
-D gallium-mediafoundation=disabled
|
||||
-D gallium-rusticl-enable-drivers=asahi,freedreno,radeonsi
|
||||
-D gallium-rusticl=true
|
||||
-D gles1=disabled
|
||||
-D html-docs=enabled
|
||||
-D intel-rt=enabled
|
||||
-D libunwind=disabled
|
||||
-D microsoft-clc=disabled
|
||||
-D sysprof=true
|
||||
-D valgrind=enabled
|
||||
-D video-codecs=all
|
||||
-D vulkan-drivers=all
|
||||
-D vulkan-layers=device-select,intel-nullhw,overlay,screenshot,anti-lag,vram-report-limit
|
||||
-D vulkan-manifest-per-architecture=false
|
||||
)
|
||||
|
||||
# Build only minimal debug info to reduce size
|
||||
CFLAGS+=" -g1"
|
||||
CXXFLAGS+=" -g1"
|
||||
|
||||
# Inject subproject packages
|
||||
export MESON_PACKAGE_CACHE_DIR="$srcdir"
|
||||
|
||||
arch-meson mesa build "${meson_options[@]}"
|
||||
meson compile -C build
|
||||
}
|
||||
|
||||
_pick() {
|
||||
local p="$1" f d; shift
|
||||
for f; do
|
||||
d="$srcdir/$p/${f#$pkgdir/}"
|
||||
mkdir -p "$(dirname "$d")"
|
||||
mv -v "$f" "$d"
|
||||
rmdir -p --ignore-fail-on-non-empty "$(dirname "$f")"
|
||||
done
|
||||
}
|
||||
|
||||
package_mesa() {
|
||||
depends=(
|
||||
expat
|
||||
glibc
|
||||
libdrm
|
||||
libelf
|
||||
libgcc
|
||||
libglvnd
|
||||
libstdc++
|
||||
libx11
|
||||
libxcb
|
||||
libxext
|
||||
libxshmfence
|
||||
libxxf86vm
|
||||
llvm-libs
|
||||
lm_sensors
|
||||
spirv-tools
|
||||
wayland
|
||||
zlib
|
||||
zstd
|
||||
)
|
||||
optdepends=("opengl-man-pages: for the OpenGL API man pages")
|
||||
provides=(
|
||||
"libva-mesa-driver=$epoch:$pkgver-$pkgrel"
|
||||
"mesa-libgl=$epoch:$pkgver-$pkgrel"
|
||||
libva-driver
|
||||
opengl-driver
|
||||
)
|
||||
conflicts=(
|
||||
'libva-mesa-driver<1:24.2.7-1'
|
||||
'mesa-libgl<17.0.1-2'
|
||||
)
|
||||
replaces=(
|
||||
'libva-mesa-driver<1:24.2.7-1'
|
||||
'mesa-libgl<17.0.1-2'
|
||||
)
|
||||
|
||||
meson install -C build --destdir "$pkgdir" --no-rebuild
|
||||
|
||||
(
|
||||
local libdir=usr/lib
|
||||
|
||||
cd "$pkgdir"
|
||||
|
||||
_pick vkintel $libdir/libvulkan_intel{,_hasvk}.so
|
||||
_pick vkintel usr/share/vulkan/icd.d/intel{,_hasvk}_icd.json
|
||||
|
||||
_pick vknvidia $libdir/libvulkan_nouveau.so
|
||||
_pick vknvidia usr/share/vulkan/icd.d/nouveau_icd.json
|
||||
|
||||
_pick vkradeon $libdir/libvulkan_radeon.so
|
||||
_pick vkradeon usr/share/drirc.d/00-radv-defaults.conf
|
||||
_pick vkradeon usr/share/vulkan/icd.d/radeon_icd.json
|
||||
|
||||
_pick vkvirtio $libdir/libvulkan_virtio.so
|
||||
_pick vkvirtio usr/share/vulkan/icd.d/virtio_icd.json
|
||||
|
||||
_pick vkdevice $libdir/libVkLayer_MESA_anti_lag.so
|
||||
_pick vkdevice $libdir/libVkLayer_MESA_device_select.so
|
||||
_pick vkdevice usr/share/vulkan/implicit_layer.d
|
||||
|
||||
_pick vklayer $libdir/libVkLayer_*.so
|
||||
_pick vklayer usr/bin/mesa-*-control.py
|
||||
_pick vklayer usr/share/vulkan/explicit_layer.d
|
||||
|
||||
# indirect rendering
|
||||
ln -sr $libdir/libGLX_{mesa,indirect}.so.0
|
||||
)
|
||||
|
||||
install -Dm644 mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_vulkan-intel() {
|
||||
pkgdesc="Open-source Vulkan driver for Intel GPUs"
|
||||
depends=(
|
||||
expat
|
||||
glibc
|
||||
libdisplay-info
|
||||
libdrm
|
||||
libgcc
|
||||
libstdc++
|
||||
libx11
|
||||
libxcb
|
||||
libxshmfence
|
||||
spirv-tools
|
||||
systemd-libs
|
||||
vulkan-icd-loader
|
||||
vulkan-mesa-implicit-layers
|
||||
wayland
|
||||
xcb-util-keysyms
|
||||
zlib
|
||||
zstd
|
||||
)
|
||||
optdepends=("vulkan-mesa-layers: additional vulkan layers")
|
||||
provides=(vulkan-driver)
|
||||
|
||||
mv vkintel/* "$pkgdir"
|
||||
|
||||
install -Dm644 mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_vulkan-nouveau() {
|
||||
pkgdesc="Open-source Vulkan driver for Nvidia GPUs"
|
||||
depends=(
|
||||
expat
|
||||
glibc
|
||||
libdisplay-info
|
||||
libdrm
|
||||
libgcc
|
||||
libstdc++
|
||||
libx11
|
||||
libxcb
|
||||
libxshmfence
|
||||
spirv-tools
|
||||
systemd-libs
|
||||
vulkan-icd-loader
|
||||
vulkan-mesa-implicit-layers
|
||||
wayland
|
||||
xcb-util-keysyms
|
||||
zlib
|
||||
zstd
|
||||
)
|
||||
optdepends=("vulkan-mesa-layers: additional vulkan layers")
|
||||
provides=(vulkan-driver)
|
||||
|
||||
mv vknvidia/* "$pkgdir"
|
||||
|
||||
install -Dm644 mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_vulkan-radeon() {
|
||||
pkgdesc="Open-source Vulkan driver for AMD GPUs"
|
||||
depends=(
|
||||
expat
|
||||
glibc
|
||||
libdisplay-info
|
||||
libdrm
|
||||
libelf
|
||||
libgcc
|
||||
libstdc++
|
||||
libx11
|
||||
libxcb
|
||||
libxshmfence
|
||||
llvm-libs
|
||||
spirv-tools
|
||||
systemd-libs
|
||||
vulkan-icd-loader
|
||||
vulkan-mesa-implicit-layers
|
||||
wayland
|
||||
xcb-util-keysyms
|
||||
zlib
|
||||
zstd
|
||||
)
|
||||
optdepends=("vulkan-mesa-layers: additional vulkan layers")
|
||||
provides=(vulkan-driver)
|
||||
replaces=('amdvlk<=2025.Q2.1-1')
|
||||
|
||||
mv vkradeon/* "$pkgdir"
|
||||
|
||||
install -Dm644 mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_vulkan-virtio() {
|
||||
pkgdesc="Open-source Vulkan driver for Virtio-GPU (Venus)"
|
||||
depends=(
|
||||
expat
|
||||
glibc
|
||||
libdisplay-info
|
||||
libdrm
|
||||
libgcc
|
||||
libx11
|
||||
libxcb
|
||||
libxshmfence
|
||||
systemd-libs
|
||||
vulkan-icd-loader
|
||||
vulkan-mesa-implicit-layers
|
||||
wayland
|
||||
xcb-util-keysyms
|
||||
zlib
|
||||
zstd
|
||||
)
|
||||
optdepends=("vulkan-mesa-layers: additional vulkan layers")
|
||||
provides=(vulkan-driver)
|
||||
|
||||
mv vkvirtio/* "$pkgdir"
|
||||
|
||||
install -Dm644 mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_vulkan-mesa-layers() {
|
||||
pkgdesc="Mesa's explicit Vulkan layers"
|
||||
depends=(
|
||||
glibc
|
||||
libgcc
|
||||
libpng
|
||||
libstdc++
|
||||
|
||||
python
|
||||
)
|
||||
conflicts=(vulkan-mesa-layer)
|
||||
replaces=(vulkan-mesa-layer)
|
||||
|
||||
mv vklayer/* "$pkgdir"
|
||||
|
||||
install -Dm644 mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
package_vulkan-mesa-implicit-layers() {
|
||||
pkgdesc="Mesa's implicit Vulkan layers"
|
||||
depends=(
|
||||
glibc
|
||||
libdrm
|
||||
libxcb
|
||||
wayland
|
||||
)
|
||||
conflicts=(vulkan-mesa-device-select)
|
||||
replaces=(vulkan-mesa-device-select)
|
||||
|
||||
mv vkdevice/* "$pkgdir"
|
||||
|
||||
install -Dm644 mesa/docs/license.rst -t "$pkgdir/usr/share/licenses/$pkgname"
|
||||
}
|
||||
|
||||
# vim:set sw=2 sts=-1 et:
|
||||
28
build/packages/virglrenderer/PKGBUILD
Normal file
28
build/packages/virglrenderer/PKGBUILD
Normal file
@@ -0,0 +1,28 @@
|
||||
pkgname=virglrenderer
|
||||
pkgver=1.3.0
|
||||
pkgrel=1
|
||||
pkgdesc='A virtual 3D GPU library, that allows the guest operating system to use the host GPU to accelerate 3D rendering'
|
||||
arch=(x86_64)
|
||||
url='https://virgil3d.github.io/'
|
||||
license=(MIT)
|
||||
depends=(libepoxy mesa libva vulkan-icd-loader)
|
||||
makedepends=(python meson ninja vulkan-headers python-yaml)
|
||||
checkdepends=(check)
|
||||
_tag=virglrenderer-$pkgver
|
||||
source=(virglrenderer-$pkgver.tar.bz2::https://gitlab.freedesktop.org/virgl/virglrenderer/-/archive/$_tag/virglrenderer-$_tag.tar.bz2)
|
||||
sha256sums=('47a64189492a754685a430c713ac6700f4b1c3e7b871e87889ddb96e4d65e8ab')
|
||||
|
||||
build() {
|
||||
cd virglrenderer-$_tag
|
||||
meson --prefix=/usr --libexecdir=lib/$pkgname build \
|
||||
-Dvideo=true \
|
||||
-Dvenus=true \
|
||||
-Ddrm-renderers=amdgpu-experimental,i915-experimental
|
||||
ninja -C build
|
||||
}
|
||||
|
||||
package() {
|
||||
cd virglrenderer-$_tag
|
||||
DESTDIR="$pkgdir" ninja -C build install
|
||||
install -D -m644 COPYING "$pkgdir/usr/share/licenses/$pkgname/COPYING"
|
||||
}
|
||||
21
build/steam/config.vdf
Normal file
21
build/steam/config.vdf
Normal file
@@ -0,0 +1,21 @@
|
||||
"InstallConfigStore"
|
||||
{
|
||||
"Software"
|
||||
{
|
||||
"Valve"
|
||||
{
|
||||
"Steam"
|
||||
{
|
||||
"CompatToolMapping"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"name" "proton_experimental"
|
||||
"config" ""
|
||||
"priority" "75"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
576
build/usr/bin/nestri-entry
Normal file
576
build/usr/bin/nestri-entry
Normal file
@@ -0,0 +1,576 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# ============================================================
|
||||
# nestri-entry
|
||||
#
|
||||
# Entry point that runs inside the bwrap sandbox.
|
||||
# Launched by nestri-runner.sh as the top-level process.
|
||||
#
|
||||
# Responsibilities:
|
||||
# 1. Start PipeWire (sandbox-local audio server)
|
||||
# 2. Start GStreamer pipeline (Wayland compositor + encoding + streaming)
|
||||
# 3. Launch muvm (microVM that runs the actual games)
|
||||
#
|
||||
# The GStreamer pipeline IS the Wayland compositor:
|
||||
# - waylanddisplaysrc creates $XDG_RUNTIME_DIR/wayland-1
|
||||
# - VM guest connects via wl-cross-domain-proxy (virtio-gpu)
|
||||
# - Video frames captured as DMA-BUF, encoded, streamed via QUIC
|
||||
# - Audio captured from PipeWire, encoded as Opus, muxed with video
|
||||
#
|
||||
# Environment variables (set by nestri-runner.sh):
|
||||
# NESTRI_WIDTH Stream width (default: 1920)
|
||||
# NESTRI_HEIGHT Stream height (default: 1080)
|
||||
# NESTRI_FPS Stream framerate (default: 60)
|
||||
# NESTRI_BITRATE Encoder bitrate in kbps (default: 8000)
|
||||
# NESTRI_RENDER_NODE GPU render node (default: /dev/dri/renderD128)
|
||||
# NESTRI_BROADCAST Stream broadcast name (default: live)
|
||||
# NESTRI_GPU GPU type: amd, intel, nvidia (default: amd)
|
||||
# NESTRI_CODEC Video codec: h264, h265, av1 (default: h264)
|
||||
# MICROVM_UID User ID inside sandbox/VM
|
||||
# MICROVM_GID Group ID inside sandbox/VM
|
||||
#
|
||||
# muvm-guest binary symlinks (in /opt/bin/):
|
||||
# muvm-remote — session runner (runs user command)
|
||||
# muvm-configure-network — network setup for VM
|
||||
# muvm-pwbridge — PipeWire bridge (host ↔ guest audio)
|
||||
# ============================================================
|
||||
|
||||
# ============================================================
|
||||
# Configuration (from environment or defaults)
|
||||
# ============================================================
|
||||
|
||||
NESTRI_WIDTH="${NESTRI_WIDTH:-1920}"
|
||||
NESTRI_HEIGHT="${NESTRI_HEIGHT:-1080}"
|
||||
NESTRI_FPS="${NESTRI_FPS:-60}"
|
||||
NESTRI_BITRATE="${NESTRI_BITRATE:-8000}"
|
||||
NESTRI_RENDER_NODE="${NESTRI_RENDER_NODE:-/dev/dri/renderD128}"
|
||||
NESTRI_BROADCAST="${NESTRI_BROADCAST:-live}"
|
||||
MICROVM_UID="${MICROVM_UID:-1000}"
|
||||
|
||||
# GPU and codec selection
|
||||
# GPU options: amd, intel, nvidia
|
||||
# Codec options: h264, h265, av1
|
||||
NESTRI_GPU="${NESTRI_GPU:-amd}"
|
||||
NESTRI_CODEC="${NESTRI_CODEC:-h264}"
|
||||
|
||||
# Setup XDG_RUNTIME_DIR
|
||||
mkdir -p "$XDG_RUNTIME_DIR"
|
||||
|
||||
# Track background PIDs for cleanup
|
||||
PIDS=()
|
||||
|
||||
cleanup() {
|
||||
echo "nestri-entry: shutting down..." >&2
|
||||
|
||||
# Kill all tracked background processes
|
||||
for pid in "${PIDS[@]}"; do
|
||||
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||
kill -TERM "$pid" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# Wait briefly for graceful shutdown
|
||||
sleep 0.5
|
||||
|
||||
# Force kill anything still alive
|
||||
for pid in "${PIDS[@]}"; do
|
||||
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||
kill -KILL "$pid" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# dbus-launch sets this separately
|
||||
if [ -n "${DBUS_SESSION_BUS_PID:-}" ]; then
|
||||
kill -TERM "$DBUS_SESSION_BUS_PID" 2>/dev/null
|
||||
fi
|
||||
|
||||
exit
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# ============================================================
|
||||
# 1. D-Bus Session Bus + PipeWire (sandbox-local audio)
|
||||
#
|
||||
# WirePlumber requires a D-Bus session bus — it's a hard
|
||||
# dependency. PipeWire itself can start without D-Bus, but
|
||||
# WirePlumber (the session manager that handles routing,
|
||||
# device enumeration, policy) will abort without one.
|
||||
#
|
||||
# Inside the VM, systemd provides the session bus via
|
||||
# nestri-session-bus.service. Here in bwrap, we have no
|
||||
# systemd, so we launch dbus-daemon manually.
|
||||
#
|
||||
# Audio flow:
|
||||
# Game (in VM) → PipeWire (guest) → muvm-pwbridge → PipeWire (here)
|
||||
# PipeWire (here) → pipewiresrc → GStreamer → Opus encode → QUIC
|
||||
# ============================================================
|
||||
|
||||
# --- D-Bus session bus ---
|
||||
echo "nestri-entry: starting dbus session bus..." >&2
|
||||
|
||||
# Create dbus directory
|
||||
mkdir -p "$XDG_RUNTIME_DIR/dbus"
|
||||
|
||||
# Launch a session bus and capture its address
|
||||
eval "$(dbus-launch --sh-syntax)"
|
||||
|
||||
if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
|
||||
echo "nestri-entry: WARNING — dbus-launch failed, trying manual start..." >&2
|
||||
|
||||
DBUS_SOCKET="$XDG_RUNTIME_DIR/dbus/session-bus"
|
||||
dbus-daemon \
|
||||
--session \
|
||||
--address="unix:path=$DBUS_SOCKET" \
|
||||
--nofork \
|
||||
--print-address \
|
||||
&>/dev/null &
|
||||
DBUS_PID=$!
|
||||
PIDS+=($DBUS_PID)
|
||||
|
||||
# Wait for socket
|
||||
for i in $(seq 1 30); do
|
||||
[ -S "$DBUS_SOCKET" ] && break
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if [ -S "$DBUS_SOCKET" ]; then
|
||||
export DBUS_SESSION_BUS_ADDRESS="unix:path=$DBUS_SOCKET"
|
||||
echo "nestri-entry: dbus ready at $DBUS_SOCKET" >&2
|
||||
else
|
||||
echo "nestri-entry: WARNING — dbus-daemon failed to start" >&2
|
||||
echo "nestri-entry: wireplumber will likely fail" >&2
|
||||
fi
|
||||
else
|
||||
# dbus-launch succeeded, track its PID for cleanup
|
||||
PIDS+=("${DBUS_SESSION_BUS_PID:-}")
|
||||
echo "nestri-entry: dbus ready (via dbus-launch) PID=${DBUS_SESSION_BUS_PID:-}" >&2
|
||||
fi
|
||||
|
||||
export DBUS_SESSION_BUS_ADDRESS
|
||||
|
||||
# --- PipeWire ---
|
||||
echo "nestri-entry: starting pipewire..." >&2
|
||||
pipewire &
|
||||
PIDS+=($!)
|
||||
|
||||
# Wait for PipeWire socket
|
||||
for i in $(seq 1 50); do
|
||||
[ -S "$XDG_RUNTIME_DIR/pipewire-0" ] && break
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if [ -S "$XDG_RUNTIME_DIR/pipewire-0" ]; then
|
||||
echo "nestri-entry: pipewire ready" >&2
|
||||
|
||||
# WirePlumber needs both PipeWire AND D-Bus
|
||||
if [ -n "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
|
||||
wireplumber &
|
||||
PIDS+=($!)
|
||||
sleep 0.5
|
||||
echo "nestri-entry: wireplumber ready" >&2
|
||||
else
|
||||
echo "nestri-entry: WARNING — skipping wireplumber (no dbus)" >&2
|
||||
echo "nestri-entry: audio routing may not work correctly" >&2
|
||||
fi
|
||||
else
|
||||
echo "nestri-entry: WARNING — pipewire not ready, continuing without audio" >&2
|
||||
fi
|
||||
|
||||
# Wait for WirePlumber to register the loopback node
|
||||
for i in $(seq 1 50); do
|
||||
if pw-cli ls Node 2>/dev/null | grep -q "nestri-source"; then
|
||||
break
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if pw-cli ls Node 2>/dev/null | grep -q "nestri-source"; then
|
||||
echo "nestri-entry: wireplumber ready, loopback node available" >&2
|
||||
else
|
||||
echo "nestri-entry: WARNING — loopback node not found after 5s" >&2
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 2. GStreamer Pipeline — Encoder Detection & Configuration
|
||||
#
|
||||
# VAAPI encoders come in two variants:
|
||||
# - vaXenc — standard encoder
|
||||
# - vaXlpenc — low-power variant (sometimes the only option)
|
||||
#
|
||||
# We probe for available encoders and use what's present.
|
||||
# ============================================================
|
||||
|
||||
# Check if a GStreamer element exists
|
||||
gst_element_exists() {
|
||||
gst-inspect-1.0 "$1" &>/dev/null
|
||||
}
|
||||
|
||||
# Find the best available VAAPI encoder for a codec
|
||||
find_vaapi_encoder() {
|
||||
local codec="$1"
|
||||
local standard_enc="va${codec}enc"
|
||||
local lowpower_enc="va${codec}lpenc"
|
||||
|
||||
# Prefer standard encoder, fall back to low-power
|
||||
if gst_element_exists "$standard_enc"; then
|
||||
echo "$standard_enc"
|
||||
elif gst_element_exists "$lowpower_enc"; then
|
||||
echo "$lowpower_enc"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 2. GStreamer Pipeline — Encoding Configuration
|
||||
#
|
||||
# GPU-specific encoding paths:
|
||||
#
|
||||
# NVIDIA (NVENC):
|
||||
# Memory: video/x-raw(memory:CUDAMemory)
|
||||
# H.264: nvh264enc (p1 preset, ultra-low-latency tune)
|
||||
# H.265: nvh265enc (p1 preset, ultra-low-latency tune)
|
||||
# AV1: nvav1enc (p1 preset, ultra-low-latency tune)
|
||||
#
|
||||
# Modern NVENC presets (p1-p7):
|
||||
# p1 = fastest (lowest quality)
|
||||
# p7 = slowest (highest quality)
|
||||
# Tunes: ultra-low-latency, low-latency, high-quality
|
||||
#
|
||||
#
|
||||
# Intel (QSV):
|
||||
# Memory: video/x-raw(memory:DMABuf) → vapostproc → video/x-raw(memory:VAMemory)
|
||||
# H.264: qsvh264enc
|
||||
# H.265: qsvh265enc
|
||||
# AV1: qsvav1enc
|
||||
#
|
||||
# target-usage is 7 for all (speed) with low-latency set to true
|
||||
#
|
||||
#
|
||||
# AMD/Intel/.. (VAAPI):
|
||||
# Memory: video/x-raw(memory:DMABuf) → vapostproc → video/x-raw(memory:VAMemory)
|
||||
# H.264: vah264enc or vah264lpenc (low-power variant)
|
||||
# H.265: vah265enc or vah265lpenc (low-power variant)
|
||||
# AV1: vaav1enc or vaav1lpenc (low-power variant)
|
||||
#
|
||||
# target-usage: 1 (quality) to 7 (speed)
|
||||
# For streaming, we use 7 (maximum speed/minimum latency)
|
||||
#
|
||||
# The vapostproc element converts DMA-BUF to VA-API memory and
|
||||
# transforms to NV12 format required by the VA-API encoders.
|
||||
# ============================================================
|
||||
|
||||
# Calculate GOP size (keyframe interval)
|
||||
# For low latency, we use 1-2 seconds worth of frames
|
||||
GOP_SIZE=$((NESTRI_FPS * 2))
|
||||
|
||||
setup_vaapi_encoder() {
|
||||
# AMD/Intel VAAPI path — uses DMA-BUF → VA-API memory
|
||||
# vapostproc handles colorspace conversion to NV12
|
||||
GST_MEM_CAPS="video/x-raw(memory:DMABuf),width=${NESTRI_WIDTH},height=${NESTRI_HEIGHT},framerate=${NESTRI_FPS}/1 ! vapostproc ! video/x-raw(memory:VAMemory),format=NV12"
|
||||
|
||||
case "$NESTRI_CODEC" in
|
||||
av1)
|
||||
VAAPI_ENC=$(find_vaapi_encoder "av1")
|
||||
if [ -z "$VAAPI_ENC" ]; then
|
||||
echo "nestri-entry: FATAL — no VAAPI AV1 encoder found" >&2
|
||||
echo "nestri-entry: tried: vaav1enc, vaav1penc" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "nestri-entry: using VAAPI encoder: $VAAPI_ENC" >&2
|
||||
GST_ENC="$VAAPI_ENC"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC key-int-max=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC target-usage=7"
|
||||
;;
|
||||
h265)
|
||||
VAAPI_ENC=$(find_vaapi_encoder "h265")
|
||||
if [ -z "$VAAPI_ENC" ]; then
|
||||
echo "nestri-entry: FATAL — no VAAPI H.265 encoder found" >&2
|
||||
echo "nestri-entry: tried: vah265enc, vah265lpenc" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "nestri-entry: using VAAPI encoder: $VAAPI_ENC" >&2
|
||||
GST_ENC="$VAAPI_ENC"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC key-int-max=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC target-usage=7"
|
||||
;;
|
||||
h264|*)
|
||||
VAAPI_ENC=$(find_vaapi_encoder "h264")
|
||||
if [ -z "$VAAPI_ENC" ]; then
|
||||
echo "nestri-entry: FATAL — no VAAPI H.264 encoder found" >&2
|
||||
echo "nestri-entry: tried: vah264enc, vah264lpenc" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "nestri-entry: using VAAPI encoder: $VAAPI_ENC" >&2
|
||||
GST_ENC="$VAAPI_ENC"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC key-int-max=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC target-usage=7"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Select memory caps and encoder based on GPU type
|
||||
case "$NESTRI_GPU" in
|
||||
nvidia)
|
||||
# NVIDIA NVENC path — uses CUDA memory
|
||||
# Modern presets: p1 (fastest) to p7 (highest quality)
|
||||
# Tunes: ultra-low-latency, low-latency, high-quality
|
||||
GST_MEM_CAPS="video/x-raw(memory:CUDAMemory),width=${NESTRI_WIDTH},height=${NESTRI_HEIGHT},framerate=${NESTRI_FPS}/1"
|
||||
|
||||
case "$NESTRI_CODEC" in
|
||||
av1)
|
||||
GST_ENC="nvav1enc"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC gop-size=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC preset=p1"
|
||||
GST_ENC="$GST_ENC tune=ultra-low-latency"
|
||||
GST_ENC="$GST_ENC multi-pass=disabled"
|
||||
GST_ENC="$GST_ENC zerolatency=true"
|
||||
;;
|
||||
h265)
|
||||
GST_ENC="nvh265enc"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC gop-size=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC preset=p1"
|
||||
GST_ENC="$GST_ENC tune=ultra-low-latency"
|
||||
GST_ENC="$GST_ENC multi-pass=disabled"
|
||||
GST_ENC="$GST_ENC zerolatency=true"
|
||||
;;
|
||||
h264|*)
|
||||
GST_ENC="nvh264enc"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC gop-size=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC preset=p1"
|
||||
GST_ENC="$GST_ENC tune=ultra-low-latency"
|
||||
GST_ENC="$GST_ENC multi-pass=disabled"
|
||||
GST_ENC="$GST_ENC zerolatency=true"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
intel)
|
||||
# Check for QSV element plugin
|
||||
if gst_element_exists "qsv"; then
|
||||
# Intel QSV path — uses DMA-BUF → VA-API memory
|
||||
# vapostproc handles colorspace conversion to NV12
|
||||
GST_MEM_CAPS="video/x-raw(memory:DMABuf),width=${NESTRI_WIDTH},height=${NESTRI_HEIGHT},framerate=${NESTRI_FPS}/1 ! vapostproc ! video/x-raw(memory:VAMemory),format=NV12"
|
||||
|
||||
case "$NESTRI_CODEC" in
|
||||
av1)
|
||||
GST_ENC="qsvav1enc"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC gop-size=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC target-usage=7"
|
||||
GST_ENC="$GST_ENC low-latency=true"
|
||||
;;
|
||||
h265)
|
||||
GST_ENC="qsvh265enc"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC gop-size=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC target-usage=7"
|
||||
GST_ENC="$GST_ENC low-latency=true"
|
||||
;;
|
||||
h264|*)
|
||||
GST_ENC="qsvh264enc"
|
||||
GST_ENC="$GST_ENC bitrate=${NESTRI_BITRATE}"
|
||||
GST_ENC="$GST_ENC gop-size=${GOP_SIZE}"
|
||||
GST_ENC="$GST_ENC target-usage=7"
|
||||
GST_ENC="$GST_ENC low-latency=true"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
# Fallback to VAAPI if no QSV available
|
||||
setup_vaapi_encoder
|
||||
fi
|
||||
;;
|
||||
|
||||
amd|*)
|
||||
setup_vaapi_encoder
|
||||
;;
|
||||
esac
|
||||
|
||||
# ============================================================
|
||||
# 2. GStreamer Pipeline — Launch
|
||||
#
|
||||
# Pipeline structure:
|
||||
#
|
||||
# Video path:
|
||||
# waylanddisplaysrc (compositor + capture)
|
||||
# → queue (buffer management)
|
||||
# → [GPU-specific caps + encoder]
|
||||
# → [codec parser]
|
||||
#
|
||||
# Audio path:
|
||||
# pipewiresrc (capture from PipeWire)
|
||||
# → audioconvert/audiorate/audioresample
|
||||
# → opusenc (Opus encoding @ 128kbps)
|
||||
#
|
||||
# Output:
|
||||
# nestrisink → QUIC/iroh-moq streaming
|
||||
#
|
||||
# waylanddisplaysrc IS the Wayland compositor:
|
||||
# - Creates socket at $XDG_RUNTIME_DIR/wayland-1
|
||||
# - Captures client buffers as DMA-BUF (zero-copy)
|
||||
# - Input events arrive via nestrisink (bidirectional)
|
||||
# ============================================================
|
||||
|
||||
echo "nestri-entry: starting gstreamer pipeline..." >&2
|
||||
echo "nestri-entry: resolution: ${NESTRI_WIDTH}x${NESTRI_HEIGHT}@${NESTRI_FPS}fps" >&2
|
||||
echo "nestri-entry: bitrate: ${NESTRI_BITRATE}kbps" >&2
|
||||
echo "nestri-entry: gop-size: ${GOP_SIZE} frames" >&2
|
||||
echo "nestri-entry: render: ${NESTRI_RENDER_NODE}" >&2
|
||||
echo "nestri-entry: gpu: ${NESTRI_GPU}" >&2
|
||||
echo "nestri-entry: codec: ${NESTRI_CODEC}" >&2
|
||||
echo "nestri-entry: encoder: ${GST_ENC%% *}" >&2
|
||||
echo "nestri-entry: broadcast: ${NESTRI_BROADCAST}" >&2
|
||||
|
||||
# Note: GST_MEM_CAPS and GST_ENC are intentionally unquoted
|
||||
# to allow bash word splitting for GStreamer's '!' element separators.
|
||||
|
||||
gst-launch-1.0 --gst-debug-no-color -e \
|
||||
nestrisink name=sink broadcast="$NESTRI_BROADCAST" \
|
||||
waylanddisplaysrc render-node="$NESTRI_RENDER_NODE" ! \
|
||||
queue max-size-buffers=2 max-size-time=0 max-size-bytes=0 ! \
|
||||
$GST_MEM_CAPS ! \
|
||||
$GST_ENC ! \
|
||||
sink. \
|
||||
pipewiresrc target-object="nestri-source" use-bufferpool=false do-timestamp=true ! \
|
||||
queue max-size-buffers=2 max-size-time=0 max-size-bytes=0 ! \
|
||||
"audio/x-raw,format=S16LE,channels=2,rate=48000" ! \
|
||||
audioconvert ! \
|
||||
audiorate ! \
|
||||
audioresample ! \
|
||||
opusenc bitrate=128000 frame-size=10 ! \
|
||||
sink. \
|
||||
>> /tmp/gstreamer.log 2>&1 &
|
||||
|
||||
GST_PID=$!
|
||||
PIDS+=($GST_PID)
|
||||
|
||||
# Wait for compositor socket
|
||||
for i in $(seq 1 100); do
|
||||
[ -S "$XDG_RUNTIME_DIR/wayland-1" ] && break
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if [ ! -S "$XDG_RUNTIME_DIR/wayland-1" ]; then
|
||||
echo "nestri-entry: FATAL — compositor socket not created" >&2
|
||||
echo "nestri-entry: check waylanddisplaysrc plugin and GPU access" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "nestri-entry: wayland compositor ready at $XDG_RUNTIME_DIR/wayland-1" >&2
|
||||
|
||||
# X_DISPLAY_NUM="12"
|
||||
|
||||
# X_SOCKET="/tmp/.X11-unix/X$X_DISPLAY_NUM"
|
||||
|
||||
# # Launch the XWayland satellite process to handle X11 clients in the VM.
|
||||
# xwayland-satellite ":$X_DISPLAY_NUM" >> /tmp/x11.log 2>&1 &
|
||||
# PIDS+=($!)
|
||||
|
||||
# # Wait for X11 socket
|
||||
# for i in $(seq 1 100); do
|
||||
# [ -S "$X_SOCKET" ] && break
|
||||
# sleep 0.1
|
||||
# done
|
||||
|
||||
# if [ ! -S "$X_SOCKET" ]; then
|
||||
# echo "nestri-entry: FATAL — X11 socket $X_SOCKET not created" >&2
|
||||
# echo "nestri-entry: check xwayland-satellite logs for startup errors" >&2
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# echo "nestri-entry: X11 server ready at $X_SOCKET" >&2
|
||||
|
||||
# export DISPLAY=":$X_DISPLAY_NUM"
|
||||
# ============================================================
|
||||
# DNS Setup
|
||||
#
|
||||
# passt (muvm's network backend) reads /etc/resolv.conf from
|
||||
# the bwrap namespace to get DNS servers for the VM's DHCP.
|
||||
# The rootfs may have a stale or symlinked resolv.conf.
|
||||
# We overwrite it here with the real DNS from the host.
|
||||
#
|
||||
# nestri-init also tries to copy /run/nestri/resolv.conf into
|
||||
# the VM's /etc/resolv.conf, but that often fails because the
|
||||
# VM filesystem may be read-only. Fixing it here in the bwrap
|
||||
# layer ensures passt gets the right servers.
|
||||
# ============================================================
|
||||
|
||||
if [ -f /run/nestri/resolv.conf ]; then
|
||||
# Remove symlink if present, then write directly
|
||||
rm -f /etc/resolv.conf 2>/dev/null || true
|
||||
cp /run/nestri/resolv.conf /etc/resolv.conf 2>/dev/null || {
|
||||
# If /etc is somehow read-only, try writing in-place
|
||||
cat /run/nestri/resolv.conf > /etc/resolv.conf 2>/dev/null || true
|
||||
}
|
||||
echo "nestri-entry: DNS configured:" >&2
|
||||
cat /etc/resolv.conf >&2
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 3. muvm — MicroVM Launch
|
||||
#
|
||||
# The VM boots from this same filesystem via virtiofs.
|
||||
# nestri-init wraps systemd, setting up machine-id, dns, etc.
|
||||
#
|
||||
# Guest systemd services (started automatically):
|
||||
# nestri-network.service — muvm-configure-network (networking)
|
||||
# nestri-wayland-proxy.* — wl-cross-domain-proxy (socket-activated)
|
||||
# nestri-pwbridge.* — muvm-pwbridge (socket-activated audio)
|
||||
# nestri-session-bus.* — dbus-daemon (socket-activated)
|
||||
# nestri-remote.service — muvm-remote (runs user command)
|
||||
#
|
||||
# Cross-domain Wayland proxy:
|
||||
# The VM guest runs wl-cross-domain-proxy which connects to
|
||||
# the host's wayland-1 socket via virtio-gpu cross-domain context.
|
||||
# This allows the guest gamescope to render to the host compositor.
|
||||
#
|
||||
# Environment passed to guest:
|
||||
# WAYLAND_DISPLAY=wayland-1 — compositor socket name
|
||||
# XDG_RUNTIME_DIR=/run/vm-user — guest runtime directory
|
||||
# XDG_SESSION_TYPE=wayland — session type hint
|
||||
# SDL_VIDEODRIVER=wayland — force SDL wayland backend
|
||||
# SDL_AUDIO_DRIVER=pipewire — force SDL pipewire audio
|
||||
# NESTRI_* — stream configuration
|
||||
# ============================================================
|
||||
echo "nestri-entry: starting muvm..." >&2
|
||||
|
||||
# -e "SDL_VIDEODRIVER=wayland" \
|
||||
# -e "ELECTRON_OZONE_PLATFORM_HINT=wayland" \
|
||||
# -e "_JAVA_AWT_WM_NONREPARENTING=1" \
|
||||
# -e "QT_QPA_PLATFORM=wayland" \
|
||||
|
||||
muvm \
|
||||
--custom-init-cmdline "nestri-init /sbin/init --echo-target=console" \
|
||||
-e "container=muvm" \
|
||||
-e "XDG_SESSION_TYPE=wayland" \
|
||||
-e "XDG_RUNTIME_DIR=/run/vm-user" \
|
||||
-e "SDL_AUDIO_DRIVER=pipewire" \
|
||||
-e "WAYLAND_DISPLAY=wayland-1" \
|
||||
-e "VK_DRIVER_FILES=$VK_DRIVER_FILES" \
|
||||
-e "NESTRI_WIDTH=$NESTRI_WIDTH" \
|
||||
-e "NESTRI_HEIGHT=$NESTRI_HEIGHT" \
|
||||
-e "NESTRI_FPS=$NESTRI_FPS" \
|
||||
-e "MICROVM_UID=$MICROVM_UID" \
|
||||
-e "MICROVM_GID=${MICROVM_GID:-$MICROVM_UID}" \
|
||||
-e "BOOT_TIME_OFFSET=${BOOT_TIME_OFFSET:-}" \
|
||||
-i -t \
|
||||
"$@"
|
||||
|
||||
MUVM_EXIT=$?
|
||||
|
||||
echo "nestri-entry: muvm exited with code $MUVM_EXIT" >&2
|
||||
|
||||
exit $MUVM_EXIT
|
||||
# /usr/bin/steam -gamepadui -cef-force-gpu &
|
||||
# STEAM_PID=$!
|
||||
# PIDS+=($STEAM_PID)
|
||||
|
||||
# wait $STEAM_PID
|
||||
93
build/usr/bin/nestri-init
Normal file
93
build/usr/bin/nestri-init
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# ============================================================
|
||||
# 1. Save files from old /run
|
||||
# ============================================================
|
||||
_resolv=""
|
||||
_localtime=""
|
||||
[ -f /run/nestri/resolv.conf ] && _resolv=$(cat /run/nestri/resolv.conf)
|
||||
[ -f /run/nestri/localtime ] && _localtime=$(base64 /run/nestri/localtime 2>/dev/null) || true
|
||||
|
||||
# ============================================================
|
||||
# 2. Fresh tmpfs on /run
|
||||
# ============================================================
|
||||
mount -t tmpfs tmpfs /run -o nosuid,nodev,strictatime
|
||||
|
||||
# ============================================================
|
||||
# 3. Restore saved files
|
||||
# ============================================================
|
||||
if [ -n "$_resolv" ]; then
|
||||
echo "$_resolv" > /run/resolv.conf
|
||||
echo "$_resolv" > /etc/resolv.conf 2>/dev/null || true
|
||||
fi
|
||||
if [ -n "$_localtime" ]; then
|
||||
echo "$_localtime" | base64 -d > /run/localtime
|
||||
echo "$_localtime" | base64 -d > /etc/localtime 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 4. Machine ID
|
||||
# ============================================================
|
||||
# FIXME(wanjohiryan): Use the same machine-id as the host? For Steam, i believe it does check machine id and stuff like that for SteamGuard
|
||||
if [ ! -s /etc/machine-id ]; then
|
||||
head -c 16 /dev/urandom | od -A n -t x1 | tr -d ' \n' > /etc/machine-id
|
||||
echo "" >> /etc/machine-id
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 5. Journald
|
||||
# ============================================================
|
||||
mkdir -p /run/systemd/journal /run/log/journal
|
||||
|
||||
mkdir -p /etc/systemd/system/systemd-journald.service.d
|
||||
cat > /etc/systemd/system/systemd-journald.service.d/override.conf << 'EOF'
|
||||
[Service]
|
||||
RuntimeDirectory=
|
||||
LogsDirectory=
|
||||
StateDirectory=
|
||||
ExecStartPre=/bin/mkdir -p /run/systemd/journal /run/log/journal
|
||||
EOF
|
||||
|
||||
# ============================================================
|
||||
# 6. Hide container FILE markers (ro rootfs)
|
||||
# But DO NOT strip the `container` env var!
|
||||
# systemd needs it for exit.target (clean shutdown).
|
||||
# ============================================================
|
||||
for marker in /.dockerenv /run/.containerenv; do
|
||||
if [ -e "$marker" ]; then
|
||||
mount --bind /dev/null "$marker" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
|
||||
# ============================================================
|
||||
# 8. Isolate X11 socket directory
|
||||
# ============================================================
|
||||
if [ -d /tmp/.X11-unix ]; then
|
||||
mount -t tmpfs tmpfs /tmp/.X11-unix -o noexec,nosuid,relatime
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 9. Remount /dev/shm as virtiofs with DAX
|
||||
# (required for cross-domain shared memory, DRI3 fences)
|
||||
# ============================================================
|
||||
umount /dev/shm
|
||||
mount -t virtiofs devshm /dev/shm -o noexec,nosuid,dax
|
||||
|
||||
# ============================================================
|
||||
# 10. Boot time offset
|
||||
# ============================================================
|
||||
if [ -n "$BOOT_TIME_OFFSET" ]; then
|
||||
if unshare --time true 2>/dev/null; then
|
||||
exec unshare --time -- bash -c '
|
||||
echo "monotonic '"$BOOT_TIME_OFFSET"'" > /proc/self/timens_offsets 2>/dev/null
|
||||
echo "boottime '"$BOOT_TIME_OFFSET"'" >> /proc/self/timens_offsets 2>/dev/null
|
||||
exec "$@"
|
||||
' -- "$@"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 11. Hand off to systemd
|
||||
# ============================================================
|
||||
exec "$@"
|
||||
BIN
build/usr/bin/steam-token.exe
Executable file
BIN
build/usr/bin/steam-token.exe
Executable file
Binary file not shown.
Reference in New Issue
Block a user