Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ parts:
cp vkcube $CRAFT_PART_INSTALL/bin/
cp glxinfo $CRAFT_PART_INSTALL/bin/
cp glxgears $CRAFT_PART_INSTALL/bin/
cp gpu $CRAFT_PART_INSTALL/bin/
cp vulkaninfo $CRAFT_PART_INSTALL/bin/
cp vkcube $CRAFT_PART_INSTALL/bin/
cp glxinfo $CRAFT_PART_INSTALL/bin/
cp glxgears $CRAFT_PART_INSTALL/bin/
cp gpu $CRAFT_PART_INSTALL/bin/
cp steam-snap.sh $CRAFT_PART_INSTALL/bin/

alsa-mixin:
plugin: dump
Expand Down Expand Up @@ -359,6 +366,12 @@ apps:
- steam-support
- removable-media
- upower-observe
gpu:
command-chain: [bin/desktop-launch]
command: bin/gpu
plugs:
- system-observe
- hardware-observe
report:
command-chain: [bin/desktop-launch]
command: bin/steamreport
Expand Down
2 changes: 1 addition & 1 deletion src/desktop-launch
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,4 @@ if [ -n "$SNAP_DESKTOP_DEBUG" ]; then
echo "Now running: exec $*"
fi

exec "$@"
$SNAP/bin/gpu $@
91 changes: 91 additions & 0 deletions src/gpu
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/python3

import json
import os
import re
import argparse
import subprocess
import sys

NVIDIA_ENV = {
"__NV_PRIME_RENDER_OFFLOAD": 1,
"__GLX_VENDOR_LIBRARY_NAME": "nvidia",
"__VK_LAYER_NV_optimus": "NVIDIA_only",
}

def get_gpus() -> dict:
"""
Get GPU data including:
shortened PCI number,
GPU name,
and environment variables to use the GPU.
"""
lspci = os.popen("lspci | grep VGA").read()
gpus = {}

for gpu in lspci.splitlines():
split = gpu.split(" VGA compatible controller: ")
pci = f"pci-0000_{split[0]}"\
.replace(":", "_")\
.replace(".", "_")
pci_num = int(re.sub(r"[^0-9]+", "", pci))

gpus[pci_num] = {}
gpus[pci_num]["gpu"] = split[1]
gpus[pci_num]["env"] = {"DRI_PRIME": pci}
if "nvidia" in split[1].lower():
gpus[pci_num]["env"].update(NVIDIA_ENV)

return gpus


def main() -> None:
# Parse arugments
parser = argparse.ArgumentParser()
parser.add_argument(
"--gpu", "-g",
help="Select a GPU to use"
)
parser.add_argument(
"--list", "-l",
help="List available GPUs",
const=True,
action="store_const"
)
parser.add_argument(
"--json", "-j",
help="List all data in json format",
const=True,
action="store_const"
)
args, nonargs = parser.parse_known_args()
nargs = sum([1 for a in vars(args).values() if a is not None])

# Handle arguments
if nargs != 0:
gpus = get_gpus()

# List GPUs with shortened PCI ID and name
if args.list:
[print(f"{k:6}: {v['gpu']}") for k, v in gpus.items()]
return

# List GPU data in JSON format
if args.json:
print(json.dumps(gpus, indent=4))
return

# Sets environment variables for the specified GPU
if args.gpu:
if int(args.gpu) not in gpus:
print("Invalid GPU ID, use --list to list GPUs.")
for k, v in gpus[int(args.gpu)]["env"].items():
os.environ[k] = str(v)

# Run remaining arguments as a command
if nonargs:
subprocess.call(nonargs)


if __name__ == "__main__":
main()
22 changes: 22 additions & 0 deletions src/newgpu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

NVIDIA_ENV="__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia __VK_LAYER_NV_optimus=NVIDIA_only"
lspci=$(lspci | grep VGA)
IFS=$'\n' read -rd '' -a gpus <<< "$lspci"
env_string=""

for gpu in "${gpus[@]}"
do
split=($(echo $gpu | awk '{split($0,a," VGA compatible controller: "); print a[1], a[2]}'))
pci=$(echo ${split[0]} | sed 's/:/_/g' | sed 's/\./_/g' | awk '{print "pci-0000_"$0}')

if [[ $(echo ${split[1]} | tr '[:upper:]' '[:lower:]') =~ "nvidia" ]]; then
env_string="DRI_PRIME=$pci $NVIDIA_ENV"
break
elif [[ $(echo ${split[1]} | tr '[:upper:]' '[:lower:]') =~ "amd" ]]; then
env_string="DRI_PRIME=$pci"
break
fi
done

echo $env_string