summaryrefslogtreecommitdiff
path: root/components/vram.c
blob: d5e8a225289e306e64805f37ea89b6288b9a4b3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "../slstatus.h"
#include "../util.h"

// Function to run a command and capture its output
char* runCommand(const char* command) {
    char buffer[128];
    char* result = NULL;
    FILE* pipe = popen(command, "r");

    if (!pipe) {
        perror("popen");
        exit(1);
    }

    while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
        if (result == NULL) {
            result = strdup(buffer);
        } else {
            char* old_result = result;
            result = (char*)malloc(strlen(old_result) + strlen(buffer) + 1);
            strcpy(result, old_result);
            strcat(result, buffer);
            free(old_result);
        }
    }

    pclose(pipe);
    return result;
}

// Funtion to gather used VRAM information (MiB)
float GetUsedVRAM() {
    char* command_output;
    float vram_used = -1.0;

    // Check if an NVIDIA card is present
    command_output = runCommand("nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits"); // Returns MiB
    if (command_output != NULL) {
        sscanf(command_output, "%f", &vram_used);
        free(command_output);
    } else {
        // If no NVIDIA card is found, check for an AMD Radeon card
        // todo intel: "intel-gpu-top -b -s 1 -o - | grep 'used:'"
        command_output = runCommand("cat /sys/class/drm/card0/device/mem_info_vram_used"); // Returns Bytes
        if (command_output != NULL) {
            sscanf(command_output, "%f", &vram_used);
            vram_used = vram_used / 1024 / 1024; // Bytes --> MiB
            free(command_output);
        }
    }

    return vram_used;
}

// Funtion to gather total VRAM information (MiB)
float GetTotalVRAM() {
    char* command_output;
    float vram_total = -1.0;

    // Check if an NVIDIA card is present
    command_output = runCommand("nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits"); // Returns MiB
    if (command_output != NULL) {
        sscanf(command_output, "%f", &vram_total);
        free(command_output);
    } else {
        // If no NVIDIA card is found, check for an AMD Radeon card
        // todo intel: "intel-gpu-top -b -s 1 -o - | grep 'total:'"
        command_output = runCommand("cat /sys/class/drm/card0/device/mem_info_vram_total"); // Returns Bytes
        if (command_output != NULL) {
            sscanf(command_output, "%f", &vram_total);
            vram_total = vram_total / 1024 / 1024; // Bytes --> MiB
            free(command_output);
        }
    }

    return vram_total;
}

/// ACTUAL FUNCTIONS TO CALL IN CONFIG.H

const char *
vram_perc(const char *unused) {
    float vram_used = GetUsedVRAM();
    float vram_total = GetTotalVRAM();

    if (vram_used >= 0.0 && vram_total >= 0.0) {
        int vram_percentage = (int) vram_used / vram_total * 100;
        return bprintf("%d", vram_percentage);
    } else {
        return NULL;
    }
}

const char *
vram_used(const char *unused) {
    int vram_used = (int) GetUsedVRAM();

    if (vram_used >= 0.0) {
        return bprintf("%d MiB", vram_used);
    } else {
        return NULL;
    }
}

const char *
vram_total(const char *unused) {
    int vram_total = (int) GetTotalVRAM();

    if (vram_total >= 0.0) {
        return bprintf("%d MiB", vram_total);
    } else {
        return NULL;
    }
}