diff --git a/src/common/emulatorConfig.cpp b/src/common/emulatorConfig.cpp
index 5f88cd587..4ef94bbc0 100644
--- a/src/common/emulatorConfig.cpp
+++ b/src/common/emulatorConfig.cpp
@@ -63,6 +63,10 @@ bool VrEnabled() {
return g_config->vr_enabled;
}
+bool AmdCpuEnabled() {
+ return g_config->amd_cpu_enabled;
+}
+
uint32_t GetVblankFrequency() {
return std::clamp(g_config->vblank_frequency, 30u, 360u);
}
diff --git a/src/common/emulatorConfig.h b/src/common/emulatorConfig.h
index 924733fbe..9b5e66cf6 100644
--- a/src/common/emulatorConfig.h
+++ b/src/common/emulatorConfig.h
@@ -48,6 +48,7 @@ struct ConfigOptions {
int32_t gpu_index = -1;
bool fullscreen_enabled = false;
bool vr_enabled = false;
+ bool amd_cpu_enabled = false;
uint32_t vblank_frequency = 60;
uint32_t console_language = DEFAULT_CONSOLE_LANGUAGE;
bool vulkan_validation_enabled = false;
@@ -83,6 +84,7 @@ PresentMode GetPresentMode();
int32_t GetGpuIndex();
bool FullscreenEnabled();
bool VrEnabled();
+bool AmdCpuEnabled();
uint32_t GetVblankFrequency();
uint32_t GetConsoleLanguage();
bool VulkanValidationEnabled();
diff --git a/src/launcher/forms/configuration_edit_dialog.ui b/src/launcher/forms/configuration_edit_dialog.ui
index bfd2109fe..e3f3ecb46 100644
--- a/src/launcher/forms/configuration_edit_dialog.ui
+++ b/src/launcher/forms/configuration_edit_dialog.ui
@@ -271,21 +271,19 @@
Compatibility
-
+
+ -
+
+ Patch CPU instructions that differ between AMD and the host CPU.
+ AMD CPU patch (EXPERIMENTAL)
+
+
-
Helps prevent crashes in some games on Windows
Windows SysV red zone crash protection (Experimental)
- -
-
- Qt::Horizontal
-
- 4020
-
-
-
diff --git a/src/launcher/include/configuration.h b/src/launcher/include/configuration.h
index 36111bcb0..bbeb79244 100644
--- a/src/launcher/include/configuration.h
+++ b/src/launcher/include/configuration.h
@@ -105,6 +105,7 @@ public:
QString printf_output_file = "_kyty.txt";
bool profiler_enabled = false;
bool renderdoc_enabled = false;
+ bool amd_cpu_enabled = false;
#if defined(_WIN32)
bool red_zone_protection_enabled = false;
#endif
@@ -134,6 +135,7 @@ public:
printf_output_file = other.printf_output_file;
profiler_enabled = other.profiler_enabled;
renderdoc_enabled = other.renderdoc_enabled;
+ amd_cpu_enabled = other.amd_cpu_enabled;
#if defined(_WIN32)
red_zone_protection_enabled = other.red_zone_protection_enabled;
#endif
@@ -180,6 +182,7 @@ public:
KYTY_CFG_SET(printf_output_file);
KYTY_CFG_SET(profiler_enabled);
KYTY_CFG_SET(renderdoc_enabled);
+ KYTY_CFG_SET(amd_cpu_enabled);
#if defined(_WIN32)
KYTY_CFG_SET(red_zone_protection_enabled);
#endif
@@ -223,6 +226,7 @@ public:
KYTY_CFG_GET(printf_output_file);
KYTY_CFG_GET(profiler_enabled);
KYTY_CFG_GET(renderdoc_enabled);
+ amd_cpu_enabled = s->value("amd_cpu_enabled", false).toBool();
#if defined(_WIN32)
red_zone_protection_enabled =
s->value("red_zone_protection_enabled", red_zone_protection_enabled).toBool();
diff --git a/src/launcher/src/configurationEditDialog.cpp b/src/launcher/src/configurationEditDialog.cpp
index a0250aa34..3e63778e0 100644
--- a/src/launcher/src/configurationEditDialog.cpp
+++ b/src/launcher/src/configurationEditDialog.cpp
@@ -239,6 +239,10 @@ void ConfigurationEditDialog::Init(const Configuration& info) {
m_ui->checkBox_shader_validation->setChecked(info.shader_validation_enabled);
m_ui->checkBox_vulkan_validation->setChecked(info.vulkan_validation_enabled);
m_ui->checkBox_renderdoc_capture->setChecked(info.renderdoc_enabled);
+ m_ui->checkBox_amd_cpu->setChecked(info.amd_cpu_enabled);
+#if !defined(__linux__)
+ m_ui->checkBox_amd_cpu->setVisible(false);
+#endif
#if defined(_WIN32)
m_ui->checkBox_red_zone_protection->setChecked(info.red_zone_protection_enabled);
#else
@@ -379,6 +383,7 @@ static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui) {
info.vulkan_validation_enabled = ui.checkBox_vulkan_validation->isChecked();
info.shader_validation_enabled = ui.checkBox_shader_validation->isChecked();
info.renderdoc_enabled = ui.checkBox_renderdoc_capture->isChecked();
+ info.amd_cpu_enabled = ui.checkBox_amd_cpu->isChecked();
#if defined(_WIN32)
info.red_zone_protection_enabled = ui.checkBox_red_zone_protection->isChecked();
#endif
diff --git a/src/launcher/src/mainDialog.cpp b/src/launcher/src/mainDialog.cpp
index 7a4cee5d5..8896ad033 100644
--- a/src/launcher/src/mainDialog.cpp
+++ b/src/launcher/src/mainDialog.cpp
@@ -254,6 +254,9 @@ static QStringList CreateEmulatorArgs(const Configuration& info) {
args << "--profile";
}
args << "--spirv-debug-printf" << "false";
+ if (info.amd_cpu_enabled) {
+ args << "--amd-cpu";
+ }
#if defined(_WIN32)
if (info.red_zone_protection_enabled) {
args << "--redzone";
diff --git a/src/loader/runtimeLinker.cpp b/src/loader/runtimeLinker.cpp
index 85433363f..621e4a003 100644
--- a/src/loader/runtimeLinker.cpp
+++ b/src/loader/runtimeLinker.cpp
@@ -2089,13 +2089,15 @@ void RuntimeLinker::LoadProgramToMemory(Program* program) {
mode == Common::VirtualMemory::Mode::NoAccess);
if (Common::VirtualMemory::IsExecute(mode)) {
- const auto reciprocal_sqrt_count =
- X64InstructionEmulator::PatchReciprocalSquareRoots(segment_addr,
- segment_file_size);
- if (reciprocal_sqrt_count != 0) {
- LOGF("Guest VRSQRTPS emulation: %s, instructions=%" PRIu64 "\n",
- Common::PathToString(program->file_name.filename()).c_str(),
- reciprocal_sqrt_count);
+ if (Config::AmdCpuEnabled()) {
+ const auto reciprocal_sqrt_count =
+ X64InstructionEmulator::PatchReciprocalSquareRoots(segment_addr,
+ segment_file_size);
+ if (reciprocal_sqrt_count != 0) {
+ LOGF("Guest VRSQRTPS emulation: %s, instructions=%" PRIu64 "\n",
+ Common::PathToString(program->file_name.filename()).c_str(),
+ reciprocal_sqrt_count);
+ }
}
PatchProgram(program, segment_addr, segment_memory_size);
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
diff --git a/src/main.cpp b/src/main.cpp
index 1c35cd237..c5ddc5256 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -56,6 +56,7 @@ static void PrintUsage() {
" --gpu Vulkan physical device index. Default: auto.\n");
::printf(" --fullscreen Run in borderless desktop fullscreen.\n");
::printf(" --vr Enable the virtual VR headset.\n");
+ ::printf(" --amd-cpu Apply AMD CPU instruction patches (Linux).\n");
::printf(" --vblank-frequency Virtual vblank frequency. Default: 60.\n");
::printf(" --console-language <0-29> Console language. Default: 1 (English US).\n");
::printf(" --vulkan-validation Enable Vulkan validation.\n");
@@ -168,6 +169,11 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
continue;
}
+ if (arg == "--amd-cpu") {
+ options.config.amd_cpu_enabled = true;
+ continue;
+ }
+
if (arg == "--playgo-hack") {
options.config.playgo_hack_enabled = true;
continue;