From 0faa3d8dd26e4049342e47e6c65fc169ea56d5f2 Mon Sep 17 00:00:00 2001 From: Daniel Tang Date: Thu, 6 Oct 2022 20:55:10 -0400 Subject: [PATCH 1/5] Add support for UVD and VCE status This add a bar for UVD and VCE. Tested on RX 460 (POLARIS). This was a difficult and tedious port of changes whose underlying code had changed extensively over the 5 intervening years. The original is at https://github.com/clbr/radeontop/pull/45 , but this port did not contact the author. Fixes #29. Tested on CARRIZO, STONEY and KAVERI. Added GTT memory usage details Co-authored-by: Chandu Babu Namburu --- amdgpu.c | 16 ++++++++++++++-- detect.c | 22 ++++++++++++++++++++++ include/radeontop.h | 7 +++++++ radeon.c | 16 ++++++++++++++-- ticks.c | 8 ++++++++ ui.c | 9 +++++++++ 6 files changed, 74 insertions(+), 4 deletions(-) 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..bea2492 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, 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 = (1U << 19); + bits.vce0 = (1U << 7); // R600 has a different texture bit, and only R600 has the TC, CR, SMX bits if (fam < RV770) { diff --git a/include/radeontop.h b/include/radeontop.h index d4c7aac..54ddcdf 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 = 0x14, 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..896198e 100644 --- a/ui.c +++ b/ui.c @@ -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.0 * (float) results->uvd / ticks; + float vce0 = 100.0 * (float) results->vce0 / ticks; 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,13 @@ void present(const unsigned int ticks, const char card[], unsigned int color, } if (color) attroff(COLOR_PAIR(5)); + percentage(start, w, uvd); + printright(start++, hw, _("UVD %6.2f%%"), uvd); + percentage(start, w, vce0); + printright(start++, hw, _("VCE %6.2f%%"), vce0); + + if(h > bigh) start++; + if (bits.vram || bits.gtt) { // Enough height? if (h > bigh) start++; From ccec6e2ef8165209f1e57585ac97fe213636c7f1 Mon Sep 17 00:00:00 2001 From: Daniel Tang Date: Fri, 7 Oct 2022 10:50:46 -0400 Subject: [PATCH 2/5] Fix UVDVCE mmap sizes --- detect.c | 2 +- include/radeontop.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/detect.c b/detect.c index bea2492..ea540b5 100644 --- a/detect.c +++ b/detect.c @@ -115,7 +115,7 @@ static void open_pci(struct pci_device *gpu_device) { static void cleanup_pci() { munmap((void *) area, MMAP_SIZE); - munmap((void *) srbm_area, MMAP_SIZE); + munmap((void *) srbm_area, SRBM_MMAP_SIZE); } static int init_drm(int drm_fd) { diff --git a/include/radeontop.h b/include/radeontop.h index 54ddcdf..888755b 100644 --- a/include/radeontop.h +++ b/include/radeontop.h @@ -39,7 +39,7 @@ enum { SRBM_STATUS = 0xe50, SRBM_STATUS2 = 0xe4c, MMAP_SIZE = 0x14, - SRBM_MMAP_SIZE = 0x14, + SRBM_MMAP_SIZE = 0xe54, VENDOR_AMD = 0x1002 }; From 37268ab30affdfb8c25189462c8ef5be78aecc18 Mon Sep 17 00:00:00 2001 From: Daniel Tang Date: Fri, 7 Oct 2022 10:53:51 -0400 Subject: [PATCH 3/5] Apply ui.c optimizations to UVDVCE --- ui.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui.c b/ui.c index 896198e..397debd 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,8 +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.0 * (float) results->uvd / ticks; - float vce0 = 100.0 * (float) results->vce0 / ticks; + 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; @@ -250,6 +250,7 @@ void present(const unsigned int ticks, const char card[], unsigned int color, percentage(start, w, vce0); printright(start++, hw, _("VCE %6.2f%%"), vce0); + // Enough height? if(h > bigh) start++; if (bits.vram || bits.gtt) { From 087b2817c8ddbe1c3d18ddfb1b4f1e782b915976 Mon Sep 17 00:00:00 2001 From: Daniel Tang Date: Fri, 7 Oct 2022 11:03:06 -0400 Subject: [PATCH 4/5] Dump UVDVCE --- dump.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dump.c b/dump.c index df41104..2876550 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,8 @@ 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); + fprintf(f, ", uvd %.2f%%", uvd); + fprintf(f, ", vce0 %.2f%%", vce0); if (bits.vram) fprintf(f, ", vram %.2f%% %.2fmb", vram, vrammb); From 258162fc41c7b019537e4e5dd16bf517a36dfa26 Mon Sep 17 00:00:00 2001 From: Daniel Tang Date: Fri, 7 Oct 2022 11:27:15 -0400 Subject: [PATCH 5/5] Check for UVDVCE support --- detect.c | 11 +++++++++-- dump.c | 6 ++++-- ui.c | 12 ++++++++---- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/detect.c b/detect.c index ea540b5..f9a1e84 100644 --- a/detect.c +++ b/detect.c @@ -359,8 +359,8 @@ void initbits(int fam) { bits.cr = (1U << 27); bits.cb = (1U << 30); bits.gui = (1U << 31); - bits.uvd = (1U << 19); - bits.vce0 = (1U << 7); + bits.uvd = 0; + bits.vce0 = 0; // R600 has a different texture bit, and only R600 has the TC, CR, SMX bits if (fam < RV770) { @@ -370,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 2876550..d43288d 100644 --- a/dump.c +++ b/dump.c @@ -129,8 +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); - fprintf(f, ", uvd %.2f%%", uvd); - fprintf(f, ", vce0 %.2f%%", vce0); + 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/ui.c b/ui.c index 397debd..9ae9746 100644 --- a/ui.c +++ b/ui.c @@ -245,10 +245,14 @@ void present(const unsigned int ticks, const char card[], unsigned int color, } if (color) attroff(COLOR_PAIR(5)); - percentage(start, w, uvd); - printright(start++, hw, _("UVD %6.2f%%"), uvd); - percentage(start, w, vce0); - printright(start++, hw, _("VCE %6.2f%%"), vce0); + 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++;