Skip to content

Commit cda9f2e

Browse files
committed
Merge branch 'xbei/option_layers' into 'main'
[REMIX-4108] Implement real-time user conf See merge request lightspeedrtx/dxvk-remix-nv!1722
2 parents 78bb211 + e66d94c commit cda9f2e

File tree

5 files changed

+51
-39
lines changed

5 files changed

+51
-39
lines changed

src/dxvk/dxvk_instance.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,9 @@ namespace dxvk {
648648

649649
m_config.logOptions("Effective (combined)");
650650

651+
RtxOptionImpl::addRtxOptionLayer(RtxOptionLayer("user.conf", RtxOptionLayer::s_runtimeOptionLayerPriority, 1.0f, 1.0f));
652+
Logger::info("Set user realtime configs.");
653+
651654
// Output environment variable info
652655
// Todo: This being here is kinda not great as this results in the Environment variables being parsed 3 times
653656
// which is quite redundant. Unfortunately this logging can't go in Config::getOption as this function is called

src/dxvk/imgui/dxvk_imgui.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,16 +1099,13 @@ namespace dxvk {
10991099
}
11001100

11011101
ImGui::Checkbox("Save Changed Settings Only", &RtxOptions::serializeChangedOptionOnlyObject());
1102-
if (ImGui::Button("Save Settings")) {
1102+
if (IMGUI_ADD_TOOLTIP(ImGui::Button("Save Settings"), "Changes are now saved to user.conf. Use the 'Save' button in the rtx.conf layer if you want to store them there for sharing.")) {
11031103
RtxOptions::serialize();
11041104
}
1105-
ImGui::SetTooltipToLastWidgetOnHover("This will save above settings in the rtx.conf file. Some may only take effect on next launch.");
11061105

11071106
ImGui::SameLine();
1108-
if (ImGui::Button("Reset Settings")) {
1109-
for (auto& optionLayer : RtxOptionImpl::getRtxOptionLayerMap()) {
1110-
optionLayer.setEnabled(false);
1111-
}
1107+
if (IMGUI_ADD_TOOLTIP(ImGui::Button("Reset settings"), "Reset all real-time changed settings.")) {
1108+
RtxOptionLayer::setResetSettings(true);
11121109
}
11131110

11141111
ImGui::SameLine();
@@ -1983,9 +1980,17 @@ namespace dxvk {
19831980
if (ImGui::CollapsingHeader("Option Layers")) {
19841981
ImGui::Indent();
19851982

1986-
if (ImGui::Button("Reset runtime settings")) {
1987-
// Remove all run-time changed settings
1988-
RtxOptionLayer::setResetSettings(true);
1983+
if (IMGUI_ADD_TOOLTIP(ImGui::Button("Disable Layers"), "Reset all settings to Default.")) {
1984+
for (auto& optionLayer : RtxOptionImpl::getRtxOptionLayerMap()) {
1985+
optionLayer.setEnabled(false);
1986+
}
1987+
}
1988+
1989+
ImGui::SameLine();
1990+
if (IMGUI_ADD_TOOLTIP(ImGui::Button("Enable Layers"), "Enable all option layers.")) {
1991+
for (auto& optionLayer : RtxOptionImpl::getRtxOptionLayerMap()) {
1992+
optionLayer.setEnabled(true);
1993+
}
19891994
}
19901995

19911996
uint32_t optionLayerCounter = 1;
@@ -2011,6 +2016,11 @@ namespace dxvk {
20112016
optionLayer.setBlendStrengthDirty(true);
20122017
}
20132018

2019+
const std::string optionLayerSavingText = "Save realtime changes into layer " + optionLayer.getName();
2020+
if (ImGui::Button(optionLayerSavingText.c_str())) {
2021+
RtxOptions::serializeOptionLayer(optionLayer.getName());
2022+
}
2023+
20142024
if (ImGui::CollapsingHeader((optionLayer.getName() + " Details").c_str(), collapsingHeaderClosedFlags)) {
20152025
ImGui::Indent();
20162026
const std::string priorityText = "Priority: " + std::to_string(optionLayer.getPriority());

src/dxvk/rtx_render/rtx_option.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,16 @@ namespace dxvk {
490490
auto& value = resolvedValue;
491491

492492
if (changedOptionOnly) {
493-
if (isDefault()) {
493+
// Skip options that have no real-time changes, or the real-time value is the same as the original resolved value.
494+
if (optionLayerValueQueue.begin()->second.priority != RtxOptionLayer::s_runtimeOptionLayerPriority) {
494495
return;
496+
} else {
497+
GenericValueWrapper originalValue(type);
498+
resolveValue(originalValue.data, true);
499+
500+
if (isEqual(originalValue.data, getGenericValue(ValueType::PendingValue))) {
501+
return;
502+
}
495503
}
496504
}
497505

@@ -742,24 +750,7 @@ namespace dxvk {
742750
}
743751
}
744752

745-
void RtxOptionImpl::copyOptionLayerToValue() {
746-
GenericValue& optionValueTop = optionLayerValueQueue.begin()->second.value;
747-
const auto& pendingValue = getGenericValue(RtxOptionImpl::ValueType::PendingValue);
748-
749-
if (optionLayerValueQueue.begin()->second.priority == RtxOptionLayer::s_runtimeOptionLayerPriority &&
750-
!isEqual(pendingValue, optionValueTop)) {
751-
// Sync the values that are changed at real-time to top option layer
752-
copyValue(pendingValue, optionValueTop);
753-
#if RTX_OPTION_DEBUG_LOGGING
754-
Logger::info(str::format("[RTX Option]: Different to pending option ", this->name,
755-
"\ntype: ", std::to_string((int) this->type),
756-
"\nbool: ", std::to_string(pendingValue.b), " ", std::to_string(optionValueTop.b),
757-
"\nint: ", std::to_string(pendingValue.i), " ", std::to_string(optionValueTop.i),
758-
"\nfloat: ", std::to_string(pendingValue.f), " ", std::to_string(optionValueTop.f)
759-
));
760-
#endif
761-
}
762-
753+
void RtxOptionImpl::resolveValue(GenericValue& value, const bool ignoreChangedOption) {
763754
/*
764755
We use "throughput" here because blending (lerp) may happen across multiple layers.
765756
The effective result is a nested lerp chain, e.g.: v = lerp(A, lerp(B, C))
@@ -786,6 +777,11 @@ namespace dxvk {
786777
float throughput = 1.0f;
787778
// Loop layers from highest priority to lowest to lerp the value across layers base on the blend strength of layers
788779
for (const auto& optionLayer : optionLayerValueQueue) {
780+
// Skip options with runtime priority when ignoreChangedOption is true
781+
if (ignoreChangedOption && optionLayer.second.priority == RtxOptionLayer::s_runtimeOptionLayerPriority) {
782+
continue;
783+
}
784+
789785
if (type == OptionType::Float || type == OptionType::Vector2 || type == OptionType::Vector3 || type == OptionType::Vector4) {
790786
// Stop when the blend strength is larger than 1, because lerp(a, b, 1.0f) => b, we don't need to loop lower priority values
791787
if (optionLayer.second.blendStrength >= 1.0f) {
@@ -804,7 +800,7 @@ namespace dxvk {
804800
}
805801

806802
// Copy to resolvedValue
807-
copyValue(optionValue.data, resolvedValue);
803+
copyValue(optionValue.data, value);
808804
}
809805

810806
bool RtxOptionImpl::writeMarkdownDocumentation(const char* outputMarkdownFilePath) {
@@ -1025,7 +1021,7 @@ Tables below enumerate all the options and their defaults set by RTX Remix. Note
10251021
: m_configName(configPath)
10261022
, m_enabled(true)
10271023
, m_dirty(false)
1028-
, m_priority(priority + s_userOptionLayerOffset)
1024+
, m_priority(priority)
10291025
, m_blendStrength(blendStrength)
10301026
, m_blendThreshold(blendThreshold)
10311027
, m_config(Config::getOptionLayerConfig(configPath)) {
@@ -1034,6 +1030,9 @@ Tables below enumerate all the options and their defaults set by RTX Remix. Note
10341030
"\nPriority: ", std::to_string(m_priority),
10351031
"\nStrength: ", std::to_string(m_blendStrength)));
10361032
#endif
1033+
if (priority != RtxOptionLayer::s_runtimeOptionLayerPriority) {
1034+
m_priority += s_userOptionLayerOffset;
1035+
}
10371036
}
10381037

10391038
RtxOptionLayer::RtxOptionLayer(const Config& config, const std::string& configName, const uint32_t priority, const float blendStrength, const float blendThreshold)

src/dxvk/rtx_render/rtx_option.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ namespace dxvk {
231231
std::string genericValueToString(ValueType valueType) const;
232232
std::string genericValueToString(const GenericValue& value) const;
233233
void copyValue(const GenericValue& source, GenericValue& target);
234-
void copyOptionLayerToValue();
234+
void resolveValue(GenericValue& value, const bool ignoreChangedOption);
235235
void addWeightedValue(const GenericValue& source, const float weight, GenericValue& target);
236236

237237
void readValue(const Config& options, const std::string& fullName, GenericValue& value);
@@ -350,12 +350,6 @@ namespace dxvk {
350350
pImpl->clampValue(RtxOptionImpl::ValueType::Value);
351351
// Mark the option as dirty so that the onChange callback is invoked, even though the value already changed mid frame.
352352
pImpl->markDirty();
353-
354-
// If the top layer is not already the runtime option layer, insert a new runtime option layer with maximum priority.
355-
// Actual promotion to the active value occurs in applyPendingValuesOptionLayers().
356-
if (pImpl->optionLayerValueQueue.begin()->second.priority != RtxOptionLayer::s_runtimeOptionLayerPriority) {
357-
pImpl->insertOptionLayerValue(pImpl->resolvedValue, RtxOptionLayer::s_runtimeOptionLayerPriority, 1.0f, 1.0f);
358-
}
359353
}
360354

361355
template<typename = std::enable_if_t<std::is_same_v<T, fast_unordered_set>>>
@@ -532,7 +526,7 @@ namespace dxvk {
532526
dirtyOptionsVector.reserve(dirtyOptions.size());
533527
{
534528
for (auto& rtxOption : dirtyOptions) {
535-
rtxOption.second->copyOptionLayerToValue();
529+
rtxOption.second->resolveValue(rtxOption.second->resolvedValue, false);
536530
dirtyOptionsVector.push_back(rtxOption.second);
537531
}
538532
}

src/dxvk/rtx_render/rtx_options.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,14 +1269,20 @@ namespace dxvk {
12691269

12701270
static void resetUpscaler();
12711271

1272-
inline static const std::string kRtxConfigFilePath = "rtx.conf";
1272+
inline static const std::string kRtxConfigFilePath = "user.conf";
12731273

12741274
static void serialize() {
12751275
Config newConfig;
12761276
RtxOption<bool>::writeOptions(newConfig, serializeChangedOptionOnly());
12771277
Config::serializeCustomConfig(newConfig, kRtxConfigFilePath, "rtx.");
12781278
}
12791279

1280+
static void serializeOptionLayer(const std::string& optionLayerName) {
1281+
Config newConfig;
1282+
RtxOption<bool>::writeOptions(newConfig, serializeChangedOptionOnly());
1283+
Config::serializeCustomConfig(newConfig, optionLayerName, "rtx.");
1284+
}
1285+
12801286
static void reset() {
12811287
RtxOption<bool>::resetOptions();
12821288
}

0 commit comments

Comments
 (0)