@@ -259,20 +259,33 @@ namespace dxvk {
259259 }
260260
261261 const GenericValue& RtxOptionImpl::getGenericValue (const ValueType valueType) const {
262+ static const GenericValue dummyValue {};
262263 if (valueType == ValueType::DefaultValue) {
264+ if (optionLayerValueQueue.size () == 0 ) {
265+ Logger::err (" Empty option layer queue. The default value of option: " + std::string (name) + " is NOT properly set." );
266+ return dummyValue;
267+ }
263268 return optionLayerValueQueue.at (0 ).value ;
264269 } else if (valueType == ValueType::PendingValue) {
270+ if (optionLayerValueQueue.size () > 0 && optionLayerValueQueue.begin ()->second .priority != RtxOptionLayer::s_runtimeOptionLayerPriority) {
271+ Logger::err (" Failed to get runtime layer. The pending value of option: " + std::string (name) + " is missing." );
272+ return dummyValue;
273+ }
265274 return optionLayerValueQueue.begin ()->second .value ;
266275 } else if (valueType == ValueType::Value) {
267276 return resolvedValue;
268277 } else {
269278 Logger::warn (" [RTX Option]: Unknown generic value type." );
270- static const GenericValue dummyValue {};
271279 return dummyValue;
272280 }
273281 }
274282
275283 GenericValue& RtxOptionImpl::getGenericValue (const ValueType valueType) {
284+ // Insert runtime layer if it's missing and user request runtime changes.
285+ if (optionLayerValueQueue.size () > 0 && optionLayerValueQueue.begin ()->second .priority != RtxOptionLayer::s_runtimeOptionLayerPriority) {
286+ insertEmptyOptionLayer (RtxOptionLayer::s_runtimeOptionLayerPriority, 1 .0f , 1 .0f );
287+ }
288+
276289 // Reuse the const overload to avoid duplicating switch logic.
277290 // const_cast is safe here because we are returning a non-const reference
278291 // only when called on a non-const RtxOptionImpl instance.
@@ -471,8 +484,8 @@ namespace dxvk {
471484 clampValue (valueType);
472485
473486 if (valueType == ValueType::PendingValue) {
474- // If reading into the pending value, need to mark the option as dirty so it gets copied to the value at the end of the frame.
475- // markDirty();
487+ // If reading into the pending value, need to mark the option as dirty so it gets resolved to the value at the end of the frame.
488+ markDirty ();
476489 } else if (valueType == ValueType::Value) {
477490 // If reading into the value, need to immediately copy to the pending value so they stay in sync.
478491 copyValue (resolvedValue, getGenericValue (ValueType::PendingValue));
@@ -548,6 +561,7 @@ namespace dxvk {
548561 void RtxOptionImpl::insertEmptyOptionLayer (const uint32_t priority, const float blendStrength, const float blendStrengthThreshold) {
549562 GenericValue optionLayerValue = createGenericValue (type);
550563 const PrioritizedValue newValue (optionLayerValue, priority, blendStrength, blendStrengthThreshold);
564+
551565 auto [it, inserted] = optionLayerValueQueue.emplace (priority, newValue);
552566 if (!inserted) {
553567 Logger::warn (" [RTX Option]: Duplicate priority " + std::to_string (priority) + " ignored (only first kept)." );
0 commit comments