diff --git a/src/intel/dev/intel_device_info.c b/src/intel/dev/intel_device_info.c index a54f52e5494..ae4f8117fd8 100644 --- a/src/intel/dev/intel_device_info.c +++ b/src/intel/dev/intel_device_info.c @@ -1333,6 +1333,69 @@ intel_device_info_update_cs_workgroup_threads(struct intel_device_info *devinfo) MIN2(devinfo->max_cs_threads, 64); } +static bool +parse_force_probe_entry(int pci_id, const char *entry, bool *force_on, + bool *force_off) +{ + const char *cp = entry; + + bool negated = *cp == '!'; + if (negated) + cp++; + + if (*cp == '\0') + return false; + + bool wildcard = *cp == '*'; + long val = 0; + + if (wildcard) { + cp++; + } else { + char *end; + val = strtol(cp, &end, 16); + if (end == cp) + return false; + cp = end; + } + + if (*cp != '\0') + return false; + + bool matched = wildcard || (long)pci_id == val; + if (matched) { + *force_on = !negated; + *force_off = negated; + } + + return matched; +} + +static void +scan_for_force_probe(int pci_id, bool *force_on, bool *force_off) +{ + *force_on = false; + *force_off = false; + + const char *env = getenv("INTEL_FORCE_PROBE"); + if (env == NULL) + return; + + size_t len = strlen(env); + if (len == 0) + return; + + char *dup = strndup(env, len); + if (dup == NULL) + return; + + for (char *entry = strtok(dup, ","); entry; entry = strtok(NULL, ",")) + parse_force_probe_entry(pci_id, entry, force_on, force_off); + + free(dup); + assert(!*force_on || !*force_off); +} + struct device_init_config { bool require_force_probe; }; @@ -1383,8 +1446,23 @@ intel_device_info_init_common(int pci_id, strncpy(devinfo->name, "Intel Unknown", sizeof(devinfo->name)); } - if (device_config.require_force_probe) + bool force_on = false; + bool force_off = false; + scan_for_force_probe(pci_id, &force_on, &force_off); + if (force_off) { + mesa_logw("%s (0x%x) disabled with INTEL_FORCE_PROBE", devinfo->name, + pci_id); return false; + } else if (device_config.require_force_probe) { + if (force_on) { + mesa_logw("Forcing probe of unsupported: %s (0x%x)", devinfo->name, + pci_id); + } else { + mesa_loge("%s (0x%x) requires INTEL_FORCE_PROBE", devinfo->name, + pci_id); + return false; + } + } devinfo->pci_device_id = pci_id; diff --git a/src/intel/dev/intel_device_info_test.c b/src/intel/dev/intel_device_info_test.c index 796a3985d3c..eaa514dfd68 100644 --- a/src/intel/dev/intel_device_info_test.c +++ b/src/intel/dev/intel_device_info_test.c @@ -1,6 +1,7 @@ #undef NDEBUG #include +#include #include #include "intel_device_info.h" @@ -21,7 +22,12 @@ main(int argc, char *argv[]) for (uint32_t i = 0; i < ARRAY_SIZE(chipsets); i++) { struct intel_device_info devinfo = { 0, }; + char force_probe[10]; + int len = snprintf(force_probe, sizeof force_probe, "%x", + chipsets[i].pci_id); + assert(len < sizeof force_probe); + setenv("INTEL_FORCE_PROBE", force_probe, 1); assert(intel_get_device_info_from_pci_id(chipsets[i].pci_id, &devinfo)); verify_device_info(&devinfo);