diff --git a/amdgpu.c b/amdgpu.c index df2cb40..135b4e5 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -26,6 +26,16 @@ static int getgrbm_amdgpu(uint32_t *out) { 0xffffffff, 0, out); } +static int getsrbm_amdgpu(uint32_t *out) { + return amdgpu_read_mm_registers(amdgpu_dev, SRBM_STATUS / 4, 1, + 0xffffffff, 0, out); +} + +static int getsrbm2_amdgpu(uint32_t *out) { + return amdgpu_read_mm_registers(amdgpu_dev, SRBM_STATUS2 / 4, 1, + 0xffffffff, 0, out); +} + static int getvram_amdgpu(uint64_t *out) { return amdgpu_query_info(amdgpu_dev, AMDGPU_INFO_VRAM_USAGE, sizeof(uint64_t), out); @@ -59,9 +69,11 @@ void init_amdgpu(int fd) { if (amdgpu_device_initialize(fd, &drm_major, &drm_minor, &amdgpu_dev)) return; - if (!(ret = getgrbm_amdgpu(&out32))) + if (!(ret = getgrbm_amdgpu(&out32))) { getgrbm = getgrbm_amdgpu; - else + getsrbm = getsrbm_amdgpu; + getsrbm2 = getsrbm2_amdgpu; + } else drmError(ret, _("Failed to get GPU usage")); #ifdef HAS_AMDGPU_QUERY_SENSOR_INFO diff --git a/detect.c b/detect.c index 94eec65..f9a1e84 100644 --- a/detect.c +++ b/detect.c @@ -28,9 +28,12 @@ uint64_t gttsize; unsigned int sclk_max = 0; // kilohertz unsigned int mclk_max = 0; // kilohertz const void *area; +static const void *srbm_area; // function pointers to the right backend int (*getgrbm)(uint32_t *out); +int (*getsrbm)(uint32_t *out); +int (*getsrbm2)(uint32_t *out); int (*getvram)(uint64_t *out); int (*getgtt)(uint64_t *out); int (*getsclk)(uint32_t *out); @@ -75,6 +78,16 @@ static int getgrbm_pci(uint32_t *out) { return 0; } +static int getsrbm_pci(uint32_t *out) { + *out = *(uint32_t *)((const char *) srbm_area + SRBM_STATUS); + return 0; +} + +static int getsrbm2_pci(uint32_t *out) { + *out = *(uint32_t *)((const char *) srbm_area + SRBM_STATUS2); + return 0; +} + static void open_pci(struct pci_device *gpu_device) { // Warning: gpu_device is a copy of a freed struct. Do not access any pointers! int reg = 2; @@ -91,12 +104,18 @@ static void open_pci(struct pci_device *gpu_device) { area = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_PRIVATE, mem, gpu_device->regions[reg].base_addr + 0x8000); if (area == MAP_FAILED) die(_("mmap failed")); + srbm_area = mmap(NULL, SRBM_MMAP_SIZE, PROT_READ, MAP_PRIVATE, mem, + gpu_device->regions[reg].base_addr); + if (srbm_area == MAP_FAILED) die(_("mmap failed")); getgrbm = getgrbm_pci; + getsrbm = getsrbm_pci; + getsrbm2 = getsrbm2_pci; } static void cleanup_pci() { munmap((void *) area, MMAP_SIZE); + munmap((void *) srbm_area, SRBM_MMAP_SIZE); } static int init_drm(int drm_fd) { @@ -247,6 +266,7 @@ void init_pci(const char *path, short *bus, unsigned int *device_id, const unsig short device_bus = -1; int err = 1; getgrbm = getsclk = getmclk = getuint32_null; + getsrbm = getsrbm2 = getuint32_null; getvram = getgtt = getuint64_null; if (path) { @@ -339,6 +359,8 @@ void initbits(int fam) { bits.cr = (1U << 27); bits.cb = (1U << 30); bits.gui = (1U << 31); + bits.uvd = 0; + bits.vce0 = 0; // R600 has a different texture bit, and only R600 has the TC, CR, SMX bits if (fam < RV770) { @@ -348,4 +370,11 @@ void initbits(int fam) { bits.cr = 0; bits.smx = 0; } + + if (fam >= RV610 && fam < VEGAM) { + bits.uvd = (1U << 19); + if (fam >= CAYMAN) { + bits.vce0 = (1U << 7); + } + } } diff --git a/dump.c b/dump.c index df41104..d43288d 100644 --- a/dump.c +++ b/dump.c @@ -96,6 +96,8 @@ void dumpdata(const unsigned int ticks, const char file[], const unsigned int li float db = 100 * results->db * k; float cr = 100 * results->cr * k; float cb = 100 * results->cb * k; + float uvd = 100 * results->uvd * k; + float vce0 = 100 * results->vce0 * k; float vram = 100.0f * results->vram / vramsize; float vrammb = results->vram / 1024.0f / 1024.0f; float gtt = 100.0f * results->gtt / gttsize; @@ -127,6 +129,10 @@ void dumpdata(const unsigned int ticks, const char file[], const unsigned int li fprintf(f, "pa %.2f%%, ", pa); fprintf(f, "db %.2f%%, ", db); fprintf(f, "cb %.2f%%", cb); + if (bits.uvd) + fprintf(f, ", uvd %.2f%%", uvd); + if (bits.vce0) + fprintf(f, ", vce0 %.2f%%", vce0); if (bits.vram) fprintf(f, ", vram %.2f%% %.2fmb", vram, vrammb); diff --git a/include/radeontop.h b/include/radeontop.h index d4c7aac..888755b 100644 --- a/include/radeontop.h +++ b/include/radeontop.h @@ -36,7 +36,10 @@ enum { GRBM_STATUS = 0x8010, + SRBM_STATUS = 0xe50, + SRBM_STATUS2 = 0xe4c, MMAP_SIZE = 0x14, + SRBM_MMAP_SIZE = 0xe54, VENDOR_AMD = 0x1002 }; @@ -53,6 +56,8 @@ void initbits(int fam); void cleanup(); extern int (*getgrbm)(uint32_t *out); +extern int (*getsrbm)(uint32_t *out); +extern int (*getsrbm2)(uint32_t *out); extern int (*getvram)(uint64_t *out); extern int (*getgtt)(uint64_t *out); extern int (*getsclk)(uint32_t *out); @@ -151,6 +156,8 @@ struct bits_t { unsigned int db; unsigned int cb; unsigned int cr; + unsigned int uvd; + unsigned int vce0; uint64_t vram; uint64_t gtt; unsigned int sclk; diff --git a/radeon.c b/radeon.c index 3beaf8b..b89f891 100644 --- a/radeon.c +++ b/radeon.c @@ -50,6 +50,16 @@ static int getgrbm_radeon(uint32_t *out) { return radeon_get_drm_value(drm_fd, RADEON_INFO_READ_REG, out); } +static int getsrbm_radeon(uint32_t *out) { + *out = SRBM_STATUS; + return radeon_get_drm_value(drm_fd, RADEON_INFO_READ_REG, out); +} + +static int getsrbm2_radeon(uint32_t *out) { + *out = SRBM_STATUS2; + return radeon_get_drm_value(drm_fd, RADEON_INFO_READ_REG, out); +} + static int getsclk_radeon(uint32_t *out) { return radeon_get_drm_value(drm_fd, RADEON_INFO_CURRENT_GPU_SCLK, out); } @@ -83,9 +93,11 @@ void init_radeon(int fd, int drm_major, int drm_minor) { #ifdef RADEON_INFO_READ_REG if (DRM_ATLEAST_VERSION(2, 42)) { - if (!(ret = getgrbm_radeon(&out32))) + if (!(ret = getgrbm_radeon(&out32))) { getgrbm = getgrbm_radeon; - else + getsrbm = getsrbm_radeon; + getsrbm2 = getsrbm2_radeon; + } else drmError(ret, _("Failed to get GPU usage")); if ((ret = radeon_get_drm_value(drm_fd, RADEON_INFO_MAX_SCLK, diff --git a/ticks.c b/ticks.c index 4b965f3..612570b 100644 --- a/ticks.c +++ b/ticks.c @@ -41,6 +41,10 @@ static void *collector(void *arg) { while (1) { unsigned int stat; getgrbm(&stat); + unsigned int uvd; + getsrbm(&uvd); + unsigned int vce; + getsrbm2(&vce); memset(&history[cur], 0, sizeof(struct bits_t)); @@ -58,6 +62,8 @@ static void *collector(void *arg) { if (stat & bits.db) history[cur].db = 1; if (stat & bits.cr) history[cur].cr = 1; if (stat & bits.cb) history[cur].cb = 1; + if (uvd & bits.uvd) history[cur].uvd = 1; + if (vce & bits.vce0) history[cur].vce0 = 1; getsclk(&history[cur].sclk); getmclk(&history[cur].mclk); @@ -86,6 +92,8 @@ static void *collector(void *arg) { res[curres].db += history[i].db; res[curres].cb += history[i].cb; res[curres].cr += history[i].cr; + res[curres].uvd += history[i].uvd; + res[curres].vce0 += history[i].vce0; res[curres].mclk += history[i].mclk; res[curres].sclk += history[i].sclk; } diff --git a/ui.c b/ui.c index dcbfeef..9ae9746 100644 --- a/ui.c +++ b/ui.c @@ -109,7 +109,7 @@ void present(const unsigned int ticks, const char card[], unsigned int color, init_pair(5, COLOR_YELLOW, COLOR_BLACK); } - const unsigned int bigh = 23; + const unsigned int bigh = 26; // Screen dimensions. (Re)calculated only when resize is non-zero. unsigned int h = 1, w = 1, hw = 1; @@ -150,6 +150,8 @@ void present(const unsigned int ticks, const char card[], unsigned int color, float db = 100 * results->db * k; float cr = 100 * results->cr * k; float cb = 100 * results->cb * k; + float uvd = 100 * results->uvd * k; + float vce0 = 100 * results->vce0 * k; float vram = 100.0f * results->vram / vramsize; float vrammb = results->vram / 1024.0f / 1024.0f; float vramsizemb = vramsize / 1024.0f / 1024.0f; @@ -243,6 +245,18 @@ void present(const unsigned int ticks, const char card[], unsigned int color, } if (color) attroff(COLOR_PAIR(5)); + if (bits.uvd) { + percentage(start, w, uvd); + printright(start++, hw, _("UVD %6.2f%%"), uvd); + } + if (bits.vce0) { + percentage(start, w, vce0); + printright(start++, hw, _("VCE %6.2f%%"), vce0); + } + + // Enough height? + if(h > bigh) start++; + if (bits.vram || bits.gtt) { // Enough height? if (h > bigh) start++;