Skip to content

chore(upscaling): simplify interop and upscale methods#1514

Merged
doodlum merged 24 commits into
devfrom
upscaler-downgrade
Sep 23, 2025
Merged

chore(upscaling): simplify interop and upscale methods#1514
doodlum merged 24 commits into
devfrom
upscaler-downgrade

Conversation

@doodlum
Copy link
Copy Markdown
Collaborator

@doodlum doodlum commented Sep 23, 2025

Summary by CodeRabbit

  • New Features

    • Adds AMD FidelityFX FSR3 frame generation and upscaling support.
  • Refactor

    • Unified upscaling pipeline and settings; Intel XeSS removed, NVIDIA DLSS retained; default upscaler set to TAA.
  • Bug Fixes / Image Quality

    • Reactive and transparency-composition masks now always generated; shader dispatch bounds checking added.
  • Performance

    • Sampler anisotropy capped to improve performance and stability.
  • Chores

    • FidelityFX SDK integrated into the build.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 23, 2025

Warning

Rate limit exceeded

@doodlum has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 37 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 8c720eb and 073039b.

📒 Files selected for processing (3)
  • src/Features/Upscaling.cpp (16 hunks)
  • src/Features/Upscaling/FidelityFX.cpp (6 hunks)
  • src/Features/Upscaling/FidelityFX.h (2 hunks)

Walkthrough

Adds FidelityFX-SDK as a git submodule and CMake include; integrates FSR3 via a DX11-based path; removes XeSS and public FFX upscale headers; changes DX11/DX12 interop and DX12 swapchain device/queue handling; unifies upscaling logic and Streamline presets; adds sampler-state hook clamping MaxAnisotropy.

Changes

Cohort / File(s) Summary
Build integration: FidelityFX-SDK
\.gitmodules, CMakeLists.txt, cmake/FidelityFX-SDK.cmake, extern/FidelityFX-SDK
Add FidelityFX-SDK submodule and CMake include; configure FSR/FSR3 DX11 backend (disable DX12/VK/ALL), enable auto shader compile, add sdk subdir, link FSR backends.
FidelityFX public API headers removed
include/FidelityFX/upscalers/include/ffx_upscale.h, include/FidelityFX/upscalers/include/ffx_upscale.hpp
Delete C and C++ Upscale API headers and all related public enums, macros, structs, and wrapper specializations.
FSR3 DX11 integration & API changes
src/Features/Upscaling/FidelityFX.h, src/Features/Upscaling/FidelityFX.cpp
Replace DX12 upscaler context with FfxFsr3Context and DX11 dispatch; add ffxGetResource helper; change Upscale/GetInputResolutionScale signatures to use ID3D11Resource and DX11-based lifecycle (ffxFsr3ContextCreate/Destroy).
XeSS removal
src/Features/Upscaling/XeSS.h, src/Features/Upscaling/XeSS.cpp
Remove XeSS header and implementation, DLL loading, function-pointer typedefs, context lifecycle, versioning, GetInputResolutionScale, and Upscale.
DX12/DX11 interop & swapchain changes
src/Features/Upscaling/DX12SwapChain.h, src/Features/Upscaling/DX12SwapChain.cpp
Add ID3D12Device and ID3D12CommandQueue members; rename InitializeD3D12Resources → CreateD3D12Device(IDXGIAdapter*); add CreateSharedResources(); create/open shared D3D11 textures and open them in D3D12 for interop; use local queue for present/sync.
Upscaling core settings & public API
src/Features/Upscaling.h, src/Features/Upscaling.cpp
Remove XeSS enum (kXESS) and upscaleMethodNoDLSS; change default upscaleMethod to TAA; remove UpdateSharedResources and multiple shared-resource members; simplify UI/preset caching and per-backend branching.
Streamline API and presets
src/Features/Upscaling/Streamline.h, src/Features/Upscaling/Streamline.cpp
Remove DLSS preset parameter from Streamline::Upscale; hard-code internal preset mapping; Upscale now takes four ID3D11Resource* parameters.
Shader unconditional logic
features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl
Make TransparencyCompositionMask declaration and several DLSS/XeSS-guarded calculations unconditional; add early-dispatch bounds check.
Hooks: sampler-state clamp
src/Hooks.cpp
Add ID3D11Device_CreateSamplerState thunk that clones the D3D11_SAMPLER_DESC, clamps MaxAnisotropy to 8, and install detour during device init.
State mip-bias tweak
src/State.cpp
Cache upscale method locally and compute mip-bias as log2(renderSize.x / screenSize.x) with an extra -1.0f only when method == DLSS.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Game
  participant Upscaling
  participant DX12SC as DX12SwapChain
  participant D3D11
  participant D3D12
  participant FFX as FidelityFX (FSR3)
  participant SL as Streamline (DLSS)

  Game->>Upscaling: Request upscale(method, resources)
  Upscaling->>DX12SC: CreateD3D12Device() / CreateSharedResources()
  DX12SC->>D3D11: Create shared D3D11 textures (depth/motion)
  D3D11-->>DX12SC: Return shared HANDLEs
  DX12SC->>D3D12: OpenSharedHandle(HANDLE) -> ID3D12Resource

  alt method == DLSS
    Upscaling->>SL: Upscale(ID3D11Resources...)
    SL-->>Upscaling: Upscaled output
  else method == FSR3
    Upscaling->>FFX: Upscale(ID3D11Resources...)
    FFX-->>Upscaling: Upscaled output
  else
    Upscaling-->>Game: TAA / bypass
  end

  Upscaling-->>Game: Present frame
Loading
sequenceDiagram
  autonumber
  participant D3D11
  participant DXGI
  participant DX12SC as DX12SwapChain
  participant D3D12

  D3D11->>DXGI: CreateTexture2D(shared)
  DXGI-->>DX12SC: Provide HANDLE
  DX12SC->>D3D12: OpenSharedHandle(HANDLE) -> ID3D12Resource
  D3D12-->>DX12SC: WrappedResource stored
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • alandtse
  • jiayev

Poem

A rabbit hopped in with an SDK so bright,
I swapped out XeSS and let FSR take flight.
Shared handles whisper between D3D friends,
Samplers capped, shaders sing — fewer conditional bends.
Hooray — the upscales hop, all snug and light! 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title is concise, one sentence, and accurately summarizes the main intent of the changeset—simplifying upscaling and interop code (e.g., XeSS removal, FidelityFX integration, DX11/DX12 resource and API simplifications)—so a reviewer scanning history can understand the primary change.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

pre-commit-ci Bot and others added 2 commits September 23, 2025 02:07
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 23, 2025

Using provided base ref: b3129e2
Using base ref: b3129e2
Base commit date: 2025-09-22T21:30:57+01:00 (Monday, September 22, 2025 09:30 PM)

Actionable Suggestions

  • Hair Specular: Action required; Needs version bump to 1-0-2

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/Features/Upscaling/DX12SwapChain.cpp (1)

87-91: Adopt smart pointers for wrapped resources.

Match the header refactor: use std::make_unique to avoid leaks.

- swapChainBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), upscaling.sharedD3D12Device.get());
+ swapChainBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), upscaling.sharedD3D12Device.get());
 
- uiBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), upscaling.sharedD3D12Device.get());
+ uiBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), upscaling.sharedD3D12Device.get());
src/Features/Upscaling.cpp (1)

1238-1241: Clear the same constant buffer slot you set (slot 0), not slot 7.

You bind the CB to CS slot 0 but unbind slot 7, leaving slot 0 live.

Apply this diff:

- ID3D11Buffer* nullBuffer = nullptr;
- context->CSSetConstantBuffers(7, 1, &nullBuffer);
+ ID3D11Buffer* nullBuffer = nullptr;
+ context->CSSetConstantBuffers(0, 1, &nullBuffer);
🧹 Nitpick comments (12)
features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl (2)

18-21: Avoid mixed casts of TrueSamplingDim; compute once and reuse.

Reduces float→int rounding drift and duplicated casts; makes bounds checks consistent.

 [numthreads(8, 8, 1)] void main(uint3 dispatchID : SV_DispatchThreadID) {
 	// Early exit if dispatch thread is outside true sampling dimensions
-	if (any(dispatchID.xy >= uint2(TrueSamplingDim)))
+	const uint2 samplingDimU = (uint2)TrueSamplingDim;
+	const int2  samplingDimI = (int2)samplingDimU;
+	if (any(dispatchID.xy >= samplingDimU))
 		return;
@@
-			// Skip samples outside true sampling dimensions
-			if (any(samplePos < 0) || any(samplePos >= int2(TrueSamplingDim)))
+			// Skip samples outside true sampling dimensions
+			if (any(samplePos < 0) || any(samplePos >= samplingDimI))
 				continue;

Also applies to: 39-41


33-60: Optional perf: tile 5x5 neighborhood with groupshared memory.

25 texture fetches/thread (Depth/TAAMask/MVs) per 8x8 group is costly. Load a (8+4)x(8+4) tile into groupshared once, then reuse for the 5x5 scan to cut bandwidth.

CMakeLists.txt (1)

52-52: Double‑check XeSS removal and module ordering.

  • If XeSS is being removed, drop include(XeSS-SDK) (Line 48) to avoid pulling unused targets.
  • Including FidelityFX-SDK here is fine as long as ${PROJECT_NAME} is already defined (it appears so since you call target_compile_definitions at Line 54). If not, move this include() below the target creation.
.gitmodules (1)

7-9: Pin the FidelityFX-SDK submodule to a trusted commit/branch.

Track a specific tag/commit (or set branch = <stable-branch>) to avoid supply‑chain drift and unexpected build changes. Consider using the upstream AMD GPUOpen repo unless you explicitly need the MapleHinata fork.

src/Features/Upscaling/DX12SwapChain.h (1)

115-117: Clarify lifecycle: who calls CreateSharedResources() and how often?

Guard against duplicate allocations and call it once when sizes/formats change. Consider adding idempotence and resize handling.

src/Features/Upscaling/Streamline.cpp (1)

293-298: Hard‑coding all DLSS presets to DLAA preset — confirm intent.

Overriding every preset to ePresetK removes quality/perf differentiation. If this was to stabilize output, gate behind a setting or map per‑mode.

src/Features/Upscaling/DX12SwapChain.cpp (2)

400-416: Shared depth/mvec resources: set appropriate bind formats/flags and use smart pointers.

  • Depth: use a float SRV resource; if you only need SRV, R32_FLOAT + D3D11_BIND_SHADER_RESOURCE is fine. If you need DSV + SRV, create typeless and views accordingly (requires WrappedResource to accept view format overrides).
  • Motion vectors: ensure D3D11_BIND_SHADER_RESOURCE (and UNORDERED_ACCESS if you write).
- texDesc.Format = DXGI_FORMAT_R32_FLOAT;
- depthBufferShared12 = new WrappedResource(texDesc, d3d11Device.get(), upscaling.sharedD3D12Device.get());
+ texDesc.Format = DXGI_FORMAT_R32_FLOAT;
+ texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ texDesc.MipLevels = 1;
+ texDesc.ArraySize = 1;
+ depthBufferShared12 = std::make_unique<WrappedResource>(texDesc, d3d11Device.get(), upscaling.sharedD3D12Device.get());
@@
- motionVector.texture->GetDesc(&texDesc);
- motionVectorBufferShared12 = new WrappedResource(texDesc, d3d11Device.get(), upscaling.sharedD3D12Device.get());
+ motionVector.texture->GetDesc(&texDesc);
+ texDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
+ motionVectorBufferShared12 = std::make_unique<WrappedResource>(texDesc, d3d11Device.get(), upscaling.sharedD3D12Device.get());

Add guards so repeated calls don’t leak:

if (!depthBufferShared12) { /* create */ }
if (!motionVectorBufferShared12) { /* create */ }

29-31: Leak: dxgiFactory is never released.

Use winrt::com_ptr<IDXGIFactory4> (or Microsoft::WRL::ComPtr) instead of a raw pointer.

src/Features/Upscaling.h (1)

159-161: Remove XeSS from feature summary for consistency.

UI and code removed XeSS; summary still lists it. Update the string table.

Apply this diff:

-            { "DLSS (Deep Learning Super Sampling) support",
-                "FSR (FidelityFX Super Resolution) support",
-                "XeSS (Intel Xe Super Sampling) support",
-                "TAA (Temporal Anti-Aliasing) support",
+            { "DLSS (Deep Learning Super Sampling) support",
+                "FSR (FidelityFX Super Resolution) support",
+                "TAA (Temporal Anti-Aliasing) support",
                 "Frame generation for supported systems" }
src/Features/Upscaling.cpp (3)

86-87: Create the shared D3D12 device only when proxying is enabled.

This avoids unnecessary D3D12 initialization on systems where FG/proxy is off.

Apply this diff:

- upscaling.CreateSharedD3D12Device(pAdapter);
+ if (shouldProxy) {
+   upscaling.CreateSharedD3D12Device(pAdapter);
+ }

152-171: Fix mode list vs range mismatch in UI.

You always push FSR/DLSS labels but gate the slider’s max via feature flags, which can desync the displayed label. Build the list conditionally and derive the slider max from it.

Apply this diff:

- std::vector<std::string> upscaleModes = { "None", "TAA" };
-
- std::string fsrLabel = "AMD FSR 3.1";
- upscaleModes.push_back(fsrLabel);
-
- std::string dlssLabel = "NVIDIA DLSS";
- upscaleModes.push_back(dlssLabel);
+ std::vector<std::string> upscaleModes = { "None", "TAA" };
+ if (true /* FSR always available */) {
+   upscaleModes.emplace_back("AMD FSR 3.1");
+ }
+ if (featureDLSS) {
+   upscaleModes.emplace_back("NVIDIA DLSS");
+ }
@@
- uint32_t availableModes = 1;  // Start with TAA
- if (featureFSR)
-   availableModes = 2;  // Add FSR
- if (featureDLSS)
-   availableModes = 3;  // Add DLSS if available
+ uint32_t availableModes = static_cast<uint32_t>(upscaleModes.size() - 1);

785-794: Dead code: NIS texture descriptors are prepared but unused.

Either remove these descriptors or create the texture; currently they’re no-ops.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b3129e2 and 286a7af.

⛔ Files ignored due to path filters (1)
  • features/Upscaling/Shaders/Upscaling/FidelityFX/amd_fidelityfx_upscaler_dx12.dll is excluded by !**/*.dll
📒 Files selected for processing (17)
  • .gitmodules (1 hunks)
  • CMakeLists.txt (1 hunks)
  • cmake/FidelityFX-SDK.cmake (1 hunks)
  • extern/FidelityFX-SDK (1 hunks)
  • features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl (1 hunks)
  • include/FidelityFX/upscalers/include/ffx_upscale.h (0 hunks)
  • include/FidelityFX/upscalers/include/ffx_upscale.hpp (0 hunks)
  • src/Features/Upscaling.cpp (12 hunks)
  • src/Features/Upscaling.h (3 hunks)
  • src/Features/Upscaling/DX12SwapChain.cpp (2 hunks)
  • src/Features/Upscaling/DX12SwapChain.h (2 hunks)
  • src/Features/Upscaling/FidelityFX.cpp (4 hunks)
  • src/Features/Upscaling/FidelityFX.h (2 hunks)
  • src/Features/Upscaling/Streamline.cpp (2 hunks)
  • src/Features/Upscaling/Streamline.h (1 hunks)
  • src/Features/Upscaling/XeSS.cpp (0 hunks)
  • src/Features/Upscaling/XeSS.h (0 hunks)
💤 Files with no reviewable changes (4)
  • src/Features/Upscaling/XeSS.h
  • src/Features/Upscaling/XeSS.cpp
  • include/FidelityFX/upscalers/include/ffx_upscale.hpp
  • include/FidelityFX/upscalers/include/ffx_upscale.h
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Features/Upscaling/Streamline.h
  • src/Features/Upscaling/DX12SwapChain.cpp
  • src/Features/Upscaling/DX12SwapChain.h
  • features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl
  • src/Features/Upscaling/FidelityFX.h
  • src/Features/Upscaling.h
  • src/Features/Upscaling/Streamline.cpp
  • src/Features/Upscaling.cpp
  • src/Features/Upscaling/FidelityFX.cpp
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Features/Upscaling/Streamline.h
  • src/Features/Upscaling/DX12SwapChain.cpp
  • src/Features/Upscaling/DX12SwapChain.h
  • src/Features/Upscaling/FidelityFX.h
  • src/Features/Upscaling.h
  • src/Features/Upscaling/Streamline.cpp
  • src/Features/Upscaling.cpp
  • src/Features/Upscaling/FidelityFX.cpp
features/*/Shaders/**/*.{hlsl,hlsli,fx,fxh}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

features/*/Shaders/**/*.{hlsl,hlsli,fx,fxh}: Place all feature shaders under features/YourFeature/Shaders/
Avoid GPU register/buffer conflicts in HLSL; verify register usage (e.g., with hlslkit buffer scanning)

Files:

  • features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Validate shader compilation (Flatrim, .github/configs/shader-validation.yaml)
  • GitHub Check: Build plugin and addons
  • GitHub Check: Validate shader compilation (VR, .github/configs/shader-validation-vr.yaml)
🔇 Additional comments (16)
features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl (1)

9-17: Confirm root signature / CPU bindings match FSR3 interop: Reactive -> u0, TransparencyComposition -> u1, MotionVectorOutput -> u2.

EncodeTexturesCS.hlsl declares TAAMask:t0, NormalsWaterMask:t1, MotionVectorMask:t2, DepthMask:t3 and writes ReactiveMask:u0, TransparencyCompositionMask:u1, MotionVectorOutput:u2 (features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl — decls lines 9–17; writes lines 62–68). No C/C++ descriptor bindings or call sites for these UAVs were found in the repository search output; verify the CPU-side descriptor table/root signature and the FSR3/FFX consumer expect separate masks (not combined) and that t0–t3 / u0–u2 align with your interop.

extern/FidelityFX-SDK (4)

1-1: Pin extern/FidelityFX-SDK to a signed/tagged release or add provenance.

extern/FidelityFX-SDK is checked out at commit 8138c9d (8138c9dc086154706643a03def91f3d01d391cd0) with no exact tag; gpg was not available in the verification environment so the commit signature could not be verified. Either switch the submodule to an upstream tagged+GPG-signed release, or add a provenance note (commit hash, commit date, upstream tag equivalence) and enable commit signature verification in CI (re-run the provided tag check with gpg installed).


1-1: CMake integration sanity.

Confirm CMake only builds needed DX11 targets (ffx_backend_dx11_x64, ffx_fsr3_x64), treats SDK includes as SYSTEM to suppress warnings, and disables unused APIs to keep build lean.


1-1: Ensure CI handles Git LFS and submodules.

Found git submodule instructions in extern/FidelityFX-SDK/sdk/tools/ffx_shader_compiler/libs/SPIRV-Reflect/README.md (lines ~94–95) but no .github/workflows to verify CI. Add CI steps to run git lfs install && git lfs fetch && git lfs checkout and git submodule update --init --recursive, or use actions/checkout with submodules: true and lfs: true.


1-1: Confirm packaging includes FidelityFX SDK license & third‑party notices

  • Files exist in the submodule: extern/FidelityFX-SDK/LICENSE.txt, extern/FidelityFX-SDK/Third_party_notices.txt, extern/FidelityFX-SDK/docs/license.md (plus vendor LICENSEs under framework/ and sdk/).
  • Action: ensure these files are copied into any distributed artifacts and/or aggregated in the repo's THIRD_PARTY/NOTICE, and surface any FSR3-specific licensing/terms in packaging and About dialogs.
src/Features/Upscaling/Streamline.cpp (1)

299-301: Fix use of undeclared result (referenced before declaration)

File: src/Features/Upscaling/Streamline.cpp (reported lines ~299–301) — repository search did not find this file; confirm path. Apply one of the fixes below:

- if (SL_FAILED(result, slDLSSSetOptions(viewport, dlssOptions))) {
-   logger::critical("[Streamline] Could not enable DLSS");
- }
+ if (slDLSSSetOptions(viewport, dlssOptions) != sl::Result::eOk) {
+   logger::critical("[Streamline] Could not enable DLSS");
+ }

Also fix earlier uses of SL_FAILED(res, ...) by declaring a result variable before use or by inlining the comparison similarly.

cmake/FidelityFX-SDK.cmake (1)

10-15: Link the DX12 backend using the SDK's DX12 target (amd_fidelityfx_dx12), not ffx_backend_dx12_x64.
ffx_backend_dx12_x64 is not an official import target in current FidelityFX‑SDK releases; link the SDK-provided DX12 library/target (e.g., amd_fidelityfx_dx12) or use the SDK's DX12 interface (ffxGetInterfaceDX12 / ffxGetDeviceDX12). File: cmake/FidelityFX-SDK.cmake (lines 10–15)

Likely an incorrect or invalid review comment.

src/Features/Upscaling/Streamline.h (1)

77-77: Signature change: verify all call sites updated.
Automated search found no occurrences of Upscale or Streamline::Upscale in the repo — confirm every invocation was migrated after removing the preset and updated to the new 4-argument signature. If any remain, update them to the new signature or restore backward compatibility.

src/Features/Upscaling/FidelityFX.h (2)

6-9: Confirm DX11/DX12 header coexistence is intentional.

You now include DX11 host backend and FSR3 host headers alongside DX12 API headers. If this translation unit is consumed by DX12-only TU(s) too, that’s fine; otherwise, consider pushing DX12-only includes into the cpp to reduce compile surface.


47-50: DX11 Upscale entrypoint: document requirements on resources.

The new signature accepts ID3D11Resource* for in/out and masks; ensure call sites bind UAV/SRV-capable textures and that depth is sourced internally as intended.

src/Features/Upscaling.h (2)

51-51: Default method to TAA: OK.

Matches UI initialization and clamping paths.


152-152: Comment update is fine.

Shared D3D12 resources relocation to DX12SwapChain aligns with interop changes.

src/Features/Upscaling.cpp (2)

127-148: hk_D3D11CreateDeviceAndSwapChainUpscaling: OK overall.

Hook order, proxy decisioning, and backend upgrade flow look sound.

Please sanity-check fullscreen + VR paths with proxy disabled.


200-207: Preset label logic is fine.

The DLSS/FSR label switch and clamped preset index are correct.

src/Features/Upscaling/FidelityFX.cpp (2)

256-264: In‑place color I/O: verify support.

Input color and upscaleOutput point to the same resource. Confirm FSR3 DX11 path allows aliasing; otherwise provide a distinct output UAV.


131-153: FrameGen prepare: OK.

DX12 command list selection and resource wiring match the interop paths.

Comment thread cmake/FidelityFX-SDK.cmake
Comment thread extern/FidelityFX-SDK
Comment thread features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl
Comment thread src/Features/Upscaling.cpp Outdated
Comment thread src/Features/Upscaling/DX12SwapChain.cpp
Comment thread src/Features/Upscaling/FidelityFX.cpp
Comment thread src/Features/Upscaling/FidelityFX.cpp
Comment thread src/Features/Upscaling/FidelityFX.cpp
Comment thread src/Features/Upscaling/FidelityFX.cpp
Comment thread src/Features/Upscaling/FidelityFX.h
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
src/Features/Upscaling/DX12SwapChain.h (1)

116-118: Lifecycle: add DestroySharedResources() and call on resize/teardown.

CreateSharedResources() needs a paired destroy to free/recreate on ResizeBuffers and shutdown.

Do you want a small helper that resets the four unique_ptrs and is called from ResizeBuffers?

src/Features/Upscaling/DX12SwapChain.cpp (2)

33-55: Avoid leaking IDXGIFactory4; use com_ptr.

dxgiFactory is a raw pointer with no Release(). Use winrt::com_ptr for RAII.

Apply this diff:

-    IDXGIFactory4* dxgiFactory;
-    DX::ThrowIfFailed(adapter->GetParent(IID_PPV_ARGS(&dxgiFactory)));
+    winrt::com_ptr<IDXGIFactory4> dxgiFactory;
+    DX::ThrowIfFailed(adapter->GetParent(IID_PPV_ARGS(dxgiFactory.put())));
@@
-    ffxSwapChainDesc.dxgiFactory = dxgiFactory;
+    ffxSwapChainDesc.dxgiFactory = dxgiFactory.get();

402-417: Ensure required bind flags for depth/motion shared RTs.

Depth copy needs an RTV; enforce flags explicitly and add names for debugging.

Apply this diff:

@@ void DX12SwapChain::CreateSharedResources()
-    main.texture->GetDesc(&texDesc);
-    texDesc.Format = DXGI_FORMAT_R32_FLOAT;
-    depthBufferShared12 = new WrappedResource(texDesc, d3d11Device.get(), d3d12Device.get());
+    main.texture->GetDesc(&texDesc);
+    texDesc.Format = DXGI_FORMAT_R32_FLOAT;
+    texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+    depthBufferShared12 = std::make_unique<WrappedResource>(texDesc, d3d11Device.get(), d3d12Device.get());
@@
-    motionVector.texture->GetDesc(&texDesc);
-    motionVectorBufferShared12 = new WrappedResource(texDesc, d3d11Device.get(), d3d12Device.get());
+    motionVector.texture->GetDesc(&texDesc);
+    motionVectorBufferShared12 = std::make_unique<WrappedResource>(texDesc, d3d11Device.get(), d3d12Device.get());

Optionally set debug names via SetPrivateData for easier PIX captures.

src/Features/Upscaling.cpp (1)

150-169: FSR availability hardcoded to true; derive from actual SDK load.

UI may expose FSR when FidelityFX loader/DLLs are missing. Query a real availability flag instead.

Apply this diff (assuming a helper exists/added):

-    bool featureDLSS = streamline.featureDLSS;
-    bool featureFSR = true;  // FSR is always available
+    bool featureDLSS = streamline.featureDLSS;
+    bool featureFSR = FidelityFX::module != nullptr; // or fidelityFX.IsUpscalerAvailable()
src/Features/Upscaling.h (2)

11-37: Docs/UI text still mention XeSS.

XeSS was removed in this PR; update summary strings/comments to avoid misleading users.

Apply this diff:

- * @brief Provides upscaling functionality including DLSS, FSR, XeSS and TAA.
+ * @brief Provides upscaling functionality including DLSS, FSR and TAA.
@@
-            { "DLSS (Deep Learning Super Sampling) support",
-                "FSR (FidelityFX Super Resolution) support",
-                "XeSS (Intel Xe Super Sampling) support",
+            { "DLSS (Deep Learning Super Sampling) support",
+                "FSR (FidelityFX Super Resolution) support",
                 "TAA (Temporal Anti-Aliasing) support",
                 "Frame generation for supported systems" }

83-86: Minor nit: type/initializer mismatch.

double refreshRate = 0.0f; → use 0.0 to match type.

-    double refreshRate = 0.0f;
+    double refreshRate = 0.0;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09986bc and 0f7c646.

📒 Files selected for processing (5)
  • src/Features/Upscaling.cpp (12 hunks)
  • src/Features/Upscaling.h (3 hunks)
  • src/Features/Upscaling/DX12SwapChain.cpp (8 hunks)
  • src/Features/Upscaling/DX12SwapChain.h (4 hunks)
  • src/Features/Upscaling/FidelityFX.cpp (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Features/Upscaling/DX12SwapChain.cpp
  • src/Features/Upscaling/DX12SwapChain.h
  • src/Features/Upscaling.cpp
  • src/Features/Upscaling/FidelityFX.cpp
  • src/Features/Upscaling.h
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Features/Upscaling/DX12SwapChain.cpp
  • src/Features/Upscaling/DX12SwapChain.h
  • src/Features/Upscaling.cpp
  • src/Features/Upscaling/FidelityFX.cpp
  • src/Features/Upscaling.h
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Validate shader compilation (VR, .github/configs/shader-validation-vr.yaml)
  • GitHub Check: Validate shader compilation (Flatrim, .github/configs/shader-validation.yaml)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (17)
src/Features/Upscaling/DX12SwapChain.h (3)

64-65: Good addition: own the D3D12 device/queue via com_ptr.

This aligns with RAII and prevents leaks.


100-100: Consider graceful fallback on feature level.

If D3D_FEATURE_LEVEL_12_0 creation fails on SE/AE/VR edge hardware, gate frame‑gen and continue without proxy instead of hard failing. Add a fallback path (disable FG) and log.


73-78: Own WrappedResource pointers to avoid leaks (and copy hazards).

These are raw owning pointers with no destructor path; they will leak and make copy semantics dangerous. Convert all WrappedResource* members to std::unique_ptr and delete copy ops.

Apply this diff:

@@
-    WrappedResource* swapChainBufferWrapped;
-    WrappedResource* uiBufferWrapped;
+    std::unique_ptr<WrappedResource> swapChainBufferWrapped;
+    std::unique_ptr<WrappedResource> uiBufferWrapped;
@@
-    // D3D12 interop resources for frame generation
-    WrappedResource* depthBufferShared12 = nullptr;
-    WrappedResource* motionVectorBufferShared12 = nullptr;
+    // D3D12 interop resources for frame generation
+    std::unique_ptr<WrappedResource> depthBufferShared12;
+    std::unique_ptr<WrappedResource> motionVectorBufferShared12;

Also add in-class copy control:

@@
 class DX12SwapChain
 {
 public:
+    DX12SwapChain() = default;
+    DX12SwapChain(const DX12SwapChain&) = delete;
+    DX12SwapChain& operator=(const DX12SwapChain&) = delete;
+    DX12SwapChain(DX12SwapChain&&) = default;
+    DX12SwapChain& operator=(DX12SwapChain&&) = default;
src/Features/Upscaling/DX12SwapChain.cpp (3)

12-21: Guard device creation; degrade cleanly if unavailable.

If D3D12CreateDevice fails (non‑12_0 GPUs, driver issues), set a flag to skip proxy/FG and continue normal D3D11 operation.

Apply this minimal guard:

-    DX::ThrowIfFailed(D3D12CreateDevice(a_adapter, D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(&d3d12Device)));
+    if (FAILED(D3D12CreateDevice(a_adapter, D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(&d3d12Device)))) {
+        logger::warn("[Frame Generation] D3D12 device creation failed; disabling proxy.");
+        globals::features::upscaling.d3d12SwapChainActive = false;
+        return;
+    }

120-162: Fence order looks correct.

D3D11 Signal → D3D12 Wait, then D3D12 Signal → D3D11 Wait prevents overlap. Good.


218-231: Don’t combine SHARED and SHARED_NTHANDLE. Use only _NTHANDLE.

These flags are mutually exclusive for IDXGIResource1::CreateSharedHandle; using both can cause undefined behavior on some drivers.

Apply this diff:

-    // Create D3D11 shared texture directly instead of wrapping D3D12 resource
-    a_texDesc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
+    // Create D3D11 shared texture with NT handle
+    a_texDesc.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX);
+    a_texDesc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
src/Features/Upscaling.cpp (3)

791-797: Fix for missing PS acknowledged.

Compiling CopyDepthToSharedBufferPS in SetupResources resolves the null-PS draw risk previously reported.


1327-1329: Gate depth/motion uploads on FG active: good.

Work only happens when the D3D12 proxy is alive and FG is enabled.


817-868: Add null/guard checks before copying into shared D3D12 buffers.

Avoid crashes if shared resources aren’t created (e.g., device creation failed or FG toggled mid‑session).

Apply this diff:

 void Upscaling::CopySharedD3D12Resources()
 {
+    if (!dx12SwapChain.motionVectorBufferShared12 || !dx12SwapChain.depthBufferShared12) {
+        logger::warn("[Frame Generation] Shared resources not available; skipping copy.");
+        return;
+    }
+    if (!copyDepthToSharedBufferPS) {
+        logger::warn("[Frame Generation] copyDepthToSharedBufferPS not available; skipping depth blit.");
+        return;
+    }
@@
-    context->CopyResource(dx12SwapChain.motionVectorBufferShared12->resource11, motionVector.texture);
+    context->CopyResource(dx12SwapChain.motionVectorBufferShared12->resource11, motionVector.texture);
src/Features/Upscaling.h (3)

4-6: Include order is fine.

Public surface unchanged by the include; build hygiene OK.


51-57: Defaulting to TAA: good choice.

Safer default for users without upscaler DLLs.


141-145: Static instances OK; clarify FG-only FidelityFX in comment.

Comment already notes “Only for frame generation”. Good.

src/Features/Upscaling/FidelityFX.cpp (5)

130-152: Defensive check before using shared depth/motion resources.

If CreateSharedResources wasn’t called, this will dereference null.

Apply this guard:

-        dispatchParameters.depth = ffxApiGetResourceDX12(swapChain.depthBufferShared12->resource.get());
-        dispatchParameters.motionVectors = ffxApiGetResourceDX12(swapChain.motionVectorBufferShared12->resource.get());
+        if (!swapChain.depthBufferShared12 || !swapChain.motionVectorBufferShared12) {
+            logger::warn("[FidelityFX] Shared resources missing; skipping frame generation dispatch.");
+            return;
+        }
+        dispatchParameters.depth = ffxApiGetResourceDX12(swapChain.depthBufferShared12->resource.get());
+        dispatchParameters.motionVectors = ffxApiGetResourceDX12(swapChain.motionVectorBufferShared12->resource.get());

16-20: LoadLibrary result handling: keep HMODULE and a bool flag.

You’re assigning LoadLibrary to a bool-like field; keep the module handle for later FreeLibrary and derive a bool.

Apply this diff (paired with header updates: add HMODULE frameGenModule; bool featureFSR3FG):

-    // Load uframe generation DLL and its function pointers
+    // Load frame generation DLL and its function pointers
@@
-    featureFSR3FG = LoadLibrary(framegenPath.c_str());
+    frameGenModule = LoadLibrary(framegenPath.c_str());
+    featureFSR3FG = (frameGenModule != nullptr);

189-211: FSR3 DX11 init: handle allocation failures and free scratch; zero-init structs.

calloc result isn’t checked and the scratch buffer leaks; context desc isn’t value‑initialized.

Apply this diff (requires members: void* fsrScratch; size_t fsrScratchSize):

-    size_t scratchBufferSize = ffxGetScratchMemorySizeDX11(FFX_FSR3UPSCALER_CONTEXT_COUNT);
-    void* scratchBuffer = calloc(scratchBufferSize, 1);
-    memset(scratchBuffer, 0, scratchBufferSize);
+    fsrScratchSize = ffxGetScratchMemorySizeDX11(FFX_FSR3UPSCALER_CONTEXT_COUNT);
+    fsrScratch = calloc(fsrScratchSize, 1);
+    if (!fsrScratch) {
+        logger::critical("[FidelityFX] Failed to allocate FSR3 scratch memory!");
+        return;
+    }
@@
-    FfxInterface fsrInterface;
-    if (ffxGetInterfaceDX11(&fsrInterface, fsrDevice, scratchBuffer, scratchBufferSize, FFX_FSR3UPSCALER_CONTEXT_COUNT) != FFX_OK)
-        logger::critical("[FidelityFX] Failed to initialize FSR3 backend interface!");
+    FfxInterface fsrInterface{};
+    if (ffxGetInterfaceDX11(&fsrInterface, fsrDevice, fsrScratch, fsrScratchSize, FFX_FSR3UPSCALER_CONTEXT_COUNT) != FFX_OK) {
+        logger::critical("[FidelityFX] Failed to initialize FSR3 backend interface!");
+        return;
+    }
@@
-    FfxFsr3ContextDescription contextDescription;
+    FfxFsr3ContextDescription contextDescription{};
@@
-    if (ffxFsr3ContextCreate(&fsrContext, &contextDescription) != FFX_OK)
-        logger::critical("[FidelityFX] Failed to initialize FSR3 context!");
+    if (ffxFsr3ContextCreate(&fsrContext, &contextDescription) != FFX_OK) {
+        logger::critical("[FidelityFX] Failed to initialize FSR3 context!");
+        return;
+    }

And free on destroy:

 void FidelityFX::DestroyFSRResources()
 {
-    if (ffxFsr3ContextDestroy(&fsrContext) != FFX_OK)
+    if (ffxFsr3ContextDestroy(&fsrContext) != FFX_OK)
         logger::critical("[FidelityFX] Failed to destroy FSR3 context!");
+    if (fsrScratch) { free(fsrScratch); fsrScratch = nullptr; fsrScratchSize = 0; }
 }

252-263: Exposure resource: pass FFX_RESOURCE_NULL when auto exposure is enabled.

Passing nullptr into ffxGetResource is unsafe and now unnecessary.

Apply this diff:

-        dispatchParameters.exposure = ffxGetResource(nullptr, L"FSR3_InputExposure");
+        dispatchParameters.exposure = FFX_RESOURCE_NULL;

224-240: ffxGetResource: handle nulls and fix wcscpy_s usage.

Dereferencing null dx11Resource will crash; wcscpy_s overload requires a buffer size.

Apply this diff:

 FfxResource ffxGetResource(ID3D11Resource* dx11Resource,
   [[maybe_unused]] wchar_t const* ffxResName,
   FfxResourceStates state = FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ)
 {
-    FfxResource resource = {};
-    resource.resource = reinterpret_cast<void*>(const_cast<ID3D11Resource*>(dx11Resource));
-    resource.state = state;
-    resource.description = GetFfxResourceDescriptionDX11(dx11Resource);
+    if (!dx11Resource) {
+        return FFX_RESOURCE_NULL;
+    }
+    FfxResource resource{};
+    resource.resource = reinterpret_cast<void*>(const_cast<ID3D11Resource*>(dx11Resource));
+    resource.state = state;
+    resource.description = GetFfxResourceDescriptionDX11(dx11Resource);
 #ifdef _DEBUG
     if (ffxResName) {
-        wcscpy_s(resource.name, ffxResName);
+        wcsncpy_s(resource.name, _countof(resource.name), ffxResName, _TRUNCATE);
     }
 #endif
     return resource;
 }

Comment on lines +89 to 93
swapChainBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());

texDesc11.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
uiBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), upscaling.sharedD3D12Device.get());
uiBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Match header RAII: use unique_ptr for WrappedResource.

Switch new/delete to unique_ptr construction.

Apply this diff:

-    swapChainBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
+    swapChainBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), d3d12Device.get());
@@
-    uiBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
+    uiBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), d3d12Device.get());
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
swapChainBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
texDesc11.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
uiBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), upscaling.sharedD3D12Device.get());
uiBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
}
swapChainBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), d3d12Device.get());
texDesc11.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
uiBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), d3d12Device.get());
}
🤖 Prompt for AI Agents
In src/Features/Upscaling/DX12SwapChain.cpp around lines 89 to 93, the code uses
raw new to allocate WrappedResource for swapChainBufferWrapped and
uiBufferWrapped; change these to construct and assign
std::unique_ptr<WrappedResource> (use std::make_unique) instead of raw new,
update the member declarations to std::unique_ptr<WrappedResource> if they
aren't already, include <memory> if needed, and remove any corresponding delete
calls so ownership is RAII-managed.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/Features/Upscaling/DX12SwapChain.cpp (4)

10-27: Device/queue init: add small robustness (SetName, NodeMask, removed-device handling).

  • Optional: set debug names for d3d12Device, commandQueue, allocators, and lists to ease GPU capture/debug.
  • If running on multi-node adapters, prefer queueDesc.NodeMask = 1 (or the target node mask) instead of 0.
  • Consider catching device removal during init and surfacing a clean fallback.

Can you confirm whether the adapter can be multi-node in your target configs and whether you want names set in non-release builds?


31-31: Guard against double-initialization.

CreateSwapChain unconditionally calls CreateD3D12Device(adapter). If resize/recreate paths call CreateSwapChain again, this will leak or reinit D3D12 objects.

Apply a simple guard:

- CreateD3D12Device(adapter);
+ if (!d3d12Device) {
+   CreateD3D12Device(adapter);
+ }

72-76: Fence interop: rights and capability check.

  • Consider narrower rights than GENERIC_ALL for the fence handle (e.g., SYNCHRONIZE|GENERIC_READ), following least-privilege.
  • Ensure d3d11Device is actually ID3D11Device5 before calling OpenSharedFence; if not, fail gracefully.

If you want, I can add a small capability probe and downgrade path.


219-220: Proactively clear incompatible MiscFlags before setting NTHANDLE.

If an incoming desc carries SHARED or KEYEDMUTEX, combining with _NTHANDLE is invalid. Clear them first.

Apply this diff:

- a_texDesc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
+ a_texDesc.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX);
+ a_texDesc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f7c646 and ae505ab.

📒 Files selected for processing (1)
  • src/Features/Upscaling/DX12SwapChain.cpp (8 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Features/Upscaling/DX12SwapChain.cpp
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Features/Upscaling/DX12SwapChain.cpp
🔇 Additional comments (7)
src/Features/Upscaling/DX12SwapChain.cpp (7)

51-51: Correct queue binding for FidelityFX.

Wiring ffxSwapChainDesc.gameQueue = commandQueue.get(); is the right call.


116-175: Fence sequencing looks right; ensure initial value policy is consistent.

The cross-API sync pattern (11 Signal N → 12 Wait N; 12 Signal N+1 → 11 Wait N+1) is correct. Verify fenceValue initializes to 1 (or any non-decreasing scheme) and that no frame can observe a stale value on first Present.

If you’d like, I can add asserts around fence progression and frameIndex bounds.


216-221: Addressed previous shared-handle flag issue.

Good fix: using only D3D11_RESOURCE_MISC_SHARED_NTHANDLE for NT handles.


89-93: Use RAII for WrappedResource to avoid leaks and simplify teardown.

Replace raw new with std::unique_ptr. Do the same for the member declarations in the header.

Apply this diff here:

- swapChainBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
+ swapChainBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), d3d12Device.get());
@@
- uiBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
+ uiBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), d3d12Device.get());

And likewise for other WrappedResource* allocations below.


402-417: Verify target enums and fence initialization — repo scan returned no matches

Repo scan found no occurrences of RE::RENDER_TARGETS (kMAIN / kMOTION_VECTOR) or any fenceValue / D3D12 fence usage; confirm the correct enum identifiers and that a D3D12 fence is created/signaled/waited when creating the shared WrappedResource objects in src/Features/Upscaling/DX12SwapChain.cpp:402–417.


402-417: Verify enum usage, SRV bind flags, and use RAII for shared resources

  • Could not find src/Features/Upscaling/DX12SwapChain.cpp in the repository — unable to verify; confirm path or include file in the PR.
  • If file exists, use the project’s actual enum name consistently (RE::RENDER_TARGET or RE::RENDER_TARGETS).
  • Ensure texDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE for depth and motion textures; if sampling a DSV, use typeless backing (DXGI_FORMAT_R32_TYPELESS) and create the SRV as DXGI_FORMAT_R32_FLOAT.
  • Set texDesc.MipLevels = 1, ArraySize = 1, CPUAccessFlags = 0, Usage = D3D11_USAGE_DEFAULT when creating shared textures.
  • Replace raw new with RAII (e.g., std::make_unique) for depthBufferShared12 and motionVectorBufferShared12.

89-93: Convert raw WrappedResource pointers to std::unique_ptr

Replace swapChainBufferWrapped, uiBufferWrapped, depthBufferShared12, and motionVectorBufferShared12 in the DX12SwapChain header with std::unique_ptr; update allocations to std::make_unique (or direct unique_ptr construction) and remove manual delete/ownership handling. Header wasn't present in the checkout during verification — apply this change in the DX12SwapChain header (also applies to lines 89–93 and 411–416) or share the header for an exact diff.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 23, 2025

✅ A pre-release build is available for this PR:
Download

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/State.cpp (1)

766-772: Avoid -inf/NaN in MipBias; keep DLSS offset intact

Guard against divide-by-zero and non-positive ratios.

Apply this diff:

-                data.MipBias = std::log2f(renderSize.x / screenSize.x);
-                if (upscaleMethod == Upscaling::UpscaleMethod::kDLSS)
-                    data.MipBias -= 1.0f;
+                const float denom = std::max(screenSize.x, 1.0f);
+                const float ratio = std::max(renderSize.x / denom, 1e-6f);
+                data.MipBias = std::log2f(ratio);
+                if (upscaleMethod == Upscaling::UpscaleMethod::kDLSS) {
+                    data.MipBias -= 1.0f;
+                }
src/Hooks.cpp (2)

346-356: Match ID3D11 signature, validate input, and clamp anisotropy to [1, 8]

Use const pointer, guard nullptr, and avoid invalid 0.

Apply this diff:

-struct ID3D11Device_CreateSamplerState
+struct ID3D11Device_CreateSamplerState
 {
-    static HRESULT STDMETHODCALLTYPE thunk(ID3D11Device* This, D3D11_SAMPLER_DESC* pSamplerDesc, ID3D11SamplerState** ppSamplerState)
+    static HRESULT STDMETHODCALLTYPE thunk(ID3D11Device* This, const D3D11_SAMPLER_DESC* pSamplerDesc, ID3D11SamplerState** ppSamplerState)
     {
-        // Limit Anisotropy to 8x for performance
-        D3D11_SAMPLER_DESC descCopy = *pSamplerDesc;  // make a copy, pSamplerDesc is supposed to be immutable
-        descCopy.MaxAnisotropy = std::min(descCopy.MaxAnisotropy, 8u);
+        if (!pSamplerDesc) return E_INVALIDARG;
+        // Limit Anisotropy to 8x for performance
+        D3D11_SAMPLER_DESC descCopy = *pSamplerDesc;  // copy, input is immutable
+        descCopy.MaxAnisotropy = std::max(1u, std::min(descCopy.MaxAnisotropy, 8u));
         return func(This, &descCopy, ppSamplerState);
     }
     static inline REL::Relocation<decltype(thunk)> func;
 };

451-452: Consider making max anisotropy configurable (not hard-coded 8)

Gate the detour with a setting so users can opt for quality vs performance.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae505ab and 2e7ecd7.

📒 Files selected for processing (4)
  • src/Features/Upscaling/DX12SwapChain.cpp (8 hunks)
  • src/Features/Upscaling/FidelityFX.cpp (5 hunks)
  • src/Hooks.cpp (2 hunks)
  • src/State.cpp (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Features/Upscaling/DX12SwapChain.cpp
  • src/State.cpp
  • src/Features/Upscaling/FidelityFX.cpp
  • src/Hooks.cpp
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Features/Upscaling/DX12SwapChain.cpp
  • src/State.cpp
  • src/Features/Upscaling/FidelityFX.cpp
  • src/Hooks.cpp
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Validate shader compilation (VR, .github/configs/shader-validation-vr.yaml)
  • GitHub Check: Validate shader compilation (Flatrim, .github/configs/shader-validation.yaml)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (19)
src/Features/Upscaling/DX12SwapChain.cpp (11)

10-27: LGTM: Dedicated D3D12 device/queue and per-frame lists

Initialization looks correct and self-contained.


31-31: LGTM: Device creation moved into swap-chain path

Keeps ownership localized.


51-51: LGTM: Framegen uses local command queue

Correct hand-off for FFX swap-chain descriptor.


72-75: LGTM: Cross-API fence interop

CreateFence + CreateSharedHandle + OpenSharedFence sequence is correct.


89-93: Prefer RAII: use unique_ptr for WrappedResource allocations

Avoid raw new; matches prior feedback.

Apply this diff:

-    swapChainBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
+    swapChainBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), d3d12Device.get());
@@
-    uiBufferWrapped = new WrappedResource(texDesc11, d3d11Device.get(), d3d12Device.get());
+    uiBufferWrapped = std::make_unique<WrappedResource>(texDesc11, d3d11Device.get(), d3d12Device.get());

Update member declarations to std::unique_ptr and drop manual deletes.


122-123: LGTM: Proper D3D11→D3D12 sync

ID3D11DeviceContext::Signal then ID3D12Queue::Wait is correct ordering.


155-156: LGTM: Execute single command list

Fits the per-frame allocator/list pattern.


161-162: LGTM: D3D12→D3D11 sync

Queue::Signal then Context::Wait is the right direction back.


400-401: No-op change

Only structural/whitespace; no action.


216-231: Do not set both D3D11_RESOURCE_MISC_SHARED and _NTHANDLE

This can fail texture creation and breaks CreateSharedHandle expectations.

Apply this diff:

-    // Create D3D11 shared texture directly instead of wrapping D3D12 resource
-    a_texDesc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
+    // Create D3D11 shared texture (NT handle only)
+    a_texDesc.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX);
+    a_texDesc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_NTHANDLE;

402-417: RAII + call ordering: ensure creation and lifetime are safe

  • Replace raw new with std::make_unique(...) for depthBufferShared12 and motionVectorBufferShared12 to ensure RAII and avoid leaks.
  • Ensure CreateSharedResources() is invoked before any frame-generation prepare/usage (SetupFrameGeneration / DispatchDescFrameGenerationPrepare).

src/Features/Upscaling/DX12SwapChain.cpp not found in repo; no occurrences of CreateSharedResources / SetupFrameGeneration / DispatchDescFrameGenerationPrepare detected — confirm invocation order locally.

src/Features/Upscaling/FidelityFX.cpp (8)

16-16: Typo + keep HMODULE for FG DLL

Fix comment typo and retain the LoadLibrary handle instead of a bool.

Apply this diff:

-    // Load uframe generation DLL and its function pointers
+    // Load frame generation DLL and its function pointers

If featureFSR3FG is a bool, prefer:

-    featureFSR3FG = LoadLibrary(framegenPath.c_str());
+    frameGenModule = LoadLibrary(framegenPath.c_str());
+    featureFSR3FG = (frameGenModule != nullptr);

Update header members accordingly.


58-58: LGTM: Use DX12 device from local swap-chain

Correct backend device pointer.


130-130: LGTM: Command list from current frame

Correct for FFX dispatch.


150-152: Ensure shared resources exist before FG prepare

Null deref risk if CreateSharedResources() hasn’t run yet.

Where is DX12SwapChain::CreateSharedResources() invoked? Ensure it runs after CreateInterop() and before first Present/Prepare. I can help place the call if needed.


189-211: Fix DX11 FSR3 init: scratch ownership, zero-init, failure paths

Avoid leaks/crash; keep scratch alive and free on failure/destroy.

Apply this diff:

-    auto fsrDevice = ffxGetDeviceDX11(globals::d3d::device);
-
-    size_t scratchBufferSize = ffxGetScratchMemorySizeDX11(FFX_FSR3UPSCALER_CONTEXT_COUNT);
-    void* scratchBuffer = calloc(scratchBufferSize, 1);
-    memset(scratchBuffer, 0, scratchBufferSize);
-
-    FfxInterface fsrInterface;
-    if (ffxGetInterfaceDX11(&fsrInterface, fsrDevice, scratchBuffer, scratchBufferSize, FFX_FSR3UPSCALER_CONTEXT_COUNT) != FFX_OK)
-        logger::critical("[FidelityFX] Failed to initialize FSR3 backend interface!");
-
-    FfxFsr3ContextDescription contextDescription;
+    auto fsrDevice = ffxGetDeviceDX11(globals::d3d::device);
+
+    fsrScratchSize = ffxGetScratchMemorySizeDX11(FFX_FSR3UPSCALER_CONTEXT_COUNT);
+    fsrScratch = calloc(fsrScratchSize, 1);
+    if (!fsrScratch) {
+        logger::critical("[FidelityFX] Failed to allocate FSR3 scratch memory!");
+        return;
+    }
+
+    FfxInterface fsrInterface{};
+    if (ffxGetInterfaceDX11(&fsrInterface, fsrDevice, fsrScratch, fsrScratchSize, FFX_FSR3UPSCALER_CONTEXT_COUNT) != FFX_OK) {
+        logger::critical("[FidelityFX] Failed to initialize FSR3 backend interface!");
+        free(fsrScratch); fsrScratch = nullptr; fsrScratchSize = 0;
+        return;
+    }
+
+    FfxFsr3ContextDescription contextDescription{};
@@
-    if (ffxFsr3ContextCreate(&fsrContext, &contextDescription) != FFX_OK)
-        logger::critical("[FidelityFX] Failed to initialize FSR3 context!");
+    if (ffxFsr3ContextCreate(&fsrContext, &contextDescription) != FFX_OK) {
+        logger::critical("[FidelityFX] Failed to initialize FSR3 context!");
+        free(fsrScratch); fsrScratch = nullptr; fsrScratchSize = 0;
+        return;
+    }

Note: add fsrScratch/fsrScratchSize members in FidelityFX.h.


215-217: Release scratch memory on destroy

Prevent leak.

Apply this diff:

     if (ffxFsr3ContextDestroy(&fsrContext) != FFX_OK)
         logger::critical("[FidelityFX] Failed to destroy FSR3 context!");
+    if (fsrScratch) {
+        free(fsrScratch);
+        fsrScratch = nullptr;
+        fsrScratchSize = 0;
+    }

224-240: Handle nulls; fix wcscpy_s usage in ffxGetResource

Avoid crash and buffer misuse.

Apply this diff:

 FfxResource ffxGetResource(ID3D11Resource* dx11Resource,
   [[maybe_unused]] wchar_t const* ffxResName,
   FfxResourceStates state = FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ)
 {
-  FfxResource resource = {};
+  if (!dx11Resource) {
+    return FFX_RESOURCE_NULL;
+  }
+  FfxResource resource = {};
   resource.resource = reinterpret_cast<void*>(const_cast<ID3D11Resource*>(dx11Resource));
   resource.state = state;
   resource.description = GetFfxResourceDescriptionDX11(dx11Resource);
 
 #ifdef _DEBUG
   if (ffxResName) {
-    wcscpy_s(resource.name, ffxResName);
+    wcsncpy_s(resource.name, sizeof(resource.name) / sizeof(resource.name[0]), ffxResName, _TRUNCATE);
   }
 #endif
 
   return resource;
 }

242-293: Do not wrap nullptr in ffxGetResource for exposure

Use FFX_RESOURCE_NULL when auto-exposure is enabled.

Apply this diff:

-        dispatchParameters.exposure = ffxGetResource(nullptr, L"FSR3_InputExposure");
+        dispatchParameters.exposure = FFX_RESOURCE_NULL;

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/Features/Upscaling/FidelityFX.cpp (1)

221-222: Prefer static_cast for enum conversion.

Safer and consistent with C++ style.

-	return 1.0f / ffxFsr3GetUpscaleRatioFromQualityMode((FfxFsr3QualityMode)qualityMode);
+	return 1.0f / ffxFsr3GetUpscaleRatioFromQualityMode(static_cast<FfxFsr3QualityMode>(qualityMode));
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e7ecd7 and 2b58d3f.

📒 Files selected for processing (1)
  • src/Features/Upscaling/FidelityFX.cpp (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Features/Upscaling/FidelityFX.cpp
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Features/Upscaling/FidelityFX.cpp
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Validate shader compilation (Flatrim, .github/configs/shader-validation.yaml)
  • GitHub Check: Validate shader compilation (VR, .github/configs/shader-validation-vr.yaml)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (11)
src/Features/Upscaling/FidelityFX.cpp (11)

16-20: Keep the HMODULE for framegen and fix the typo in the comment.

You’re discarding the HMODULE and storing success in a bool. Keep the handle so you can FreeLibrary later; also fix “uframe” → “frame”.

-	// Load uframe generation DLL and its function pointers
+	// Load frame generation DLL and its function pointers
  	std::wstring framegenDllName = L"amd_fidelityfx_framegeneration_dx12.dll";
  	std::wstring framegenPath = std::wstring(FidelityFX::PluginDir) + L"\\" + framegenDllName;
-	featureFSR3FG = LoadLibrary(framegenPath.c_str());
+	frameGenModule = LoadLibrary(framegenPath.c_str());
+	featureFSR3FG = (frameGenModule != nullptr);

Additionally add (outside this hunk):

// file-scope
static HMODULE frameGenModule = nullptr;
// On shutdown: if (frameGenModule) { FreeLibrary(frameGenModule); frameGenModule = nullptr; }

54-54: Async workload enablement: verify capability gating and fallback.

You enable async in both create and configure. Confirm drivers/runtime support and that you fall back cleanly if not.

Also applies to: 104-104


130-130: LGTM on command list selection.

Using the per-frame indexed command list is appropriate.


150-151: Validate resource state/availability for DX12 depth/MVs.

Ensure these resources are non-null and transitioned to the states expected by the FG path before dispatch to avoid undefined behavior.


260-260: Verify in-place output aliasing is supported.

Confirm FSR3 DX11 allows upscaleOutput == color for your formats/states.


264-267: Motion vector scale in VR: verify per-eye math.

Half-width for x in VR seems intended; confirm screenSize/renderSize semantics for stereo (per-eye vs combined).


280-286: Sharpening defaults: confirm UX expectations.

Defaulting to enable with 0.5 strength—ensure this matches your settings UI/state and doesn’t double-apply if driver-side sharpening is active.


275-275: Frame time source: confirm units and monotonicity.

Ensure deltaTime is seconds and monotonic; negative/zero frames can destabilize the history.


215-216: Free scratch on destroy to avoid leak.

The DX11 scratch buffer must be freed.

 	if (ffxFsr3ContextDestroy(&fsrContext) != FFX_OK)
 		logger::critical("[FidelityFX] Failed to destroy FSR3 context!");
+	if (fsrScratch) {
+		free(fsrScratch);
+		fsrScratch = nullptr;
+		fsrScratchSize = 0;
+	}

224-239: Guard null resources and fix wcscpy_s usage.

Null dx11Resource currently dereferences; wcscpy_s needs the destination size.

-FfxResource ffxGetResource(ID3D11Resource* dx11Resource,
+FfxResource ffxGetResource(ID3D11Resource* dx11Resource,
 	[[maybe_unused]] wchar_t const* ffxResName,
 	FfxResourceStates state = FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ)
 {
-	FfxResource resource = {};
+	if (!dx11Resource) {
+		return FFX_RESOURCE_NULL;
+	}
+	FfxResource resource = {};
 	resource.resource = reinterpret_cast<void*>(const_cast<ID3D11Resource*>(dx11Resource));
 	resource.state = state;
 	resource.description = GetFfxResourceDescriptionDX11(dx11Resource);
 
 #ifdef _DEBUG
 	if (ffxResName) {
-		wcscpy_s(resource.name, ffxResName);
+		wcsncpy_s(resource.name,
+		          sizeof(resource.name) / sizeof(resource.name[0]),
+		          ffxResName,
+		          _TRUNCATE);
 	}
 #endif
 
 	return resource;
 }

259-259: Crash risk: passing nullptr into ffxGetResource; use FFX_RESOURCE_NULL for exposure.

This will dereference null in ffxGetResource. Use the null sentinel since AUTO_EXPOSURE is enabled.

-		dispatchParameters.exposure = ffxGetResource(nullptr, L"FSR3_InputExposure");
+		dispatchParameters.exposure = FFX_RESOURCE_NULL;

Comment thread src/Features/Upscaling/FidelityFX.cpp
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/Features/Upscaling.cpp (1)

416-444: Consider extracting common texture descriptor setup.

The texture creation logic for reactive mask, transparency composition mask, and motion vector copy repeats similar D3D11 descriptor setup patterns. Consider extracting a helper method to reduce duplication.

+private:
+    Texture2D* CreateMaskTexture(const D3D11_TEXTURE2D_DESC& sourceDesc, DXGI_FORMAT format) {
+        D3D11_TEXTURE2D_DESC texDesc = sourceDesc;
+        texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
+        texDesc.Format = format;
+        
+        D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+        srvDesc.Format = format;
+        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+        srvDesc.Texture2D.MipLevels = 1;
+        
+        D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
+        uavDesc.Format = format;
+        uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
+        
+        auto* texture = new Texture2D(texDesc);
+        texture->CreateSRV(srvDesc);
+        texture->CreateUAV(uavDesc);
+        return texture;
+    }

 void Upscaling::CreateUpscalingTextureResources(UpscaleMethod a_upscalemethod)
 {
     // ... existing code ...
-    if (!reactiveMaskTexture) {
-        reactiveMaskTexture = new Texture2D(texDesc);
-        reactiveMaskTexture->CreateSRV(srvDesc);
-        reactiveMaskTexture->CreateUAV(uavDesc);
-    }
+    if (!reactiveMaskTexture) {
+        reactiveMaskTexture = CreateMaskTexture(texDesc, DXGI_FORMAT_R8_UNORM);
+    }
     
-    if (!transparencyCompositionMaskTexture) {
-        transparencyCompositionMaskTexture = new Texture2D(texDesc);
-        transparencyCompositionMaskTexture->CreateSRV(srvDesc);
-        transparencyCompositionMaskTexture->CreateUAV(uavDesc);
-    }
+    if (!transparencyCompositionMaskTexture) {
+        transparencyCompositionMaskTexture = CreateMaskTexture(texDesc, DXGI_FORMAT_R8_UNORM);
+    }

Also applies to: 446-467

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b58d3f and 8c720eb.

📒 Files selected for processing (2)
  • features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl (2 hunks)
  • src/Features/Upscaling.cpp (15 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl
  • src/Features/Upscaling.cpp
features/*/Shaders/**/*.{hlsl,hlsli,fx,fxh}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

features/*/Shaders/**/*.{hlsl,hlsli,fx,fxh}: Place all feature shaders under features/YourFeature/Shaders/
Avoid GPU register/buffer conflicts in HLSL; verify register usage (e.g., with hlslkit buffer scanning)

Files:

  • features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Features/Upscaling.cpp
🧠 Learnings (2)
📚 Learning: 2025-08-17T18:37:35.839Z
Learnt from: CR
PR: doodlum/skyrim-community-shaders#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T18:37:35.839Z
Learning: Applies to features/*/Shaders/**/*.{hlsl,hlsli,fx,fxh} : Avoid GPU register/buffer conflicts in HLSL; verify register usage (e.g., with hlslkit buffer scanning)

Applied to files:

  • features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl
  • src/Features/Upscaling.cpp
📚 Learning: 2025-08-03T18:37:19.690Z
Learnt from: jiayev
PR: doodlum/skyrim-community-shaders#0
File: :0-0
Timestamp: 2025-08-03T18:37:19.690Z
Learning: ISReflectionsRayTracing.hlsl and ISWorldMap.hlsl in the skyrim-community-shaders repository are image-space post-processing shaders that perform color sampling and blending operations that need proper linear color space handling for the linear lighting system. ISReflectionsRayTracing handles screen-space reflections and should use conditional Color::IrradianceToLinear/Gamma conversions similar to ISCompositeLensFlareVolumetricLighting.hlsl. ISWorldMap performs 7x7 color accumulation that should be done in linear space similar to the pattern used in ISSAOComposite.hlsl.

Applied to files:

  • features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl
🔇 Additional comments (8)
features/Upscaling/Shaders/Upscaling/EncodeTexturesCS.hlsl (3)

19-21: Good addition of early boundary check.

The early exit for threads outside TrueSamplingDim prevents unnecessary computation and UAV writes beyond the valid texture bounds.


26-62: DLSS-specific motion vector logic looks correct.

The 5x5 neighborhood search for the longest motion vector with depth-based filtering is appropriate for DLSS requirements. The boundary checks prevent out-of-bounds reads.


64-68: Clamp masks to [0,1] to meet upscaler input contracts.

reactiveMask can exceed 1 (e.g., 0.1*1+1=1.1). transparencyCompositionMask may also be out of range. Clamp with saturate to avoid artifacts and honor FSR/DLSS/streamline expectations.

-	float reactiveMask = taaMask.x * 0.1 + taaMask.y;
-	ReactiveMask[dispatchID.xy] = reactiveMask;
+	float reactiveMask = saturate(taaMask.x * 0.1 + taaMask.y);
+	ReactiveMask[dispatchID.xy] = reactiveMask;

-	TransparencyCompositionMask[dispatchID.xy] = transparencyCompositionMask;
+	TransparencyCompositionMask[dispatchID.xy] = saturate(transparencyCompositionMask);
src/Features/Upscaling.cpp (5)

407-410: Proper parameter clamping ensures safe method selection.

The clamping of upscaleMethod and qualityMode prevents out-of-bounds access in UI display logic and method selection, which is crucial for stability.


151-168: UI label vector access is properly bounded.

Line 172 correctly clamps the modeLabelIndex to prevent out-of-bounds access when reading from the upscaleModes vector, addressing potential crashes from stale configuration values.


804-807: Good fix for the missing pixel shader compilation.

The copyDepthToSharedBufferPS is now properly compiled during SetupResources(), resolving the previous issue where the shader was used but never created. This ensures the depth copy to shared buffer will function correctly.


1338-1339: Verify conditional logic for shared D3D12 resource copying — File: src/Features/Upscaling.cpp (lines 1338–1339): the call to CopySharedD3D12Resources only runs when upscaling.d3d12SwapChainActive && upscaling.settings.frameGenerationMode; confirm every code path that requires D3D12 shared-resource synchronization satisfies both flags (missing copies can cause rendering artifacts). Repository search in this branch did not locate src/Features/Upscaling.cpp or any CopySharedD3D12Resources occurrences — confirm the correct file path or additional callsites where shared D3D12 resources are created/updated.


530-531: Verify FSR resource creation timing and idempotence

Ensure fidelityFX.CreateFSRResources() is idempotent and correctly frees/recreates GPU resources when switching to FSR (called at src/Features/Upscaling.cpp:530–531). Automated search did not locate Upscaling.cpp/CreateFSRResources in this repo — verify the implementation handles existing resources and any required cleanup/recreation.

@doodlum doodlum merged commit cf9c400 into dev Sep 23, 2025
15 checks passed
Pentalimbed pushed a commit to Pentalimbed/skyrim-community-shaders that referenced this pull request Dec 16, 2025
* chore(ui): update discord banner (community-shaders#1493)

* fix: use proper filename settingsuser.json (community-shaders#1491)

* chore(upscaling): increase fsr sharpness

* chore: rename d3d12interop to d3d12SwapChainActive (community-shaders#1494)

* feat(llf): remove particle lights (community-shaders#1495)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* feat(llf): move llf to core (community-shaders#1496)

* fix: remove water clamp (community-shaders#1497)

* fix(upscaling): more upscaling fixes (community-shaders#1498)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix: fix some internal errors when debugging (community-shaders#1500)

* fix(ui): fix save settings conflicts & welcome screen (community-shaders#1501)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(ui): add constraints for discord banner size (community-shaders#1463)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(VR): fix exiting menu using controllers (community-shaders#1502)

* build: fix warnings (community-shaders#1505)

* feat(UI): allow tooltips for disabled elements (community-shaders#1503)

* feat(upscaling): add downscale percentages (community-shaders#1506)

* perf(ssgi): optimize  (community-shaders#1499)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat(ui): font size and perf overlay improvements (community-shaders#1511)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: remove unused hooks (community-shaders#1510)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix: adjust IsInterior to consider kNoSky or kFixedDimensions flags (community-shaders#1512)

* fix(hair): correct hair indirect normal, marschner by default (community-shaders#1515)

Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: mostly revert ISHDR to 1.3.6 (community-shaders#1516)

* chore(upscaling): simplify interop and upscale methods (community-shaders#1514)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(hair): typo in code (community-shaders#1517)

* feat(ibl): lerp sky ibl using skylighting (community-shaders#1519)

* fix(sss): burley artifacts with effect blend (community-shaders#1518)

* fix(upscaling): fix screenshots when upscaling enabled (community-shaders#1520)

* fix(upscaling): fix mipbias sometimes being wrong (community-shaders#1521)

* fix: fix compile error if snow shader on (community-shaders#1522)

* chore(upscaling): revert fsr to typical settings (community-shaders#1523)

* fix: fix minor ui issues (community-shaders#1524)

* chore(grass collision): simpler grass collision (community-shaders#1525)

* fix: update skylighting and version

* fix(pbr): fix inconsistencies (community-shaders#1526)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: jiayev <l936249247@hotmail.com>

* feat(upscaling): sharpening slider (community-shaders#1527)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: bump versions

* fix(ibl): add ibl to reflection normalization (community-shaders#1528)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(hair): remove pbr lighting mult for hair (community-shaders#1531)

* chore(upscaling): add back upscale multiplier (community-shaders#1532)

* fix(upscaling): fix minor upscaling issues (community-shaders#1536)

* chore: gamma space normalisation (community-shaders#1535)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat(grass collision): implement with texture and history (community-shaders#1539)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore(grass collision): less aggressive (community-shaders#1546)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(skylighting): fix cell id casting (community-shaders#1544)

* chore(emat): auto detect terrain parallax (community-shaders#1545)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: update versions

* feat(VR): enable upscaling (community-shaders#1507)

* fix(terrain shadows): fix brightened lods (community-shaders#1547)

* chore(upscaling): reduce ghosting near camera (community-shaders#1548)

* fix: fix grass not animating (community-shaders#1549)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(grass collision): fix non-standard timescales (community-shaders#1550)

* build: deploy only updated files (community-shaders#1556)

* feat: add Clear Shader Cache to Advanced (community-shaders#1555)

* chore(featureissues): default collapse testing menu (community-shaders#1554)

* fix(VR): use only supported shaders from cache (community-shaders#1553)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* build: use gersemi cmake formatter (community-shaders#1557)

* fix(terrain): vanilla diffuse in pbr terrain cell too bright due to wrong color space (community-shaders#1558)

* docs: add new feature development template guide (community-shaders#1529)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* docs(UI): remove duplicate GPL license statement (community-shaders#1561)

* feat: add renderdoc for debugging (community-shaders#1560)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@gmail.com>

* fix(ui): welcome popup size issues (community-shaders#1573)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore(grass collision): minor tweaks (community-shaders#1568)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(terrain helper): fix conflicting bit (community-shaders#1566)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat(UI): separate theme settings, UI refactor, font support (community-shaders#1571)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: bump versions

* build: fix zipping aio (community-shaders#1579)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(grass collision): clamp maximum depth of grass (community-shaders#1578)

* feat(UI): enhance shader blocking (community-shaders#1564)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@gmail.com>

* fix: remove duplicate buffer setup (community-shaders#1586)

* feat: update shader compile elapsed time every second (community-shaders#1587)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* build: add cmake install commands (community-shaders#1372)

* feat(perf-overlay): add size controls (community-shaders#1591)

* fix(perf-overlay): fix infinite draw calls table height (community-shaders#1590)

* refactor(perf-overlay): remove collapsible headers (community-shaders#1572)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(perf-overlay): removed ImGuiTableFlags_ScrollX/Y for scroll bar issues (community-shaders#1594)

* build: fix shader copying to relative paths (community-shaders#1603)

* fix(ibl): apply ibl to cubemap normalisation for non deferred (community-shaders#1604)

* fix(grass): use correct light direction (community-shaders#1602)

* fix(welcome-popup): adjust font size & window spacing (community-shaders#1592)

* feat(lod): add gamma sliders (community-shaders#1588)

* build: correct CodeRabbit schema syntax (community-shaders#1608)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>

* build: add compile-time validation of GPU buffers (community-shaders#1427)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>

* ci: run shader validation on CMake and CI config changes (community-shaders#1606)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>

* feat: procedural sun

* limb darkening

* another darkening

* build(deps): remove orphaned Intel XeSS dependency (community-shaders#1611)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

* fix: accumulate sunlight color in pixel shader output

* fix(ui): enter key now behaves properly when first time popup is open (community-shaders#1615)

* feat(ui): add tabs to advanced settings & PBR search (community-shaders#1599)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* build: add HLSL intellisense (community-shaders#1614)

* refactor(UI): move light limit visualization into debug (community-shaders#1619)

* refactor(ui): add settings for shader block hotkeys (community-shaders#1624)

Co-authored-by: Bruce <44987693+brucenguyen@users.noreply.github.com>

* fix(ui): anchor reset settings button position  (community-shaders#1621)

Co-authored-by: Giovanni Correia <Gistix@users.noreply.github.com>

* fix(hair): use indirect normal for deferred marschner hair (community-shaders#1626)

* build: fix Package-AIO-Manual for fresh pulls (community-shaders#1625)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(snow): use world space vectors (community-shaders#1618)

* feat(UI): add gaussian blur shader core files (community-shaders#1595)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* feat(ui): add test conditions button (community-shaders#1637)

* fix(ui): blocked shader info overflow in Shader Debug tab (community-shaders#1632)

* fix(upscaling): replace NIS with RCAS for DLSS (community-shaders#1620)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(dynamic cubemaps): add a check for timeskip (community-shaders#1639)

* refactor: restructure lighting (community-shaders#1633)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* feat(ui): add themes & fonts (community-shaders#1596)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat(water): add flowmap parallax (community-shaders#1636)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix cloud shadow setting saving

---------

Co-authored-by: zxcvbn <66063766+zndxcvbn@users.noreply.github.com>
Co-authored-by: davo0411 <davidkehoe0411@outlook.com>
Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@users.noreply.github.com>
Co-authored-by: soda <130315225+soda3000@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: ThePagi <32794457+ThePagi@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@gmail.com>
Co-authored-by: Yupeng Zhang <ArcEarth@outlook.com>
Co-authored-by: kuplion <kuplion@hotmail.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Giovanni Correia <Gistix@users.noreply.github.com>
Co-authored-by: Bruce <44987693+brucenguyen@users.noreply.github.com>
Co-authored-by: Midona <106106405+midona-rhel@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant