mirror of
https://github.com/izzy2lost/xenia-edge.git
synced 2026-07-06 00:20:26 -07:00
[Config/UI] Consolidate render_target_path* cvars
Change from fbo/rtv and fsi/rov to performance/accuracy and rework cvar aliasing to accommodate more entries
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "xenia/base/string.h"
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/base/system.h"
|
||||
#include "xenia/ui/config_helpers.h"
|
||||
|
||||
toml::parse_result ParseFile(const std::filesystem::path& filename) {
|
||||
return toml::parse_file(xe::path_to_utf8(filename));
|
||||
@@ -88,6 +89,38 @@ void PrintConfigToLog(const std::filesystem::path& file_path) {
|
||||
file.close();
|
||||
}
|
||||
|
||||
void MigrateLegacyCvars(const toml::table& config) {
|
||||
if (!cvar::ConfigVars) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& [category_name, category_table] : config) {
|
||||
if (!category_table.is_table()) continue;
|
||||
|
||||
for (const auto& [key, value] : *category_table.as_table()) {
|
||||
std::string var_name = std::string(key);
|
||||
std::string var_value = value.value_or("");
|
||||
|
||||
if (var_value.length() >= 2 && var_value.front() == '"' &&
|
||||
var_value.back() == '"') {
|
||||
var_value = var_value.substr(1, var_value.length() - 2);
|
||||
}
|
||||
|
||||
for (const auto& alias : xe::ui::GetCvarAliases()) {
|
||||
if (var_name == alias.old_name && var_value == alias.old_value) {
|
||||
auto new_cvar = (*cvar::ConfigVars).find(alias.new_name);
|
||||
if (new_cvar != (*cvar::ConfigVars).end()) {
|
||||
auto config_var = static_cast<cvar::IConfigVar*>(new_cvar->second);
|
||||
toml::value new_value(alias.new_value);
|
||||
config_var->LoadConfigValue(&new_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadConfig(const std::filesystem::path& file_path,
|
||||
bool update_if_no_version_stored) {
|
||||
if (!cvar::ConfigVars) {
|
||||
@@ -115,6 +148,8 @@ void ReadConfig(const std::filesystem::path& file_path,
|
||||
config_var->LoadConfigValue(config_key_node.node());
|
||||
}
|
||||
}
|
||||
|
||||
MigrateLegacyCvars(config);
|
||||
uint32_t config_defaults_date = defaults_date_cvar->GetTypedConfigValue();
|
||||
if (update_if_no_version_stored || config_defaults_date) {
|
||||
cvar::IConfigVarUpdate::ApplyUpdates(config_defaults_date);
|
||||
|
||||
@@ -38,33 +38,6 @@ DEFINE_bool(
|
||||
"working on UHD Graphics 630 as of March 2021 (driver 27.20.0100.8336).",
|
||||
"GPU");
|
||||
DEFINE_bool(no_discard_stencil_in_transfer_pipelines, false, "bleh", "GPU");
|
||||
// TODO(Triang3l): Make ROV the default when it's optimized better (for
|
||||
// instance, using static shader modifications to pass render target
|
||||
// parameters).
|
||||
DEFINE_string(
|
||||
render_target_path_d3d12, "",
|
||||
"Render target emulation path to use on Direct3D 12.\n"
|
||||
"Use: [any, rtv, rov]\n"
|
||||
" rtv:\n"
|
||||
" Host render targets and fixed-function blending and depth / stencil "
|
||||
"testing, copying between render targets when needed.\n"
|
||||
" Lower accuracy (limited pixel format support).\n"
|
||||
" Performance limited primarily by render target layout changes requiring "
|
||||
"copying, but generally higher.\n"
|
||||
" rov:\n"
|
||||
" Manual pixel packing, blending and depth / stencil testing, with free "
|
||||
"render target layout changes.\n"
|
||||
" Requires a GPU supporting rasterizer-ordered views.\n"
|
||||
" Highest accuracy (all pixel formats handled in software).\n"
|
||||
" Performance limited primarily by overdraw.\n"
|
||||
" On AMD drivers, currently causes shader compiler crashes in many "
|
||||
"cases.\n"
|
||||
" Any other value:\n"
|
||||
" Choose what is considered the most optimal for the system (currently "
|
||||
"always RTV because the ROV path is much slower now, except for Intel "
|
||||
"GPUs, which have a bug in stencil testing that causes Xbox 360 Direct3D 9 "
|
||||
"clears not to work).",
|
||||
"GPU");
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
@@ -214,9 +187,9 @@ bool D3D12RenderTargetCache::Initialize() {
|
||||
command_processor_.GetD3D12Provider();
|
||||
ID3D12Device* device = provider.GetDevice();
|
||||
|
||||
if (cvars::render_target_path_d3d12 == "rtv") {
|
||||
if (cvars::render_target_path == "performance") {
|
||||
path_ = Path::kHostRenderTargets;
|
||||
} else if (cvars::render_target_path_d3d12 == "rov") {
|
||||
} else if (cvars::render_target_path == "accuracy") {
|
||||
path_ = Path::kPixelShaderInterlock;
|
||||
} else {
|
||||
// As of April 2021 (driver version 27.20.0100.9316), on Intel (tested on
|
||||
|
||||
@@ -66,3 +66,27 @@ DEFINE_int32(
|
||||
"Set to higher number than query_occlusion_sample_lower_threshold. This "
|
||||
"value is ignored if query_occlusion_sample_lower_threshold is set to -1.",
|
||||
"GPU");
|
||||
|
||||
// TODO(Triang3l): Make accuracy (ROV/FSI) the default when it's optimized
|
||||
// better (for instance, using static shader modifications to pass render
|
||||
// target parameters).
|
||||
DEFINE_string(
|
||||
render_target_path, "performance",
|
||||
"Render target emulation path to use across all GPU backends.\n"
|
||||
"Use: [performance, accuracy]\n"
|
||||
" performance:\n"
|
||||
" Host render targets and fixed-function blending and depth/stencil "
|
||||
"testing, copying between render targets when needed.\n"
|
||||
" Lower accuracy (limited pixel format support).\n"
|
||||
" Performance limited primarily by render target layout changes requiring "
|
||||
"copying, but generally higher.\n"
|
||||
" Maps to 'fbo' on Vulkan and 'rtv' on D3D12.\n"
|
||||
" accuracy:\n"
|
||||
" Manual pixel packing, blending and depth/stencil testing, with free "
|
||||
"render target layout changes.\n"
|
||||
" Requires GPU supporting fragment shader interlock (Vulkan) or "
|
||||
"rasterizer-ordered views (D3D12).\n"
|
||||
" Highest accuracy (all pixel formats handled in software).\n"
|
||||
" Performance limited primarily by overdraw.\n"
|
||||
" Maps to 'fsi' on Vulkan and 'rov' on D3D12.",
|
||||
"GPU");
|
||||
|
||||
@@ -32,6 +32,8 @@ DECLARE_int32(query_occlusion_sample_upper_threshold);
|
||||
|
||||
DECLARE_bool(disassemble_pm4);
|
||||
|
||||
DECLARE_string(render_target_path);
|
||||
|
||||
#define XE_GPU_FINE_GRAINED_DRAW_SCOPES 1
|
||||
|
||||
#endif // XENIA_GPU_GPU_FLAGS_H_
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/gpu/draw_util.h"
|
||||
#include "xenia/gpu/gpu_flags.h"
|
||||
#include "xenia/gpu/registers.h"
|
||||
#include "xenia/gpu/spirv_builder.h"
|
||||
#include "xenia/gpu/spirv_compatibility.h"
|
||||
@@ -29,27 +30,6 @@
|
||||
#include "xenia/gpu/xenos.h"
|
||||
#include "xenia/ui/vulkan/vulkan_util.h"
|
||||
|
||||
DEFINE_string(
|
||||
render_target_path_vulkan, "",
|
||||
"Render target emulation path to use on Vulkan.\n"
|
||||
"Use: [any, fbo, fsi]\n"
|
||||
" fbo:\n"
|
||||
" Host framebuffers and fixed-function blending and depth / stencil "
|
||||
"testing, copying between render targets when needed.\n"
|
||||
" Lower accuracy (limited pixel format support).\n"
|
||||
" Performance limited primarily by render target layout changes requiring "
|
||||
"copying, but generally higher.\n"
|
||||
" fsi:\n"
|
||||
" Manual pixel packing, blending and depth / stencil testing, with free "
|
||||
"render target layout changes.\n"
|
||||
" Requires a GPU supporting fragment shader interlock.\n"
|
||||
" Highest accuracy (all pixel formats handled in software).\n"
|
||||
" Performance limited primarily by overdraw.\n"
|
||||
" Any other value:\n"
|
||||
" Choose what is considered the most optimal for the system (currently "
|
||||
"always FB because the FSI path is much slower now).",
|
||||
"GPU");
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace vulkan {
|
||||
@@ -216,7 +196,7 @@ bool VulkanRenderTargetCache::Initialize(uint32_t shared_memory_binding_count) {
|
||||
const ui::vulkan::VulkanDevice::Properties& device_properties =
|
||||
vulkan_device->properties();
|
||||
|
||||
if (cvars::render_target_path_vulkan == "fsi") {
|
||||
if (cvars::render_target_path == "accuracy") {
|
||||
path_ = Path::kPixelShaderInterlock;
|
||||
} else {
|
||||
path_ = Path::kHostRenderTargets;
|
||||
|
||||
@@ -19,6 +19,27 @@
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
|
||||
struct CvarAlias {
|
||||
std::string old_name;
|
||||
std::string old_value;
|
||||
std::string new_name;
|
||||
std::string new_value;
|
||||
};
|
||||
|
||||
inline const std::vector<CvarAlias>& GetCvarAliases() {
|
||||
static const std::vector<CvarAlias> aliases = {
|
||||
{"use_new_decoder", "true", "xma_decoder", "new"},
|
||||
{"use_old_decoder", "true", "xma_decoder", "old"},
|
||||
{"readback_resolve", "true", "readback_resolve", "fast"},
|
||||
{"readback_resolve", "false", "readback_resolve", "fast"},
|
||||
{"render_target_path_d3d12", "rtv", "render_target_path", "performance"},
|
||||
{"render_target_path_d3d12", "rov", "render_target_path", "accuracy"},
|
||||
{"render_target_path_vulkan", "fbo", "render_target_path", "performance"},
|
||||
{"render_target_path_vulkan", "fsi", "render_target_path", "accuracy"},
|
||||
};
|
||||
return aliases;
|
||||
}
|
||||
|
||||
// Known enum-like cvars with their valid options
|
||||
inline const std::map<std::string, std::vector<std::string>>&
|
||||
GetKnownEnumOptions() {
|
||||
@@ -39,8 +60,7 @@ GetKnownEnumOptions() {
|
||||
{"d3d12_readback_resolve",
|
||||
{"kCopy", "kComputeLuminance", "kComputeRGBA16"}},
|
||||
{"readback_resolve", {"fast", "full", "none"}},
|
||||
{"render_target_path_d3d12", {"any", "rtv", "rov"}},
|
||||
{"render_target_path_vulkan", {"any", "fbo", "fsi"}},
|
||||
{"render_target_path", {"performance", "accuracy"}},
|
||||
{"postprocess_antialiasing", {"off", "fxaa", "fxaa_extreme"}},
|
||||
{"postprocess_scaling_and_sharpening",
|
||||
{"bilinear", "cas", "fsr", "nearest"}},
|
||||
|
||||
@@ -63,32 +63,16 @@ std::string JsonValueToString(const rapidjson::Value& value) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// CanaryCvarCompat: Translate legacy Xenia Canary cvar names/values to current
|
||||
// ones Returns true if translation occurred, filling out_var_name and out_value
|
||||
bool CanaryCvarCompat(const std::string& var_name, const std::string& value,
|
||||
std::string& out_var_name, std::string& out_value) {
|
||||
// use_new_decoder: true -> xma_decoder: new
|
||||
if (var_name == "use_new_decoder" && value == "true") {
|
||||
out_var_name = "xma_decoder";
|
||||
out_value = "new";
|
||||
return true;
|
||||
for (const auto& alias : xe::ui::GetCvarAliases()) {
|
||||
if (var_name == alias.old_name && value == alias.old_value) {
|
||||
out_var_name = alias.new_name;
|
||||
out_value = alias.new_value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// use_old_decoder: true -> xma_decoder: old
|
||||
if (var_name == "use_old_decoder" && value == "true") {
|
||||
out_var_name = "xma_decoder";
|
||||
out_value = "old";
|
||||
return true;
|
||||
}
|
||||
|
||||
// readback_resolve: true/false -> readback_resolve: fast (default)
|
||||
if (var_name == "readback_resolve" && (value == "true" || value == "false")) {
|
||||
out_var_name = "readback_resolve";
|
||||
out_value = "fast";
|
||||
return true;
|
||||
}
|
||||
|
||||
// No translation needed
|
||||
out_var_name = var_name;
|
||||
out_value = value;
|
||||
return false;
|
||||
@@ -255,6 +239,33 @@ void GameConfigDialogQt::LoadConfigOverrides() {
|
||||
CreateRow(var_name, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for legacy cvar names in the TOML that need migration
|
||||
for (const auto& [category_name, category_table] : config) {
|
||||
if (!category_table.is_table()) continue;
|
||||
|
||||
for (const auto& [key, value] : *category_table.as_table()) {
|
||||
std::string var_name = std::string(key);
|
||||
std::string var_value = value.value_or("");
|
||||
|
||||
if (var_value.length() >= 2 && var_value.front() == '"' &&
|
||||
var_value.back() == '"') {
|
||||
var_value = var_value.substr(1, var_value.length() - 2);
|
||||
}
|
||||
|
||||
std::string translated_name;
|
||||
std::string translated_value;
|
||||
if (CanaryCvarCompat(var_name, var_value, translated_name,
|
||||
translated_value)) {
|
||||
if (translated_name != var_name &&
|
||||
!config_overrides_.count(translated_name)) {
|
||||
config_overrides_[translated_name] = translated_value;
|
||||
CreateRow(translated_name, translated_value);
|
||||
has_unsaved_changes_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
XELOGE("Failed to load game config {}: {}", xe::path_to_utf8(config_path),
|
||||
e.what());
|
||||
|
||||
Reference in New Issue
Block a user