UI: Replasce accurate GPU option for GPU Accuracy Level

This commit is contained in:
Fernando Sahmkow 2020-02-18 16:51:42 -04:00
parent d64290884a
commit 084ceb925a
12 changed files with 77 additions and 28 deletions

View File

@ -92,7 +92,7 @@ void LogSettings() {
LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit); LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit);
LogSetting("Renderer_FrameLimit", Settings::values.frame_limit); LogSetting("Renderer_FrameLimit", Settings::values.frame_limit);
LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache); LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache);
LogSetting("Renderer_UseAccurateGpuEmulation", Settings::values.use_accurate_gpu_emulation); LogSetting("Renderer_GPUAccuracyLevel", Settings::values.gpu_accuracy);
LogSetting("Renderer_UseAsynchronousGpuEmulation", LogSetting("Renderer_UseAsynchronousGpuEmulation",
Settings::values.use_asynchronous_gpu_emulation); Settings::values.use_asynchronous_gpu_emulation);
LogSetting("Renderer_UseVsync", Settings::values.use_vsync); LogSetting("Renderer_UseVsync", Settings::values.use_vsync);

View File

@ -376,6 +376,12 @@ enum class RendererBackend {
Vulkan = 1, Vulkan = 1,
}; };
enum class GPUAccuracy : u32 {
Normal = 0,
High = 1,
Extreme = 2,
};
struct Values { struct Values {
// System // System
bool use_docked_mode; bool use_docked_mode;
@ -436,7 +442,7 @@ struct Values {
bool use_frame_limit; bool use_frame_limit;
u16 frame_limit; u16 frame_limit;
bool use_disk_shader_cache; bool use_disk_shader_cache;
bool use_accurate_gpu_emulation; GPUAccuracy gpu_accuracy;
bool use_asynchronous_gpu_emulation; bool use_asynchronous_gpu_emulation;
bool use_vsync; bool use_vsync;
bool force_30fps_mode; bool force_30fps_mode;
@ -480,6 +486,14 @@ struct Values {
std::map<u64, std::vector<std::string>> disabled_addons; std::map<u64, std::vector<std::string>> disabled_addons;
} extern values; } extern values;
constexpr bool IsGPULevelExtreme() {
return values.gpu_accuracy == GPUAccuracy::Extreme;
}
constexpr bool IsGPULevelHigh() {
return values.gpu_accuracy == GPUAccuracy::Extreme || values.gpu_accuracy == GPUAccuracy::High;
}
void Apply(); void Apply();
void LogSettings(); void LogSettings();
} // namespace Settings } // namespace Settings

View File

@ -56,6 +56,18 @@ static const char* TranslateRenderer(Settings::RendererBackend backend) {
return "Unknown"; return "Unknown";
} }
static const char* TranslateGPUAccuracyLevel(Settings::GPUAccuracy backend) {
switch (backend) {
case Settings::GPUAccuracy::Normal:
return "Normal";
case Settings::GPUAccuracy::High:
return "High";
case Settings::GPUAccuracy::Extreme:
return "Extreme";
}
return "Unknown";
}
u64 GetTelemetryId() { u64 GetTelemetryId() {
u64 telemetry_id{}; u64 telemetry_id{};
const std::string filename{FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + const std::string filename{FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) +
@ -184,8 +196,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
AddField(field_type, "Renderer_UseFrameLimit", Settings::values.use_frame_limit); AddField(field_type, "Renderer_UseFrameLimit", Settings::values.use_frame_limit);
AddField(field_type, "Renderer_FrameLimit", Settings::values.frame_limit); AddField(field_type, "Renderer_FrameLimit", Settings::values.frame_limit);
AddField(field_type, "Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache); AddField(field_type, "Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache);
AddField(field_type, "Renderer_UseAccurateGpuEmulation", AddField(field_type, "Renderer_GPUAccuracyLevel",
Settings::values.use_accurate_gpu_emulation); TranslateGPUAccuracyLevel(Settings::values.gpu_accuracy));
AddField(field_type, "Renderer_UseAsynchronousGpuEmulation", AddField(field_type, "Renderer_UseAsynchronousGpuEmulation",
Settings::values.use_asynchronous_gpu_emulation); Settings::values.use_asynchronous_gpu_emulation);
AddField(field_type, "Renderer_UseVsync", Settings::values.use_vsync); AddField(field_type, "Renderer_UseVsync", Settings::values.use_vsync);

View File

@ -136,7 +136,7 @@ void MaxwellDMA::HandleCopy() {
write_buffer.resize(dst_size); write_buffer.resize(dst_size);
} }
if (Settings::values.use_accurate_gpu_emulation) { if (Settings::IsGPULevelExtreme()) {
memory_manager.ReadBlock(source, read_buffer.data(), src_size); memory_manager.ReadBlock(source, read_buffer.data(), src_size);
memory_manager.ReadBlock(dest, write_buffer.data(), dst_size); memory_manager.ReadBlock(dest, write_buffer.data(), dst_size);
} else { } else {

View File

@ -661,7 +661,7 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
} }
void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
if (Settings::values.use_accurate_gpu_emulation) { if (Settings::IsGPULevelExtreme()) {
FlushRegion(addr, size); FlushRegion(addr, size);
} }
InvalidateRegion(addr, size); InvalidateRegion(addr, size);

View File

@ -417,7 +417,7 @@ private:
**/ **/
RecycleStrategy PickStrategy(std::vector<TSurface>& overlaps, const SurfaceParams& params, RecycleStrategy PickStrategy(std::vector<TSurface>& overlaps, const SurfaceParams& params,
const GPUVAddr gpu_addr, const MatchTopologyResult untopological) { const GPUVAddr gpu_addr, const MatchTopologyResult untopological) {
if (Settings::values.use_accurate_gpu_emulation) { if (Settings::IsGPULevelExtreme()) {
return RecycleStrategy::Flush; return RecycleStrategy::Flush;
} }
// 3D Textures decision // 3D Textures decision
@ -461,7 +461,7 @@ private:
} }
switch (PickStrategy(overlaps, params, gpu_addr, untopological)) { switch (PickStrategy(overlaps, params, gpu_addr, untopological)) {
case RecycleStrategy::Ignore: { case RecycleStrategy::Ignore: {
return InitializeSurface(gpu_addr, params, Settings::values.use_accurate_gpu_emulation); return InitializeSurface(gpu_addr, params, Settings::IsGPULevelExtreme());
} }
case RecycleStrategy::Flush: { case RecycleStrategy::Flush: {
std::sort(overlaps.begin(), overlaps.end(), std::sort(overlaps.begin(), overlaps.end(),
@ -598,7 +598,7 @@ private:
if (passed_tests == 0) { if (passed_tests == 0) {
return {}; return {};
// In Accurate GPU all tests should pass, else we recycle // In Accurate GPU all tests should pass, else we recycle
} else if (Settings::values.use_accurate_gpu_emulation && passed_tests != overlaps.size()) { } else if (Settings::IsGPULevelExtreme() && passed_tests != overlaps.size()) {
return {}; return {};
} }
for (const auto& surface : overlaps) { for (const auto& surface : overlaps) {
@ -668,7 +668,7 @@ private:
for (const auto& surface : overlaps) { for (const auto& surface : overlaps) {
if (!surface->MatchTarget(params.target)) { if (!surface->MatchTarget(params.target)) {
if (overlaps.size() == 1 && surface->GetCpuAddr() == cpu_addr) { if (overlaps.size() == 1 && surface->GetCpuAddr() == cpu_addr) {
if (Settings::values.use_accurate_gpu_emulation) { if (Settings::IsGPULevelExtreme()) {
return std::nullopt; return std::nullopt;
} }
Unregister(surface); Unregister(surface);

View File

@ -639,8 +639,8 @@ void Config::ReadRendererValues() {
Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toInt(); Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toInt();
Settings::values.use_disk_shader_cache = Settings::values.use_disk_shader_cache =
ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool(); ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool();
Settings::values.use_accurate_gpu_emulation = const int gpu_accuracy_level = ReadSetting(QStringLiteral("gpu_accuracy"), 0).toInt();
ReadSetting(QStringLiteral("use_accurate_gpu_emulation"), false).toBool(); Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level);
Settings::values.use_asynchronous_gpu_emulation = Settings::values.use_asynchronous_gpu_emulation =
ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool(); ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool();
Settings::values.use_vsync = ReadSetting(QStringLiteral("use_vsync"), true).toBool(); Settings::values.use_vsync = ReadSetting(QStringLiteral("use_vsync"), true).toBool();
@ -1080,8 +1080,7 @@ void Config::SaveRendererValues() {
WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100);
WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache, WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache,
true); true);
WriteSetting(QStringLiteral("use_accurate_gpu_emulation"), WriteSetting(QStringLiteral("gpu_accuracy"), static_cast<int>(Settings::values.gpu_accuracy), 0);
Settings::values.use_accurate_gpu_emulation, false);
WriteSetting(QStringLiteral("use_asynchronous_gpu_emulation"), WriteSetting(QStringLiteral("use_asynchronous_gpu_emulation"),
Settings::values.use_asynchronous_gpu_emulation, false); Settings::values.use_asynchronous_gpu_emulation, false);
WriteSetting(QStringLiteral("use_vsync"), Settings::values.use_vsync, true); WriteSetting(QStringLiteral("use_vsync"), Settings::values.use_vsync, true);

View File

@ -19,7 +19,7 @@ ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
void ConfigureGraphicsAdvanced::SetConfiguration() { void ConfigureGraphicsAdvanced::SetConfiguration() {
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation); ui->gpu_accuracy->setCurrentIndex(static_cast<int>(Settings::values.gpu_accuracy));
ui->use_vsync->setEnabled(runtime_lock); ui->use_vsync->setEnabled(runtime_lock);
ui->use_vsync->setChecked(Settings::values.use_vsync); ui->use_vsync->setChecked(Settings::values.use_vsync);
ui->force_30fps_mode->setEnabled(runtime_lock); ui->force_30fps_mode->setEnabled(runtime_lock);
@ -29,7 +29,8 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
} }
void ConfigureGraphicsAdvanced::ApplyConfiguration() { void ConfigureGraphicsAdvanced::ApplyConfiguration() {
Settings::values.use_accurate_gpu_emulation = ui->use_accurate_gpu_emulation->isChecked(); auto gpu_accuracy = static_cast<Settings::GPUAccuracy>(ui->gpu_accuracy->currentIndex());
Settings::values.gpu_accuracy = gpu_accuracy;
Settings::values.use_vsync = ui->use_vsync->isChecked(); Settings::values.use_vsync = ui->use_vsync->isChecked();
Settings::values.force_30fps_mode = ui->force_30fps_mode->isChecked(); Settings::values.force_30fps_mode = ui->force_30fps_mode->isChecked();
Settings::values.max_anisotropy = ui->anisotropic_filtering_combobox->currentIndex(); Settings::values.max_anisotropy = ui->anisotropic_filtering_combobox->currentIndex();

View File

@ -23,11 +23,34 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<widget class="QCheckBox" name="use_accurate_gpu_emulation"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="text"> <item>
<string>Use accurate GPU emulation (slow)</string> <widget class="QLabel" name="label_gpu_accuracy">
</property> <property name="text">
</widget> <string>Accuracy Level:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="gpu_accuracy">
<item>
<property name="text">
<string notr="true">Normal</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">High</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Extreme(very slow)</string>
</property>
</item>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="use_vsync"> <widget class="QCheckBox" name="use_vsync">

View File

@ -388,8 +388,8 @@ void Config::ReadValues() {
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));
Settings::values.use_disk_shader_cache = Settings::values.use_disk_shader_cache =
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false); sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false);
Settings::values.use_accurate_gpu_emulation = const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0);
sdl2_config->GetBoolean("Renderer", "use_accurate_gpu_emulation", false); Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level);
Settings::values.use_asynchronous_gpu_emulation = Settings::values.use_asynchronous_gpu_emulation =
sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false); sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false);
Settings::values.use_vsync = Settings::values.use_vsync =

View File

@ -146,9 +146,9 @@ frame_limit =
# 0 (default): Off, 1 : On # 0 (default): Off, 1 : On
use_disk_shader_cache = use_disk_shader_cache =
# Whether to use accurate GPU emulation # Which gpu accuracy level to use
# 0 (default): Off (fast), 1 : On (slow) # 0 (Normal), 1 (High), 2 (Extreme)
use_accurate_gpu_emulation = gpu_accuracy =
# Whether to use asynchronous GPU emulation # Whether to use asynchronous GPU emulation
# 0 : Off (slow), 1 (default): On (fast) # 0 : Off (slow), 1 (default): On (fast)

View File

@ -126,8 +126,8 @@ void Config::ReadValues() {
Settings::values.frame_limit = 100; Settings::values.frame_limit = 100;
Settings::values.use_disk_shader_cache = Settings::values.use_disk_shader_cache =
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false); sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false);
Settings::values.use_accurate_gpu_emulation = const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0);
sdl2_config->GetBoolean("Renderer", "use_accurate_gpu_emulation", false); Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level);
Settings::values.use_asynchronous_gpu_emulation = Settings::values.use_asynchronous_gpu_emulation =
sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false); sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false);