0

What I'm talking about here is the horrid combination Optirun/Primusrun + PlayonLinux + Steam that makes for wrappers over wrappers over wrappers (primus/optirun calls playonlinux, which calls wine through a bunch of wrapper scripts, which in turn calls steam, which finally calls your game executable)

And, no, it does not work so well.

In my case the game in question is Audiosurf (first of its name), although I'm also interested in making other games (like Skyrim) run the same way.

The Facts

What I'm sure of is that the game runs. But not on the nvidia card.
I've done the following stupid test :

  1. Check the status of the bumblebee daemon
    systemctl status bumblebeed
    Watch for the CGroup line :

    CGroup: /system.slice/bumblebeed.service
                  └─809 /usr/sbin/bumblebeed

  2. Run glxgears on bumblebee
    primusrun glxgears

  3. While still running glxgears, check again for bumblebee
    systemctl status bumblebeed

    CGroup: /system.slice/bumblebeed.service
                  ├─ 809 /usr/sbin/bumblebeed
                  └─3707 Xorg :8 -config /etc/bumblebee/xorg.conf.nvidia -configdir ...

    As to be expected there is now an instance of the X server, spawned by bumblebee, which is running glxgears on the nvidia card

  4. Stop glxgears and check again : The X.org instance is gone

  5. Now launch the steam game through primusrun
    primusrun /usr/share/playonlinux/playonlinux --run "Steam" -applaunch 12900

  6. And check the status of Bumblebee : Back at step 1, no Xorg child. (Be sure to be in-game when you do that, not just in the menu)

I used primusrun because if the program doesn't use the graphics card then no Xorg instance is spawned, whereas optirun somehow forces the instantiation of Worg

I even went so far as to stop the bumblebee daemon to make sure the game was still running (DON'T DO THAT! If the program is really running on the nvidia card that would not only freeze the window on your side, but also stall the GPU)

The Conjectures

So, right, the game doesn't run on Bumblebee ; But where's the problem?

It has to be because, somewhere, one of the wrappers spawns a new process and returns. Making the target process unreachable to primusrun. But who's to blame?
Is it one of the multiple wrappers used by playonlinux? Or is it just steam?

Or maybe it's even deeper than that : What if Audiosurf simply doesn't use opengl? Of course it doesn't natively, but doesn't wine translate DirectX calls to opengl calls?


Leaving that gloomy hypothesis aside, I figured I should get as close as I could to the executable before calling primusrun. The ideal being something like primusrun wine game.exe.

So how do I do that?

Well, for starters, I found the "Command to exec before running the program" in the "Miscellaneous" tab of the playonlinux configuration window, as hinted by this line :

You can use this box to prefix commands to the shortcut. Handy in, say, the case of laptops with Nvidia and Intel graphics, and you need to use prefix primusrun or optirun before starting a particular game.

But it turns out this is complete BOLLOCKS

After a little poking around the sources of PlayonLinux, I found the bastard :

if [ -e "$HOME/.PlayOnLinux/configurations/pre_shortcut/$NAME" ]; then source "$HOME/.PlayOnLinux/configurations/pre_shortcut/$NAME" fi exec ./playonlinux-bash "$HOME/.PlayOnLinux/shortcuts/$NAME" "$@"

The $HOME/.PlayOnLinux/configurations/pre_shortcut/$NAME file is where the "Command to exec before running the program" field is saved. As you can see, this file is sourced which means you can do a bunch of stuff before running the program (that would be the last line with the exec command), but not as you're running it.

So calling any wrapper like primusrun in this box would be like beating the air.

Nevertheless, following that lead further, I also found that $HOME/.PlayOnLinux/shortcuts/$NAME contains a call to the POL_Wine function followed by the actual .exe file, and that's about as far as I've gotten into the chain of wrappers used by POL.

Bottom Note

I realise I have greatly diverged from the topic by going into details but I truly mean for this question to include any steam game not yet available natively on Linux that might have the same issues, so I'll try and reformulate the questions here (please don't just answer them with "You could do this hack to make it work with Audiosurf") :

  • Why is my game not running on the discrete nvidia card when I used primusrun/optirun?
  • What can I do to work around this?
1

I can answer your second question: What can I do to work around this?

What we want to do is to run Steam through PlayonLinux with optirun/primusrun as a prefix. All games that you run through Steam will also be launched automatically like this.

We have to go to /usr/share/playonlinux/lib/

There is a file there called wine.lib that we will edit.

Important: Create a backup of that file just in case something breaks.

Inside the file, there is a function called POL_Wine ().

Basically what we want to change inside this function is the way wine is executed everytime you launch an app through PlayonLinux.

So inside this function you have to find all the parts where wine is called. Look for wine "$@" in the file with ctrl+F in your favourite text editor. In my file there were 3 occurences of wine "$@".

Before every occurence, I just added primusrun so it looks like primusrun wine "$@". You can try optirun or optirun -b primus as well, but primusrun is what works for me.

This is how the section I edited looks like now:

if [ "$POL_OS" = "Linux" ] || [ "$POL_OS" = "Mac" ];
then
    if [ "$LOGFILE" = "/dev/null" ]; then
        $BEFORE_WINE $(POL_Config_Read BEFORE_WINE) primusrun wine "$@"  2> >(grep -v menubuilder --line-buffered | tee -a "$WINEPREFIX/playonlinux.log" >&2) > >(tee -a "$WINEPREFIX/playonlinux.log")
        errors=$?
    else
        $BEFORE_WINE $(POL_Config_Read BEFORE_WINE) primusrun wine "$@" 2> >(grep -v menubuilder --line-buffered | tee -a "$LOGFILE" "$WINEPREFIX/playonlinux.log" >&2) > >(tee -a "$LOGFILE" "$WINEPREFIX/playonlinux.log")
        errors=$?
    fi
else
    # FIXME 
    $BEFORE_WINE $(POL_Config_Read BEFORE_WINE) primusrun wine "$@"  2> "$WINEPREFIX/playonlinux.log" > "$WINEPREFIX/playonlinux.log"
    errors=$?
fi

Save the file and start PlayonLinux normally.

You can check anytime if your discrete video card is used or not by running the following command in a terminal:

optirun --status

When it is NOT used the output looks like this:

Bumblebee status: Ready (3.2.1). X inactive. Discrete video card is off.

Select Steam from your PlayonLinux apps and run it. When it launches check with optirun --status to see if your discrete card is activated.

My output looked like this:

Bumblebee status: Ready (3.2.1). X is PID 26685, 1 applications using bumblebeed.

Great! Steam now is using your discrete card!

Now, let's try launching a game on Steam. Pick one and launch it normally (no need to fiddle with launch options on Steam).

Check again with optirun --status. Output should look like this :

Bumblebee status: Ready (3.2.1). X is PID 26685, 2 applications using bumblebeed.

Wondeful! The game you launched is also using your discrete card!

The beauty of this is that it works with any app you run through PlayonLinux, not just Steam.

To revert the changes, just use your backup file you created, or just delete the prefixes you added in wine.lib and save the file. Try all the different prefixes I mentioned above if you run into problems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.