diff --git a/Dockerfile b/Dockerfile index c6a1341..5a40fb3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,7 @@ ARG GMMLIB_VERSION=22.3.12 ARG INTEL_MEDIA_DRIVER_VERSION=23.3.5 ARG INTEL_MEDIA_SDK_VERSION=23.2.2 ARG INTEL_ONEVPL_GPU_RUNTIME_VERSION=23.3.4 +ARG CPU_FEATURES_VERSION=0.9.0 # Define software download URLs. ARG HANDBRAKE_URL=https://github.com/HandBrake/HandBrake/releases/download/${HANDBRAKE_VERSION}/HandBrake-${HANDBRAKE_VERSION}-source.tar.bz2 @@ -24,6 +25,7 @@ ARG GMMLIB_URL=https://github.com/intel/gmmlib/archive/intel-gmmlib-${GMMLIB_VER ARG INTEL_MEDIA_DRIVER_URL=https://github.com/intel/media-driver/archive/intel-media-${INTEL_MEDIA_DRIVER_VERSION}.tar.gz ARG INTEL_MEDIA_SDK_URL=https://github.com/Intel-Media-SDK/MediaSDK/archive/intel-mediasdk-${INTEL_MEDIA_SDK_VERSION}.tar.gz ARG INTEL_ONEVPL_GPU_RUNTIME_URL=https://github.com/oneapi-src/oneVPL-intel-gpu/archive/refs/tags/intel-onevpl-${INTEL_ONEVPL_GPU_RUNTIME_VERSION}.tar.gz +ARG CPU_FEATURES_URL=https://github.com/google/cpu_features/archive/refs/tags/v${CPU_FEATURES_VERSION}.tar.gz # Set to 'max' to keep debug symbols. ARG HANDBRAKE_DEBUG_MODE=none @@ -59,6 +61,15 @@ RUN xx-verify \ /tmp/handbrake-install/usr/bin/ghb \ /tmp/handbrake-install/usr/bin/HandBrakeCLI +# Build cpu_features. +FROM --platform=$BUILDPLATFORM alpine:3.17 AS cpu_features +ARG TARGETPLATFORM +ARG CPU_FEATURES_URL +COPY --from=xx / / +COPY src/cpu_features /build +RUN /build/build.sh "$CPU_FEATURES_URL" +RUN xx-verify /tmp/cpu_features-install/bin/list_cpu_features + # Pull base image. FROM jlesage/baseimage-gui:alpine-3.17-v4.5.1 @@ -116,6 +127,7 @@ RUN \ # Add files. COPY rootfs/ / COPY --from=handbrake /tmp/handbrake-install / +COPY --from=cpu_features /tmp/cpu_features-install/bin/list_cpu_features /usr/bin/ # Set internal environment variables. RUN \ diff --git a/rootfs/etc/cont-init.d/54-check-qsv.sh b/rootfs/etc/cont-init.d/54-check-qsv.sh index 59d8374..a5b684d 100755 --- a/rootfs/etc/cont-init.d/54-check-qsv.sh +++ b/rootfs/etc/cont-init.d/54-check-qsv.sh @@ -5,14 +5,63 @@ set -u # Treat unset variables as an error. DRI_DIR="/dev/dri" DRI_DEV="$DRI_DIR/renderD128" -PROCESSOR_NAME="$(cat /proc/cpuinfo | grep "model name" | head -n1 | cut -d':' -f2 | xargs)" +PROCESSOR_NAME="$(list_cpu_features | grep "^brand " | awk -F ':' '{ gsub(/^[ \t]+/,"",$2); print $2 }')" +MICROARCHITECTURE="$(list_cpu_features | grep "^uarch " | awk -F ':' '{ gsub(/^[ \t]+/,"",$2); print $2 }')" + +CPU_QSV_CAPABLE=true +CPU_SUPPORTED_BY_HB=true echo "Processor: $PROCESSOR_NAME" +echo "Microarchitecture: $MICROARCHITECTURE" -if ! echo "$PROCESSOR_NAME" | grep -qiwE "(INTEL|KVM|QEMU)"; then - echo "Intel Quick Sync Video not supported: not a supported processor." - exit 0 -fi +# +# Determine if the microarchitecture supports QSV. If it does, verify if it is +# supported by HandBrake. +# +# See the following references: +# https://en.wikipedia.org/w/index.php?title=Intel_Quick_Sync_Video +# https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures +# https://github.com/google/cpu_features/blob/main/include/cpuinfo_x86.h +# https://handbrake.fr/docs/en/latest/technical/video-qsv.html +# +case "$MICROARCHITECTURE" in + # QSV Version 1 + INTEL_SNB) # SANDYBRIDGE + CPU_SUPPORTED_BY_HB=false + ;; + # QSV Version 2 + INTEL_IVB) # IVYBRIDGE + CPU_SUPPORTED_BY_HB=false + ;; + # QSV Version 3 + INTEL_HSW) # HASWELL + CPU_SUPPORTED_BY_HB=false + ;; + # QSV Version 4 + INTEL_BDW) # BROADWELL + CPU_SUPPORTED_BY_HB=false + ;; + # QSV Version 5 + INTEL_SKL) ;; # SKYLAKE + # QSV Version 6 + INTEL_KBL) ;; # KABY LAKE + INTEL_CFL) ;; # COFFEE LAKE + INTEL_WHL) ;; # WHISKEY LAKE + INTEL_CML) ;; # COMET LAKE + # QSV Version 7 + INTEL_ICL) ;; # ICE LAKE + # QSV Version 8 + INTEL_TGL) ;; # TIGER LAKE + INTEL_RCL) ;; # ROCKET LAKE + INTEL_ADL) ;; # ALDER LAKE + INTEL_RPL) ;; # RAPTOR LAKE + # QSV Version 9 + # Only Intel ARC for now. + # QSV not supported by the processor. + *) + CPU_QSV_CAPABLE=false + ;; +esac if [ ! -d "$DRI_DIR" ]; then echo "Intel Quick Sync Video not supported: device directory $DRI_DIR not exposed to the container." @@ -29,6 +78,14 @@ if ! lspci -k | grep -qw i915; then exit 0 fi +# Intel ARC is a discrete GPU that supports QSV. This means that QSV might be +# usable even if CPU doesn't support it. +if ! $CPU_QSV_CAPABLE; then + echo "Intel Quick Sync Video may not be supported: processor not QSV capable." +elif ! $CPU_SUPPORTED_BY_HB; then + echo "Intel Quick Sync Video may not be supported: processor not supported by HandBrake." +fi + # Get group of devices under /dev/dri/. find /dev/dri/ -type c | while read DRI_DEV do diff --git a/src/cpu_features/build.sh b/src/cpu_features/build.sh new file mode 100755 index 0000000..cd6b9f5 --- /dev/null +++ b/src/cpu_features/build.sh @@ -0,0 +1,107 @@ +#!/bin/sh + +set -e # Exit immediately if a command exits with a non-zero status. +set -u # Treat unset variables as an error. + +# Set same default compilation flags as abuild. +export CFLAGS="-fomit-frame-pointer" +export CXXFLAGS="$CFLAGS" +export CPPFLAGS="$CFLAGS" +export LDFLAGS="-Wl,--strip-all -Wl,--as-needed" + +export CC=xx-clang +export CXX=xx-clang++ + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +function log { + echo ">>> $*" +} + +CPU_FEATURES_URL="${1:-}" + +if [ -z "$CPU_FEATURES_URL" ]; then + log "ERROR: URL missing." + exit 1 +fi + +# +# Install required packages. +# +apk --no-cache add \ + curl \ + clang15 \ + make \ + cmake \ + +# binutils \ +# git \ +# llvm15 \ +# pkgconf \ +# autoconf \ +# automake \ +# libtool \ +# yasm \ +# m4 \ +# patch \ +# coreutils \ +# tar \ +# file \ +# pythonispython3 \ +# intltool \ +# diffutils \ +# bash \ +# nasm \ +# meson \ +# cargo \ +# cargo-c \ +# gettext-dev \ +# glib-dev \ + +xx-apk --no-cache --no-scripts add \ + musl-dev \ + gcc \ + +# g++ \ +# linux-headers \ + +# +# Download sources. +# + +#log "Downloading x264 sources..." +#mkdir /tmp/x264 +#curl -# -L -f ${X264_URL} | tar xz --strip 1 -C /tmp/x264 + +log "Downloading cpu_features sources..." +mkdir /tmp/cpu_features +curl -# -L -f ${CPU_FEATURES_URL} | tar xz --strip 1 -C /tmp/cpu_features + +# +# Compile cpu_features. +# + +log "Configuring cpu_features..." +( + mkdir /tmp/cpu_features/build && \ + cd /tmp/cpu_features/build && cmake \ + $(xx-clang --print-cmake-defines) \ + -DCMAKE_FIND_ROOT_PATH=$(xx-info sysroot) \ + -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \ + -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \ + -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \ + -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \ + -DCMAKE_INSTALL_PREFIX=/tmp/cpu_features-install \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=OFF \ + -DENABLE_INSTALL=ON \ + -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_EXECUTABLE=ON \ + ../ +) + +log "Compiling cpu_features..." +make -C /tmp/cpu_features/build -j$(nproc) + +log "Installing cpu_features..." +make -C /tmp/cpu_features/build install