summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/util/u_cpu_detect.c24
-rw-r--r--src/gallium/auxiliary/util/u_cpu_detect.h1
2 files changed, 25 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/util/u_cpu_detect.c b/src/gallium/auxiliary/util/u_cpu_detect.c
index 29f4ce98203..751443f06f9 100644
--- a/src/gallium/auxiliary/util/u_cpu_detect.c
+++ b/src/gallium/auxiliary/util/u_cpu_detect.c
@@ -368,6 +368,28 @@ check_os_arm_support(void)
#endif /* PIPE_ARCH_ARM */
static void
+get_cpu_topology(void)
+{
+ uint32_t regs[4];
+
+ /* Default. This is correct if L3 is not present or there is only one. */
+ util_cpu_caps.cores_per_L3 = util_cpu_caps.nr_cpus;
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ /* AMD Zen */
+ if (util_cpu_caps.x86_cpu_type == 0x17) {
+ /* Query the L3 cache topology information. */
+ cpuid_count(0x8000001D, 3, regs);
+ unsigned cache_level = (regs[0] >> 5) & 0x7;
+ unsigned cores_per_cache = ((regs[0] >> 14) & 0xfff) + 1;
+
+ if (cache_level == 3)
+ util_cpu_caps.cores_per_L3 = cores_per_cache;
+ }
+#endif
+}
+
+static void
util_cpu_detect_once(void)
{
memset(&util_cpu_caps, 0, sizeof util_cpu_caps);
@@ -520,6 +542,8 @@ util_cpu_detect_once(void)
check_os_altivec_support();
#endif /* PIPE_ARCH_PPC */
+ get_cpu_topology();
+
#ifdef DEBUG
if (debug_get_option_dump_cpu()) {
debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus);
diff --git a/src/gallium/auxiliary/util/u_cpu_detect.h b/src/gallium/auxiliary/util/u_cpu_detect.h
index 19f5567ca7b..efc910d1473 100644
--- a/src/gallium/auxiliary/util/u_cpu_detect.h
+++ b/src/gallium/auxiliary/util/u_cpu_detect.h
@@ -51,6 +51,7 @@ struct util_cpu_caps {
/* Feature flags */
int x86_cpu_type;
unsigned cacheline;
+ unsigned cores_per_L3;
unsigned has_intel:1;
unsigned has_tsc:1;