Skip to content

Graphics: acquire D3D12 back buffer per-present (resize/F-11 fix)#218

Merged
Segfaultd merged 1 commit into
MafiaHub:developfrom
Kheartz:d3d12-f11
Jun 25, 2026
Merged

Graphics: acquire D3D12 back buffer per-present (resize/F-11 fix)#218
Segfaultd merged 1 commit into
MafiaHub:developfrom
Kheartz:d3d12-f11

Conversation

@Kheartz

@Kheartz Kheartz commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

This issue predated my work on the d3d12 view. When Init is called, the back buffers were cached, but these are usually recreated whenever the window is resized--making references to them invalid.

The backend cached the swapchain back buffers for the process lifetime, so the game's ResizeBuffers failed (DXGI_ERROR_INVALID_CALL) and UE4 crashed on any fullscreen/resolution change. Acquire the back buffer fresh in Begin() and release it in End() so no reference is held across frames.

Summary by CodeRabbit

  • Bug Fixes

    • Improved frame rendering reliability by handling render targets per frame instead of keeping them across frames.
    • Added safer cleanup so back-buffer resources are released correctly, helping avoid issues during resize or swapchain recreation.
    • Updated frame presentation flow to better guard against initialization failures and invalid back-buffer usage.
  • New Features

    • Added swapchain access controls so the graphics backend can be pointed to a recreated swapchain.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Kheartz, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 34 minutes and 45 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e70624bd-4809-4dde-9eee-d55f6b732d97

📥 Commits

Reviewing files that changed from the base of the PR and between 3f973eb and cbe53e7.

📒 Files selected for processing (2)
  • code/framework/src/graphics/backend/d3d12.cpp
  • code/framework/src/graphics/backend/d3d12.h

Walkthrough

The D3D12 backend now acquires the swapchain back buffer each frame, creates the RTV during Begin, and releases that buffer in End and Shutdown. The header removes stored render-target ownership and adds swapchain accessors.

Changes

D3D12 back-buffer lifecycle

Layer / File(s) Summary
Frame state and swapchain accessors
code/framework/src/graphics/backend/d3d12.h
FrameContext drops _mainRenderTargetResource, _barrier is initialized at backend scope, _currentBackBuffer is added, and GetSwapChain() / SetSwapChain() are declared.
Init-time RTV setup and back-buffer acquisition
code/framework/src/graphics/backend/d3d12.cpp
Init only stores reserved RTV descriptor handles, and Begin acquires the current swapchain buffer, creates its RTV, and transitions that buffer for rendering.
End and shutdown release
code/framework/src/graphics/backend/d3d12.cpp
End returns early when _currentBackBuffer is absent, performs the present transition and submission, and releases _currentBackBuffer; Shutdown clears any remaining _currentBackBuffer and stops releasing frame-context render-target resources.

Sequence Diagram(s)

sequenceDiagram
  participant D3D12Backend
  participant IDXGISwapChain3
  participant FrameContext
  D3D12Backend->>FrameContext: assign reserved main render target descriptor in Init()
  D3D12Backend->>IDXGISwapChain3: GetCurrentBackBufferIndex()
  D3D12Backend->>IDXGISwapChain3: GetBuffer(index, _currentBackBuffer)
  D3D12Backend->>D3D12Backend: CreateRenderTargetView(_currentBackBuffer, frameContext._mainRenderTargetDescriptor)
  D3D12Backend->>D3D12Backend: transition _currentBackBuffer for rendering
  D3D12Backend->>D3D12Backend: transition _currentBackBuffer for present
  D3D12Backend->>D3D12Backend: release _currentBackBuffer in End()
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • zpl-zak

Poem

Hop hop, I fetched the buffer bright,
Reserved the RTV, set it right.
I render, present, then let it go,
So every frame can start the show. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main D3D12 back-buffer acquisition change and the resize/fullscreen fix.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@code/framework/src/graphics/backend/d3d12.h`:
- Around line 62-64: `SetSwapChain` currently only replaces `_swapChain` and
leaves the frame-state derived from `Init()` stale. Update the
`D3D12Backend::SetSwapChain` flow to rebuild swapchain-dependent state when a
new `IDXGISwapChain3` is assigned: refresh `_frameBufferCount`,
resize/reinitialize `_frameContext`, and ensure any RTV/descriptor resources
tied to the old buffer count are recreated or validated before `Begin()` uses
them.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 23cdfd0f-e3a7-4d96-9bc6-0b6e0500af19

📥 Commits

Reviewing files that changed from the base of the PR and between 6a7378e and 3f973eb.

📒 Files selected for processing (2)
  • code/framework/src/graphics/backend/d3d12.cpp
  • code/framework/src/graphics/backend/d3d12.h

Comment thread code/framework/src/graphics/backend/d3d12.h
The backend cached the swapchain back buffers for the process lifetime, so
the game's ResizeBuffers failed (DXGI_ERROR_INVALID_CALL) and UE4 crashed on
any fullscreen/resolution change. Acquire the back buffer fresh in Begin()
and release it in End() so no reference is held across frames.
@Segfaultd Segfaultd merged commit b9dbb64 into MafiaHub:develop Jun 25, 2026
1 check passed
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.

2 participants