Add GPU_FOREIGN_UTIL_PCT: game detection via per-process GPU 3D-engine usage
Reads the same PDH counters as Task Manager (\GPU Engine(*)\Utilization Percentage, locale-independent via PdhAddEnglishCounterW), which cover graphics work under WDDM — games are caught without an exe list and the offender is named. Windows-only; a missing or failing counter disables the path with one log line. dwm (the desktop compositor) joins the default ignore list.
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// errNotPrimed marks the first PDH sample after opening a query: rate-based
|
||||
// counters (like engine utilization) need two collections before they
|
||||
// return meaningful values.
|
||||
var errNotPrimed = errors.New("GPU engine counter needs a second sample")
|
||||
|
||||
// parseGPUEngineInstance splits a PDH "GPU Engine" instance name —
|
||||
// "pid_1234_luid_0x00000000_0x00011A2B_phys_0_eng_0_engtype_3D" — into PID
|
||||
// and engine type ("3D", "Copy", "VideoDecode", ...). engType is empty when
|
||||
// the name carries no engtype marker.
|
||||
func parseGPUEngineInstance(name string) (pid int, engType string, ok bool) {
|
||||
rest, found := strings.CutPrefix(name, "pid_")
|
||||
if !found {
|
||||
return 0, "", false
|
||||
}
|
||||
digits, rest, found := strings.Cut(rest, "_")
|
||||
if !found {
|
||||
return 0, "", false
|
||||
}
|
||||
pid, err := strconv.Atoi(digits)
|
||||
if err != nil || pid < 0 {
|
||||
return 0, "", false
|
||||
}
|
||||
const marker = "engtype_"
|
||||
if i := strings.LastIndex(rest, marker); i >= 0 {
|
||||
engType = rest[i+len(marker):]
|
||||
}
|
||||
return pid, engType, true
|
||||
}
|
||||
Reference in New Issue
Block a user