mirror of
https://github.com/outbackdingo/OpCore-Simplify.git
synced 2026-01-27 10:19:49 +00:00
Improve GPU compatibility handling and kext selection
This commit is contained in:
@@ -57,11 +57,9 @@ class HardwareCustomizer:
|
||||
print("Type Device Device ID")
|
||||
print("------------------------------------------------------------------")
|
||||
for device_type, device_dict in self.selected_devices.items():
|
||||
device_name = list(device_dict.keys())[0]
|
||||
device_props = list(device_dict.values())[0]
|
||||
device_id = device_props.get("Device ID", "Unknown")
|
||||
|
||||
print("{:<13} {:<42} {}".format(device_type, device_name[:38], device_id))
|
||||
for device_name, device_props in device_dict.items():
|
||||
device_id = device_props.get("Device ID", "Unknown")
|
||||
print("{:<13} {:<42} {}".format(device_type, device_name[:38], device_id))
|
||||
print("")
|
||||
print("All other devices of the same type have been disabled.")
|
||||
print("")
|
||||
@@ -69,36 +67,81 @@ class HardwareCustomizer:
|
||||
|
||||
return self.customized_hardware, self.disabled_devices, needs_oclp
|
||||
|
||||
def _get_device_combinations(self, device_indices):
|
||||
devices = sorted(list(device_indices))
|
||||
n = len(devices)
|
||||
all_combinations = []
|
||||
|
||||
if n == 0:
|
||||
return []
|
||||
|
||||
for i in range(1, 1 << n):
|
||||
current_combination = []
|
||||
for j in range(n):
|
||||
if (i >> j) & 1:
|
||||
current_combination.append(devices[j])
|
||||
|
||||
if 1 <= len(current_combination) <= n:
|
||||
all_combinations.append(current_combination)
|
||||
|
||||
all_combinations.sort(key=lambda combo: (len(combo), combo))
|
||||
|
||||
return all_combinations
|
||||
|
||||
def _handle_device_selection(self, device_type):
|
||||
devices = self._get_compatible_devices(device_type)
|
||||
device_groups = None
|
||||
|
||||
if len(devices) > 1:
|
||||
print("\n*** Multiple {} Devices Detected".format(device_type))
|
||||
if device_type == "WiFi" or device_type == "Bluetooth":
|
||||
print(f"macOS works best with only one {device_type} device enabled.")
|
||||
elif device_type == "GPU":
|
||||
_has_multiple_compatible_devices = False
|
||||
_apu_index = None
|
||||
_navi_22_indices = set()
|
||||
_navi_indices = set()
|
||||
_intel_gpu_indices = set()
|
||||
_other_indices = set()
|
||||
|
||||
for gpu_name, gpu_props in devices.items():
|
||||
for index, (gpu_name, gpu_props) in enumerate(devices.items()):
|
||||
gpu_manufacturer = gpu_props.get("Manufacturer")
|
||||
gpu_codename = gpu_props.get("Codename")
|
||||
gpu_type = gpu_props.get("Device Type")
|
||||
|
||||
if gpu_manufacturer == "AMD":
|
||||
if gpu_props.get("Device Type") == "Integrated GPU":
|
||||
_has_multiple_compatible_devices = True
|
||||
elif gpu_props.get("Device Type") == "Discrete GPU" and gpu_codename == "Navi 22":
|
||||
_has_multiple_compatible_devices = True
|
||||
if gpu_type == "Integrated GPU":
|
||||
_apu_index = index
|
||||
continue
|
||||
elif gpu_type == "Discrete GPU":
|
||||
if gpu_codename.startswith("Navi"):
|
||||
_navi_indices.add(index)
|
||||
if gpu_codename == "Navi 22":
|
||||
_navi_22_indices.add(index)
|
||||
continue
|
||||
elif gpu_manufacturer == "Intel":
|
||||
_intel_gpu_indices.add(index)
|
||||
continue
|
||||
|
||||
if _has_multiple_compatible_devices:
|
||||
_other_indices.add(index)
|
||||
|
||||
if _apu_index or _navi_22_indices:
|
||||
print("Multiple active GPUs can cause kext conflicts in macOS.")
|
||||
print("It's recommended to use only one GPU at a time.")
|
||||
else:
|
||||
return
|
||||
|
||||
selected_device = self._select_device(device_type, devices)
|
||||
if selected_device:
|
||||
self.selected_devices[device_type] = {
|
||||
selected_device: devices[selected_device]
|
||||
}
|
||||
device_groups = []
|
||||
if _apu_index:
|
||||
device_groups.append({_apu_index} | _other_indices)
|
||||
if _navi_22_indices:
|
||||
device_groups.append(_navi_22_indices | _other_indices)
|
||||
if _navi_indices or _intel_gpu_indices or _other_indices:
|
||||
device_groups.append(_navi_indices | _intel_gpu_indices | _other_indices)
|
||||
|
||||
selected_devices = self._select_device(device_type, devices, device_groups)
|
||||
if selected_devices:
|
||||
for selected_device in selected_devices:
|
||||
if not device_type in self.selected_devices:
|
||||
self.selected_devices[device_type] = {}
|
||||
|
||||
self.selected_devices[device_type][selected_device] = devices[selected_device]
|
||||
|
||||
def _get_compatible_devices(self, device_type):
|
||||
compatible_devices = {}
|
||||
@@ -119,43 +162,112 @@ class HardwareCustomizer:
|
||||
|
||||
return compatible_devices
|
||||
|
||||
def _select_device(self, device_type, devices):
|
||||
def _select_device(self, device_type, devices, device_groups=None):
|
||||
print("")
|
||||
print("Please select which {} device you want to use:".format(device_type))
|
||||
if device_groups:
|
||||
print("Please select a {} combination configuration:".format(device_type))
|
||||
else:
|
||||
print("Please select which {} device you want to use:".format(device_type))
|
||||
print("")
|
||||
|
||||
for index, device_name in enumerate(devices, start=1):
|
||||
device_props = devices[device_name]
|
||||
compatibility = device_props.get("Compatibility")
|
||||
|
||||
print("{}. {}".format(index, device_name))
|
||||
print(" Device ID: {}".format(device_props.get("Device ID", "Unknown")))
|
||||
print(" Compatibility: {}".format(self.compatibility_checker.show_macos_compatibility(compatibility)))
|
||||
|
||||
if device_props.get("OCLP Compatibility"):
|
||||
oclp_compatibility = device_props.get("OCLP Compatibility")
|
||||
if device_groups:
|
||||
valid_combinations = []
|
||||
|
||||
if self.utils.parse_darwin_version(oclp_compatibility[0]) > self.utils.parse_darwin_version(compatibility[0]):
|
||||
print(" OCLP Compatibility: {}".format(self.compatibility_checker.show_macos_compatibility((oclp_compatibility[0], os_data.get_lowest_darwin_version()))))
|
||||
print()
|
||||
|
||||
while True:
|
||||
choice = self.utils.request_input(f"Select a {device_type} device (1-{len(devices)}): ")
|
||||
for group in device_groups:
|
||||
device_combinations = self._get_device_combinations(group)
|
||||
for device_combination in device_combinations:
|
||||
group_devices = []
|
||||
group_compatibility = None
|
||||
group_indices = set()
|
||||
has_oclp_required = False
|
||||
|
||||
for index in device_combination:
|
||||
device_name = list(devices.keys())[index]
|
||||
device_props = devices[device_name]
|
||||
group_devices.append(device_name)
|
||||
group_indices.add(index)
|
||||
compatibility = device_props.get("Compatibility")
|
||||
if compatibility:
|
||||
if group_compatibility is None:
|
||||
group_compatibility = compatibility
|
||||
else:
|
||||
if self.utils.parse_darwin_version(compatibility[0]) < self.utils.parse_darwin_version(group_compatibility[0]):
|
||||
group_compatibility = (compatibility[0], group_compatibility[1])
|
||||
if self.utils.parse_darwin_version(compatibility[1]) > self.utils.parse_darwin_version(group_compatibility[1]):
|
||||
group_compatibility = (group_compatibility[0], compatibility[1])
|
||||
|
||||
if device_props.get("OCLP Compatibility"):
|
||||
has_oclp_required = True
|
||||
|
||||
if has_oclp_required and len(device_combination) > 1:
|
||||
continue
|
||||
|
||||
if group_devices and (group_devices, group_indices, group_compatibility) not in valid_combinations:
|
||||
valid_combinations.append((group_devices, group_indices, group_compatibility))
|
||||
|
||||
valid_combinations.sort(key=lambda x: (len(x[0]), x[2][0]))
|
||||
|
||||
try:
|
||||
choice_num = int(choice)
|
||||
if 1 <= choice_num <= len(devices):
|
||||
selected_device = list(devices)[choice_num - 1]
|
||||
|
||||
for device in devices:
|
||||
if device != selected_device:
|
||||
self._disable_device(device_type, device, devices[device])
|
||||
|
||||
return selected_device
|
||||
else:
|
||||
print("Invalid option. Please try again.")
|
||||
except:
|
||||
print("Please enter a number.")
|
||||
for idx, (group_devices, _, group_compatibility) in enumerate(valid_combinations, start=1):
|
||||
print("{}. {}".format(idx, " + ".join(group_devices)))
|
||||
if group_compatibility:
|
||||
print(" Compatibility: {}".format(self.compatibility_checker.show_macos_compatibility(group_compatibility)))
|
||||
if len(group_devices) == 1:
|
||||
device_props = devices[group_devices[0]]
|
||||
if device_props.get("OCLP Compatibility"):
|
||||
oclp_compatibility = device_props.get("OCLP Compatibility")
|
||||
if self.utils.parse_darwin_version(oclp_compatibility[0]) > self.utils.parse_darwin_version(group_compatibility[0]):
|
||||
print(" OCLP Compatibility: {}".format(self.compatibility_checker.show_macos_compatibility((oclp_compatibility[0], os_data.get_lowest_darwin_version()))))
|
||||
print("")
|
||||
|
||||
while True:
|
||||
choice = self.utils.request_input(f"Select a {device_type} combination (1-{len(valid_combinations)}): ")
|
||||
|
||||
try:
|
||||
choice_num = int(choice)
|
||||
if 1 <= choice_num <= len(valid_combinations):
|
||||
selected_devices, _, _ = valid_combinations[choice_num - 1]
|
||||
|
||||
for device in devices:
|
||||
if device not in selected_devices:
|
||||
self._disable_device(device_type, device, devices[device])
|
||||
|
||||
return selected_devices
|
||||
else:
|
||||
print("Invalid option. Please try again.")
|
||||
except ValueError:
|
||||
print("Please enter a valid number.")
|
||||
else:
|
||||
for index, device_name in enumerate(devices, start=1):
|
||||
device_props = devices[device_name]
|
||||
compatibility = device_props.get("Compatibility")
|
||||
|
||||
print("{}. {}".format(index, device_name))
|
||||
print(" Device ID: {}".format(device_props.get("Device ID", "Unknown")))
|
||||
print(" Compatibility: {}".format(self.compatibility_checker.show_macos_compatibility(compatibility)))
|
||||
|
||||
if device_props.get("OCLP Compatibility"):
|
||||
oclp_compatibility = device_props.get("OCLP Compatibility")
|
||||
if self.utils.parse_darwin_version(oclp_compatibility[0]) > self.utils.parse_darwin_version(compatibility[0]):
|
||||
print(" OCLP Compatibility: {}".format(self.compatibility_checker.show_macos_compatibility((oclp_compatibility[0], os_data.get_lowest_darwin_version()))))
|
||||
print()
|
||||
|
||||
while True:
|
||||
choice = self.utils.request_input(f"Select a {device_type} device (1-{len(devices)}): ")
|
||||
|
||||
try:
|
||||
choice_num = int(choice)
|
||||
if 1 <= choice_num <= len(devices):
|
||||
selected_device = list(devices)[choice_num - 1]
|
||||
|
||||
for device in devices:
|
||||
if device != selected_device:
|
||||
self._disable_device(device_type, device, devices[device])
|
||||
|
||||
return [selected_device]
|
||||
else:
|
||||
print("Invalid option. Please try again.")
|
||||
except ValueError:
|
||||
print("Please enter a valid number.")
|
||||
|
||||
def _disable_device(self, device_type, device_name, device_props):
|
||||
if device_type == "WiFi":
|
||||
|
||||
@@ -136,12 +136,56 @@ class KextMaestro:
|
||||
int(hardware_report.get("CPU").get("Core Count")) > 6:
|
||||
selected_kexts.append("CpuTopologyRebuild")
|
||||
|
||||
if "AMD" in hardware_report.get("CPU").get("Manufacturer") and \
|
||||
"Integrated GPU" in list(hardware_report.get("GPU").items())[0][-1].get("Device Type") and \
|
||||
"Integrated GPU" in list(hardware_report.get("GPU").items())[-1][-1].get("Device Type"):
|
||||
selected_kexts.append("NootedRed")
|
||||
else:
|
||||
selected_kexts.append("NootRX" if "Navi 22" in list(hardware_report.get("GPU").items())[0][-1].get("Codename") else "WhateverGreen")
|
||||
for gpu_name, gpu_props in hardware_report.get("GPU", {}).items():
|
||||
if "Integrated GPU" in gpu_props.get("Device Type"):
|
||||
if "AMD" in gpu_props.get("Manufacturer"):
|
||||
selected_kexts.append("NootedRed")
|
||||
else:
|
||||
if "Navi 22" in gpu_props.get("Codename"):
|
||||
selected_kexts.append("NootRX")
|
||||
elif gpu_props.get("Codename") in {"Navi 21", "Navi 23"}:
|
||||
print("\n*** Found {} is AMD {} GPU.".format(gpu_name, gpu_props.get("Codename")))
|
||||
print("")
|
||||
print("\033[91mImportant: Black Screen Fix\033[0m")
|
||||
print("If you experience a black screen after verbose mode:")
|
||||
print(" 1. Use ProperTree to open config.plist")
|
||||
print(" 2. Navigate to NVRAM -> Add -> 7C436110-AB2A-4BBB-A880-FE41995C9F82 -> boot-args")
|
||||
print(" 3. Remove \"-v debug=0x100 keepsyms=1\" from boot-args")
|
||||
print("")
|
||||
print("\033[93mNote:\033[0m - AMD {} GPUs have two available kext options:".format(gpu_props.get("Codename")))
|
||||
print(" - You can try different kexts after installation to find the best one for your system")
|
||||
print("")
|
||||
print("1. \033[1mNootRX\033[0m - Uses latest GPU firmware")
|
||||
print("2. \033[1mWhateverGreen\033[0m - Uses original Apple firmware")
|
||||
print("")
|
||||
|
||||
if any(other_gpu_props.get("Manufacturer") == "Intel" for other_gpu_props in hardware_report.get("GPU", {}).values()):
|
||||
print("\033[91mImportant:\033[0m - NootRX kext is not compatible with Intel GPUs")
|
||||
print(" - Automatically selecting WhateverGreen kext due to Intel GPU compatibility")
|
||||
print("")
|
||||
self.utils.request_input("Press Enter to continue...")
|
||||
continue
|
||||
|
||||
recommended_option = 2
|
||||
recommended_name = "WhateverGreen"
|
||||
|
||||
kext_option = self.utils.request_input("Select kext for your AMD {} GPU (default: {}): ".format(gpu_props.get("Codename"), recommended_name)).strip() or str(recommended_option)
|
||||
|
||||
if kext_option.isdigit() and 0 < int(kext_option) < 3:
|
||||
selected_option = int(kext_option)
|
||||
else:
|
||||
print("\033[91mInvalid selection, using recommended option: {}\033[0m".format(recommended_option))
|
||||
selected_option = recommended_option
|
||||
|
||||
if selected_option == 2:
|
||||
selected_kexts.append("WhateverGreen")
|
||||
else:
|
||||
selected_kexts.append("NootRX")
|
||||
elif gpu_props.get("Codename").startswith("Navi 1"):
|
||||
selected_kexts.append("WhateverGreen")
|
||||
|
||||
if not "NootedRed" in selected_kexts and not "NootRX" in selected_kexts and not "WhateverGreen" in selected_kexts:
|
||||
selected_kexts.append("WhateverGreen")
|
||||
|
||||
if "Laptop" in hardware_report.get("Motherboard").get("Platform") and ("ASUS" in hardware_report.get("Motherboard").get("Name") or "NootedRed" in selected_kexts):
|
||||
selected_kexts.append("ForgedInvariant")
|
||||
|
||||
Reference in New Issue
Block a user