* Clean up DLSS DX12 inputs
- Refactored CreateFeature() and EvaluateFeature() into smaller functions with shared utilities and distinct code paths for internal OptiScaler and passthrough features.
- Added documentation to clarify internal implementation details and behavior required by the NGX API.
- Added more descriptive error messages.
- Fixed a potential memory leak in GetParameters(). Per the DLSS Programming Guide (310.5.0), this deprecated API requires the SDK to manage the lifetime of the returned parameter table, as legacy applications do not free this memory.
- Identified a memory management issue: NVNGX_Parameter tables are incorrectly handled in Allocate/Destroy and FeatureProvider. C-style free() is being used on tables allocated with 'new' and on native NGX tables, leading to memory leaks and undefined behavior. Using free() here is actually worse than just willfully leaking memory. This needs fixing.
* Fix: Correct NGX Parameter table lifetime and deallocation
Problem:
The previous implementation incorrectly used C-style free() on NVSDK_NGX_Parameter objects within the DLSS feature providers. This was unsafe for several reasons:
- Non-trivial types: These structs often contain internal data/tables that free() does not account for, bypassing necessary destructors.
- Ambiguous ownership: Tables were inconsistently sourced from internal allocations (OptiScaler), external NGX API calls, or legacy persistent pointers.
- Heap/Stack corruption: Using free() on memory managed by the NGX API or on stack-allocated memory from legacy GetParameters() calls. This risked immediate crashes or heap instability.
Solution:
Introduced a tagging system to explicitly track memory ownership and determine the correct deallocation strategy. When a destruction request is made, the system now checks the table's tag and acts accordingly:
1. InternPersistent: Internal OptiScaler tables for legacy APIs. Lifetime is managed by the SDK; these persist until process exit.
2. InternDynamic: Internal tables explicitly created/destroyed by the client. Now correctly freed using delete with a static_cast to the implementation type.
3. NVPersistent: Native NGX legacy tables. These are ignored as the native SDK manages their lifetime.
4. NVDynamic: Native NGX modern tables. These are now properly forwarded to the native NGX DestroyParameters() function.
* Start gathering unique string literals in header
- Started organizing string literals being used as unique identifiers for things like feature selection and parameter lookup into a dedicated header. Less error prone and actually works with intellisense.
- The actual usages of these strings have yet to be replaced, but I am using them for new code.
* Fix incorrect configurable FOV conversion in FSR
- The conversions for manually configured horizontal FOV to vertical FOV used in upscaling have been corrected to use the following formula: vFov = 2 * arctan( tan( hFov / 2 ) * ( h / w ) )
- Added convenience variables for global singletons to Eval functions to help readability
- Streamlined ffxResolveTypelessFormat usages. More readable.
* Update ffxResolveTypelessFormat usage
* Run clang formatting
* Fix potential NGX handle memory leak if device couldn't be acquired
Fixed a preexisting edge case that could cause the NGX handle to be leaked if the D3D12 device could not be acquired.
* Fix Vulkan upscaler typo and DX11 init error
- Vulkan: Correct default upscaler key from FSR 2.1 to FSR 2.2.
- DX11: Removed redundant table initialization in DLSS inputs caused by copy-paste error.
* Add NGX table reset check and remove old DLSSD check
- Added extra check in NGX table to preserve usage keys for custom tables.
- Fixed incorrect feature release log error
- Reran clang-format
- Removed old DLSSD check for root signature restore
- Removed GetIsDlssModuleInited() helper utility