From 18437c7a65a909044add3cb78c1e291bbf871743 Mon Sep 17 00:00:00 2001 From: Dhruv Mark Collins Date: Thu, 9 Apr 2026 13:19:42 +0000 Subject: [PATCH] tu: Disable features using performance counter for KGSL KGSL doesn't support reading of performance counters by writing to the selector registers directly from a userspace CS, instead these requests need to be routed via the KGSL uAPI for perf counters. Certain Turnip features which use performance counters such as KHR_performance_query as well as preempt-optimize mode in autotune are now explicitly disabled to reflect this. Signed-off-by: Dhruv Mark Collins Part-of: --- src/freedreno/vulkan/tu_autotune.cc | 3 ++- src/freedreno/vulkan/tu_device.cc | 2 +- src/freedreno/vulkan/tu_device.h | 3 +++ src/freedreno/vulkan/tu_knl_drm_msm.cc | 2 ++ src/freedreno/vulkan/tu_knl_drm_virtio.cc | 1 + src/freedreno/vulkan/tu_knl_kgsl.cc | 3 +++ 6 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/freedreno/vulkan/tu_autotune.cc b/src/freedreno/vulkan/tu_autotune.cc index 9943721f992..d1c3af11210 100644 --- a/src/freedreno/vulkan/tu_autotune.cc +++ b/src/freedreno/vulkan/tu_autotune.cc @@ -336,7 +336,8 @@ uint32_t tu_autotune::get_supported_mod_flags(tu_device *device) const { uint32_t supported_mod_flags = (uint32_t) mod_flag::BIG_GMEM | (uint32_t) mod_flag::TUNE_SMALL; - if (device->physical_device->info->props.max_draw_states > TU_DRAW_STATE_AT_WRITE_RP_HASH) { + if (device->physical_device->info->props.max_draw_states > TU_DRAW_STATE_AT_WRITE_RP_HASH && + device->physical_device->is_perf_cntr_selectable) { supported_mod_flags |= (uint32_t) mod_flag::PREEMPT_OPTIMIZE; } return supported_mod_flags; diff --git a/src/freedreno/vulkan/tu_device.cc b/src/freedreno/vulkan/tu_device.cc index aab6d3d944a..e42af3e4379 100644 --- a/src/freedreno/vulkan/tu_device.cc +++ b/src/freedreno/vulkan/tu_device.cc @@ -216,7 +216,7 @@ get_device_extensions(const struct tu_physical_device *device, .KHR_maintenance8 = tu_is_vk_1_1(device), .KHR_map_memory2 = true, .KHR_multiview = tu_has_multiview(device), - .KHR_performance_query = TU_DEBUG(PERFC) || TU_DEBUG(PERFCRAW), + .KHR_performance_query = (TU_DEBUG(PERFC) || TU_DEBUG(PERFCRAW)) && device->is_perf_cntr_selectable, .KHR_pipeline_executable_properties = true, .KHR_pipeline_library = true, #ifdef TU_USE_WSI_PLATFORM diff --git a/src/freedreno/vulkan/tu_device.h b/src/freedreno/vulkan/tu_device.h index 400d81c18f0..204eae9511c 100644 --- a/src/freedreno/vulkan/tu_device.h +++ b/src/freedreno/vulkan/tu_device.h @@ -142,6 +142,9 @@ struct tu_physical_device bool has_preemption; + /* Whether performance counter selector registers can be written by userspace CSes. */ + bool is_perf_cntr_selectable; + struct { uint32_t non_lazy_type_count; uint32_t type_count; diff --git a/src/freedreno/vulkan/tu_knl_drm_msm.cc b/src/freedreno/vulkan/tu_knl_drm_msm.cc index 8695981b6b1..d6f6d6d4fba 100644 --- a/src/freedreno/vulkan/tu_knl_drm_msm.cc +++ b/src/freedreno/vulkan/tu_knl_drm_msm.cc @@ -1668,6 +1668,8 @@ tu_knl_drm_msm_load(struct tu_instance *instance, device->has_preemption = tu_drm_has_preemption(device); + device->is_perf_cntr_selectable = true; + /* Even if kernel is new enough, the GPU itself may not support it. */ device->has_cached_coherent_memory = (device->msm_minor_version >= 8) && diff --git a/src/freedreno/vulkan/tu_knl_drm_virtio.cc b/src/freedreno/vulkan/tu_knl_drm_virtio.cc index ce357d3569e..6040850b2a2 100644 --- a/src/freedreno/vulkan/tu_knl_drm_virtio.cc +++ b/src/freedreno/vulkan/tu_knl_drm_virtio.cc @@ -1339,6 +1339,7 @@ tu_knl_drm_virtio_load(struct tu_instance *instance, device->has_set_iova = true; device->has_lazy_bos = true; device->has_preemption = has_preemption; + device->is_perf_cntr_selectable = true; device->uche_trap_base = uche_trap_base; device->ubwc_config.bank_swizzle_levels = bank_swizzle_levels; diff --git a/src/freedreno/vulkan/tu_knl_kgsl.cc b/src/freedreno/vulkan/tu_knl_kgsl.cc index 0f689efd269..594f736e674 100644 --- a/src/freedreno/vulkan/tu_knl_kgsl.cc +++ b/src/freedreno/vulkan/tu_knl_kgsl.cc @@ -1870,6 +1870,9 @@ tu_knl_kgsl_load(struct tu_instance *instance, int fd) /* preemption is always supported on kgsl */ device->has_preemption = true; + /* KGSL doesn't allow writing the perf counter selector as the expectation is to use the uAPI provided for this. */ + device->is_perf_cntr_selectable = false; + device->ubwc_config.highest_bank_bit = highest_bank_bit; /* The other config values can be partially inferred from the UBWC version,