@@ -2086,42 +2086,58 @@ namespace dxvk {
20862086 }
20872087#endif
20882088
2089- if (ImGui::CollapsingHeader (" Option Layers" )) {
2089+ if (IMGUI_ADD_TOOLTIP ( ImGui::CollapsingHeader (" Option Layers" ), " View what options are present in each layer, and alter the blend strength and threshold for them. " )) {
20902090 ImGui::Indent ();
2091+ static char optionLayerFilter[256 ] = " " ;
2092+ if (IMGUI_ADD_TOOLTIP (ImGui::CollapsingHeader (" Layer Controls" ), " Some utilities for controlling the option layers and display." )) {
2093+ ImGui::Indent ();
20912094
2092- if (IMGUI_ADD_TOOLTIP (ImGui::Button (" Disable Layers" ), " Reset all settings to Default." )) {
2093- for (auto & [unusedLayerKey, optionLayerPtr] : RtxOptionImpl::getRtxOptionLayerMap ()) {
2094- optionLayerPtr->requestEnabled (false );
2095+ if (IMGUI_ADD_TOOLTIP (ImGui::Button (" Disable Layers" ), " All optional layers will be disabled. The runtime and default layers will remain active." )) {
2096+ for (auto & [layerKey, optionLayerPtr] : RtxOptionImpl::getRtxOptionLayerMap ()) {
2097+ if (layerKey.priority != RtxOptionLayer::s_runtimeOptionLayerPriority && layerKey.priority != (uint32_t )RtxOptionLayer::SystemLayerPriority::Default) {
2098+ optionLayerPtr->requestEnabled (false );
2099+ }
2100+ }
20952101 }
2096- }
20972102
2098- ImGui::SameLine ();
2099- if (IMGUI_ADD_TOOLTIP (ImGui::Button (" Enable Layers" ), " Enable all option layers." )) {
2100- for (auto & [unusedLayerKey, optionLayerPtr] : RtxOptionImpl::getRtxOptionLayerMap ()) {
2101- optionLayerPtr->requestEnabled (true );
2103+ ImGui::SameLine ();
2104+ if (IMGUI_ADD_TOOLTIP (ImGui::Button (" Enable Layers" ), " Enable all option layers." )) {
2105+ for (auto & [unusedLayerKey, optionLayerPtr] : RtxOptionImpl::getRtxOptionLayerMap ()) {
2106+ optionLayerPtr->requestEnabled (true );
2107+ }
21022108 }
2103- }
21042109
2105- ImGui::Checkbox (" Override configs" , &RtxOptions::Option::overwriteConfigObject ());
2110+ // Filter for option layer contents
2111+ IMGUI_ADD_TOOLTIP (ImGui::InputText (" RtxOption Display Filter" , optionLayerFilter, IM_ARRAYSIZE (optionLayerFilter)),
2112+ " Filter options displayed in the Contents sections. Only options containing this text will be shown." );
2113+
2114+
2115+ ImGui::Checkbox (" Pause Graph Execution" , &GraphManager::pauseGraphUpdatesObject ());
2116+ if (ImGui::IsItemHovered ()) {
2117+ ImGui::SetTooltip (
2118+ " Many graphs set `enable`, `blendStrength`, and `blendThreshold` every frame.\n "
2119+ " Pausing the graph execution will allow controlling these values without interference." );
2120+ }
2121+ ImGui::Unindent ();
2122+ }
2123+ // Pre-compute lowercased filter once for efficiency
2124+ std::string filterLower = optionLayerFilter;
2125+ std::transform (filterLower.begin (), filterLower.end (), filterLower.begin (), ::tolower);
21062126
21072127 uint32_t optionLayerCounter = 1 ;
21082128 for (auto & [layerKey, optionLayerPtr] : RtxOptionImpl::getRtxOptionLayerMap ()) {
2109- // Runtime option layer priority is reserved for real-time user changes.
2110- // These layers should not be modified through the GUI.
2111- if (layerKey.priority != RtxOptionLayer::s_runtimeOptionLayerPriority) {
2112- RtxOptionLayer& optionLayer = *optionLayerPtr;
2113- ImGui::Dummy (ImVec2 (0 .0f , 5 .0f ));
2114- ImGui::Separator ();
2115- ImGui::Dummy (ImVec2 (0 .0f , 5 .0f ));
2129+ RtxOptionLayer& optionLayer = *optionLayerPtr;
21162130
2131+ std::string displayName;
2132+
2133+ if (layerKey.priority != RtxOptionLayer::s_runtimeOptionLayerPriority && layerKey.priority != (uint32_t )RtxOptionLayer::SystemLayerPriority::Default) {
21172134 const std::string optionLayerName = optionLayer.getName ();
2118-
2135+
21192136 // Process the display name
2120- std::string displayName;
21212137 // construct "rtx-remix/mods/" using OS appropriate separator
21222138 const std::string modsMarker = (std::filesystem::path (" rtx-remix" ) / " mods" / " " ).string ();
21232139 size_t modsPos = optionLayerName.find (modsMarker);
2124-
2140+
21252141 constexpr size_t kLongestPathLength = 30 ;
21262142 if (modsPos != std::string::npos) {
21272143 // Extract portion after "mods/"
@@ -2132,49 +2148,27 @@ namespace dxvk {
21322148 } else {
21332149 displayName = optionLayerName;
21342150 }
2151+ bool pendingEnabled = optionLayer.getPendingEnabled ();
2152+ float pendingStrength = optionLayer.getPendingBlendStrength ();
2153+ float pendingThreshold = optionLayer.getPendingBlendThreshold ();
21352154
21362155 const std::string optionLayerText = std::to_string (optionLayerCounter++) + " . " + displayName;
2137- const std::string optionLayerStrengthText = " Strength###Strength_" + displayName;
2138- const std::string optionLayerThresholdText = " Threshold###Threshold_" + displayName;
2156+ const bool isLayerActive = pendingEnabled && pendingStrength > pendingThreshold;
21392157
2140- // Use pending values for UI display and send requests on change
2141- bool pendingEnabled = optionLayer.getPendingEnabled ();
2142- if (IMGUI_ADD_TOOLTIP (ImGui::Checkbox (optionLayerText.c_str (), &pendingEnabled), optionLayer.getName ().c_str ())) {
2143- optionLayer.requestEnabled (pendingEnabled);
2144- }
2145-
2146- float pendingStrength = optionLayer.getPendingBlendStrength ();
2147- if (IMGUI_ADD_TOOLTIP (ImGui::SliderFloat (optionLayerStrengthText.c_str (), &pendingStrength, 0 .0f , 1 .0f ),
2148- " Adjusts the blending strength of this option layer (0 = off, 1 = full effect)." )) {
2149- optionLayer.requestBlendStrength (pendingStrength);
2158+ // Dim the header text when the layer is inactive
2159+ if (!isLayerActive) {
2160+ ImGui::PushStyleColor (ImGuiCol_Text, ImGui::GetStyleColorVec4 (ImGuiCol_TextDisabled));
21502161 }
21512162
2152- float pendingThreshold = optionLayer.getPendingBlendThreshold ( );
2153- if ( IMGUI_ADD_TOOLTIP ( ImGui::SliderFloat (optionLayerThresholdText. c_str (), &pendingThreshold, 0 . 0f , 1 . 0f ),
2154- " Sets the blending strength threshold for this option layer. Only applicable to non-float variables. The option is applied only when the blend strength exceeds this threshold. " ) ) {
2155- optionLayer. requestBlendThreshold (pendingThreshold );
2163+ bool headerOpen = IMGUI_ADD_TOOLTIP ( ImGui::CollapsingHeader (optionLayerText. c_str (), collapsingHeaderClosedFlags), optionLayer.getName (). c_str () );
2164+
2165+ if (!isLayerActive ) {
2166+ ImGui::PopStyleColor ( );
21562167 }
2157-
2158- // TODO: We need to move these part into a separate saving session
2159- // std::string layerType;
2160- // if (optionLayerName == "rtx.conf") {
2161- // layerType = "RTX";
2162- // } else if (optionLayerName == "quality.conf") {
2163- // layerType = "Quality";
2164- // } else if (optionLayerName == "user.conf") {
2165- // layerType = "Runtime";
2166- // } else {
2167- // layerType = optionLayerName;
2168- // }
2169- // const std::string optionLayerSavingText = RtxOptions::Option::saveToLayerConf() || displayName == "rtx.conf"?
2170- // "Save all settings from " + layerType + " layer to " + displayName :
2171- // "Save all settings from " + layerType + " layer to rtx.conf";
2172- // if (IMGUI_ADD_TOOLTIP(ImGui::Button(optionLayerSavingText.c_str()), "Save layer to rtx.conf")) {
2173- // RtxOptions::serializeOptionLayer(optionLayer, RtxOptions::Option::saveToLayerConf());
2174- // }
2175-
2176- if (ImGui::CollapsingHeader ((" Contents of " + displayName).c_str (), collapsingHeaderClosedFlags)) {
2168+
2169+ if (headerOpen) {
21772170 ImGui::Indent ();
2171+
21782172 const std::string priorityText = " Priority: " + std::to_string (optionLayer.getPriority ());
21792173 ImGui::Text (priorityText.c_str ());
21802174 if (ImGui::IsItemHovered ()) {
@@ -2184,9 +2178,104 @@ namespace dxvk {
21842178 " If a layer's blendWeight is not 1 and the option is a float or Vector type,\n "
21852179 " then the values will be calculated as LERP(previousValue, layerValue, blendWeight)." );
21862180 }
2187- for (const auto & option : optionLayer.getConfig ().getOptions ()) {
2188- const std::string optionText = option.first + " =" + option.second ;
2189- ImGui::TextWrapped (optionText.c_str ());
2181+
2182+ const std::string optionLayerEnabledText = " Enabled###Enabled_" + displayName;
2183+ const std::string optionLayerStrengthText = " Strength###Strength_" + displayName;
2184+ const std::string optionLayerThresholdText = " Threshold###Threshold_" + displayName;
2185+ const std::string optionLayerContentsText = " Contents###Contents_" + displayName;
2186+
2187+ // Use pending values for UI display and send requests on change
2188+ if (IMGUI_ADD_TOOLTIP (ImGui::Checkbox (optionLayerEnabledText.c_str (), &pendingEnabled), " Check to enable the option layer. Uncheck to disable it." )) {
2189+ optionLayer.requestEnabled (pendingEnabled);
2190+ }
2191+
2192+ if (IMGUI_ADD_TOOLTIP (ImGui::SliderFloat (optionLayerStrengthText.c_str (), &pendingStrength, 0 .0f , 1 .0f ),
2193+ " Adjusts the blending strength of this option layer (0 = off, 1 = full effect)." )) {
2194+ optionLayer.requestBlendStrength (pendingStrength);
2195+ }
2196+
2197+ if (IMGUI_ADD_TOOLTIP (ImGui::SliderFloat (optionLayerThresholdText.c_str (), &pendingThreshold, 0 .0f , 1 .0f ),
2198+ " Sets the blending strength threshold for this option layer. Only applicable to non-float variables.\n "
2199+ " The option is applied only when the blend strength exceeds this threshold." )) {
2200+ optionLayer.requestBlendThreshold (pendingThreshold);
2201+ }
2202+
2203+ if (ImGui::CollapsingHeader (optionLayerContentsText.c_str (), collapsingHeaderClosedFlags)) {
2204+ ImGui::Indent ();
2205+ for (const auto & option : optionLayer.getConfig ().getOptions ()) {
2206+ // Apply filter if one is set
2207+ if (!filterLower.empty ()) {
2208+ std::string optionLower = option.first ;
2209+ std::transform (optionLower.begin (), optionLower.end (), optionLower.begin (), ::tolower);
2210+ if (optionLower.find (filterLower) == std::string::npos) {
2211+ continue ;
2212+ }
2213+ }
2214+ const std::string optionText = option.first + " =" + option.second ;
2215+ ImGui::TextWrapped (optionText.c_str ());
2216+ }
2217+ ImGui::Unindent ();
2218+ }
2219+ ImGui::Unindent ();
2220+ }
2221+ } else {
2222+ // Runtime and default option layers don't have configs in the same way as the other layers, so print them differently
2223+ // The blend and enabled settings for these layers should not be modified through the GUI.
2224+ bool headerOpen = false ;
2225+ if (layerKey.priority == RtxOptionLayer::s_runtimeOptionLayerPriority) {
2226+ displayName = " runtime layer" ;
2227+ const std::string optionLayerText = std::to_string (optionLayerCounter++) + " . user.conf and runtime changes" ;
2228+ headerOpen = IMGUI_ADD_TOOLTIP (ImGui::CollapsingHeader (optionLayerText.c_str (), collapsingHeaderClosedFlags),
2229+ " This layer is initialized from user.conf, but includes any options that are changed at runtime (either through the GUI, the API, or when applying presets)." );
2230+ } else {
2231+ displayName = " default" ;
2232+ const std::string optionLayerText = std::to_string (optionLayerCounter++) + " . default" ;
2233+ headerOpen = IMGUI_ADD_TOOLTIP (ImGui::CollapsingHeader (optionLayerText.c_str (), collapsingHeaderClosedFlags),
2234+ " This is the default setting for each option, as can be seen in RtxOptions.md." );
2235+ }
2236+ if (headerOpen) {
2237+ ImGui::Indent ();
2238+ if (layerKey.priority == RtxOptionLayer::s_runtimeOptionLayerPriority) {
2239+ ImGui::Text (" Priority: MAX" );
2240+ if (ImGui::IsItemHovered ()) {
2241+ ImGui::SetTooltip (" Highest possible priority - any changes made in this layer will apply fully regardless of options in other layers.\n "
2242+ " The actual priority value is 4,294,967,295, or uint32's max value." );
2243+ }
2244+ } else {
2245+ ImGui::Text (" Priority: 0" );
2246+ if (ImGui::IsItemHovered ()) {
2247+ ImGui::SetTooltip (" Lowest possible priority - every other layer will be applied on top of this layer." );
2248+ }
2249+ }
2250+ const std::string optionLayerContentsText = " Contents###Contents_" + displayName;
2251+
2252+ if (ImGui::CollapsingHeader (optionLayerContentsText.c_str (), collapsingHeaderClosedFlags)) {
2253+ ImGui::Indent ();
2254+
2255+ // For runtime layer, iterate through all options and find those with runtime layer values
2256+ // (the runtime layer's config is empty since values are stored in each option's optionLayerValueQueue)
2257+ for (const auto & [optionHash, optionPtr] : RtxOptionImpl::getGlobalRtxOptionMap ()) {
2258+ const RtxOptionImpl& rtxOption = *optionPtr;
2259+ // Check if this option has a runtime layer value (first entry has runtime priority)
2260+ if (!rtxOption.optionLayerValueQueue .empty () &&
2261+ rtxOption.optionLayerValueQueue .begin ()->first .priority == optionLayer.getPriority ()) {
2262+ const std::string fullName = rtxOption.getFullName ();
2263+
2264+ // Apply filter if one is set
2265+ if (!filterLower.empty ()) {
2266+ std::string optionLower = fullName;
2267+ std::transform (optionLower.begin (), optionLower.end (), optionLower.begin (), ::tolower);
2268+ if (optionLower.find (filterLower) == std::string::npos) {
2269+ continue ;
2270+ }
2271+ }
2272+
2273+ const std::string optionText = fullName + " =" +
2274+ rtxOption.genericValueToString (rtxOption.optionLayerValueQueue .begin ()->second .value );
2275+ ImGui::TextWrapped (optionText.c_str ());
2276+ }
2277+ }
2278+ ImGui::Unindent ();
21902279 }
21912280 ImGui::Unindent ();
21922281 }
0 commit comments