Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ForcedGpu option #206

Merged
merged 34 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
acb120e
Minor formatting fix
jrelvas-ipc Oct 14, 2023
1cb163f
WIP: Added ForcedGpuId and PrimeOffload options
jrelvas-ipc Oct 15, 2023
16634d3
Global.PrimeOffload set to true by default
jrelvas-ipc Oct 15, 2023
684c12d
Remove unnecessary error handling for sysfs IO
jrelvas-ipc Oct 15, 2023
3a8da28
Refactor: Merge Prime & ForcedGpuId into ForcedGpu
jrelvas-ipc Oct 15, 2023
95e71d0
ForcedGpu is now validated by config.go
jrelvas-ipc Oct 15, 2023
0f314ad
prime: Do not redefine existing env vars
jrelvas-ipc Oct 15, 2023
aa5b714
prime: handle cases with 3+ gpus and opengl
jrelvas-ipc Oct 15, 2023
d3a0e09
prime: Remove vendor check, only probe driver.
jrelvas-ipc Oct 15, 2023
fcb9305
prime -> gpu: major codebase refactor
jrelvas-ipc Oct 16, 2023
693f364
Yet another refactor: removed vid:nid logic
jrelvas-ipc Oct 16, 2023
9d20c2c
oops: fixed inverted condition in gpu probe
jrelvas-ipc Oct 16, 2023
8cddff0
gpu: validate if index exists by checking length
jrelvas-ipc Oct 16, 2023
377fbd2
gpu: use PrimeNone string instead of literal
jrelvas-ipc Oct 17, 2023
083ebbb
Merge branch 'vinegarhq:master' into dgpu-prime
jrelvas-ipc Oct 24, 2023
2346e83
card: Refactor prime logic around new sysinfo
jrelvas-ipc Oct 24, 2023
b3c37e4
cardpick: Remove unnecessary env return
jrelvas-ipc Oct 24, 2023
21fcec0
cardpick: improve readbility, consolidate prime
jrelvas-ipc Oct 24, 2023
67d097b
setIfUndefined as env method instead of function
jrelvas-ipc Oct 24, 2023
34a18a8
Simplify prime check variable names
jrelvas-ipc Oct 24, 2023
1db1543
Fix env "set if undefined" method
jrelvas-ipc Oct 24, 2023
bb13dbc
Remove log for env set
jrelvas-ipc Oct 24, 2023
0169b7f
Update cardpick code for suggestions made
jrelvas-ipc Oct 24, 2023
89b5f9f
Consolidate BinaryParse into setup method
jrelvas-ipc Oct 24, 2023
811a541
Do not run pickCard logic if opt is empty string
jrelvas-ipc Oct 24, 2023
e97a9ba
Reduced complexity of cardpick prime check
jrelvas-ipc Oct 24, 2023
3eadaaf
The pickCard rewrite.
jrelvas-ipc Oct 24, 2023
fa1fe00
Turn pickCard into a binary method
jrelvas-ipc Oct 24, 2023
cd0c3b7
config: return error directly in binary setup
jrelvas-ipc Oct 24, 2023
901456d
cardpick: Declare aIdx and prime in one var clause
jrelvas-ipc Oct 24, 2023
a750fd7
cardpick: removed unnecessary opt var
jrelvas-ipc Oct 24, 2023
8018629
Update internal/config/cardpick.go (format change)
jrelvas-ipc Oct 24, 2023
e0f46e1
env: use self directly in set
jrelvas-ipc Oct 24, 2023
12c8a17
binary: Moved setenv from pickCard into setup.
jrelvas-ipc Oct 24, 2023
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
79 changes: 79 additions & 0 deletions internal/config/cardpick.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package config

import (
"errors"
"fmt"
"strconv"
"strings"

"github.com/vinegarhq/vinegar/sysinfo"
)

// opt accepts the following values:
// aliases - "integrated", "prime-discrete" and "none": Equivalent to "0", "1" or empty. Enables an extra "prime" check.
// integer - GPU index
// empty - Skips logic and does nothing.
func (b *Binary) pickCard() error {
aliases := map[string]string{
"integrated": "0",
"prime-discrete": "1",
"none": "",
}

var (
aIdx string
prime bool
)

aIdx = b.ForcedGpu
if a, ok := aliases[b.ForcedGpu]; ok {
aIdx = a
prime = true
}

if aIdx == "" {
return nil
}

n := len(sysinfo.Cards)

// Check if the system actually has PRIME offload and there's no ambiguity with the GPUs.
if prime {
vk := (b.Dxvk && b.Renderer == "D3D11") || b.Renderer == "Vulkan"

if n != 2 && (!vk && n != 1) {
return fmt.Errorf("opengl is not capable of choosing the right gpu, it must be explicitly defined")
}

if n != 2 {
return nil
}

if !sysinfo.Cards[0].Embedded {
return nil
}
}

idx, err := strconv.Atoi(aIdx)
if err != nil {
return err
}

if idx < 0 {
return errors.New("gpu index cannot be negative")
}
if n < idx+1 {
return errors.New("gpu not found")
}
c := sysinfo.Cards[idx]

b.Env.Set("MESA_VK_DEVICE_SELECT_FORCE_DEFAULT_DEVICE", "1")
b.Env.Set("DRI_PRIME", aIdx)

if strings.HasSuffix(c.Driver, "nvidia") { //Workaround for OpenGL in nvidia GPUs
b.Env.Set("__GLX_VENDOR_LIBRARY_NAME", "nvidia")
} else {
b.Env.Set("__GLX_VENDOR_LIBRARY_NAME", "mesa")
}
return nil
}
25 changes: 23 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Binary struct {
Dxvk bool `toml:"dxvk"`
FFlags roblox.FFlags `toml:"fflags"`
Env Environment `toml:"env"`
ForcedGpu string `toml:"gpu"`
}

type Config struct {
Expand Down Expand Up @@ -88,6 +89,9 @@ func Default() Config {
"__GL_THREADED_OPTIMIZATIONS": "1",
},

Global: Binary{
ForcedGpu: "prime-discrete",
},
Player: Binary{
DiscordRPC: true,
Dxvk: true,
Expand All @@ -113,6 +117,19 @@ func Default() Config {
}
}

func (b *Binary) setup() error {
if !roblox.ValidRenderer(b.Renderer) {
return errors.New("invalid renderer given")
}

if err := b.pickCard(); err != nil {
return err
}

b.Env.Setenv()
return nil
jrelvas-ipc marked this conversation as resolved.
Show resolved Hide resolved
}

func (c *Config) setup() error {
if c.SanitizeEnv {
util.SanitizeEnv()
Expand All @@ -135,8 +152,12 @@ func (c *Config) setup() error {
log.Printf("Using Wine Root: %s", c.WineRoot)
}

if !roblox.ValidRenderer(c.Player.Renderer) || !roblox.ValidRenderer(c.Studio.Renderer) {
return fmt.Errorf("invalid renderer given to either player or studio")
if err := c.Player.setup(); err != nil {
return fmt.Errorf("player: %w", err)
}

if err := c.Studio.setup(); err != nil {
return fmt.Errorf("studio: %w", err)
}

c.Env.Setenv()
Expand Down
9 changes: 9 additions & 0 deletions internal/config/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ import (

type Environment map[string]string

// Set will only set the given environment key and value if it isn't already set
// within the Environment.
func (e *Environment) Set(key, value string) {
if _, ok := (*e)[key]; ok {
return
}
(*e)[key] = value
}

func (e *Environment) Setenv() {
for name, value := range *e {
os.Setenv(name, value)
Expand Down
Loading