Skip to content

Graphics: (d3d12 pt II) SRV descriptor slot allocator#213

Open
Kheartz wants to merge 1 commit into
MafiaHub:developfrom
Kheartz:d3d12-srv-allocator
Open

Graphics: (d3d12 pt II) SRV descriptor slot allocator#213
Kheartz wants to merge 1 commit into
MafiaHub:developfrom
Kheartz:d3d12-srv-allocator

Conversation

@Kheartz

@Kheartz Kheartz commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Adds a bounded, shader-visible SRV slot pool on the D3D12 backend for upcoming web-view textures. The heap grows by a fixed kExtraSrvSlots (64) past the ImGui-reserved slots; AllocateSRVSlot/FreeSRVSlot hand out and reclaim indices into that range, and the slots share ImGui's heap so handles double as ImTextureID.

Guards, since the eventual consumer (CEF views) renders partly untrusted content into a heap shared with the trusted in-game UI:

  • the slot getters bounds-check and return a null handle for any out-of-range index, so an exhausted -1 or a stray id can never produce an out-of-heap descriptor
  • FreeSRVSlot rejects out-of-pool indices and double-frees via an in-use bitmap, so a bad id can't re-enter the free list and alias a live slot
  • a mutex serializes allocate/free against concurrent view lifecycle

Bounded by the fixed 64-slot cap. Gating (opt-in reservation) is left as a follow-up pending the rendering backend's configuration story; no consumer allocates slots yet.

Summary by CodeRabbit

  • New Features
    • Added SRV descriptor slot pooling for the graphics backend, reserving extra shader-visible descriptor space for dynamic use.
    • Introduced thread-safe APIs to allocate and free SRV slots, retrieve CPU/GPU descriptor handles for a slot, and query remaining free slot capacity.
  • Bug Fixes
    • Improved shutdown behavior by fully clearing the descriptor heap handle after release.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c230ba95-b70b-49ff-8710-22c5597b239d

📥 Commits

Reviewing files that changed from the base of the PR and between 79b9dbf and 1fb9e4a.

📒 Files selected for processing (2)
  • code/framework/src/graphics/backend/d3d12.cpp
  • code/framework/src/graphics/backend/d3d12.h
🚧 Files skipped from review as they are similar to previous changes (2)
  • code/framework/src/graphics/backend/d3d12.h
  • code/framework/src/graphics/backend/d3d12.cpp

Walkthrough

D3D12Backend gains a mutex-protected SRV descriptor slot pool. The shader-visible CBV/SRV/UAV heap is enlarged by kExtraSrvSlots (64) beyond the frame buffer count, and five new public methods expose slot allocation, freeing with double-free/range guards, CPU/GPU handle queries, and free-slot count reporting.

Changes

D3D12Backend SRV Slot Pool

Layer / File(s) Summary
Interface: constant, private fields, and public API
code/framework/src/graphics/backend/d3d12.h
Adds <mutex> include, kExtraSrvSlots = 64 constant, private pool tracking fields (_srvDescriptorSize, _srvHeapSize, _freeSrvSlots, _srvSlotInUse, _srvMutex), and five public method declarations for SRV slot lifecycle and handle queries.
Heap init, shutdown, and slot method implementations
code/framework/src/graphics/backend/d3d12.cpp
Init sizes the heap with _frameBufferCount + kExtraSrvSlots and populates descriptor size, heap size, in-use bitmap, and free-slot list. Shutdown nulls _srvHeap. Implements AllocateSRVSlot, FreeSRVSlot, GetSRVSlotCPUHandle, GetSRVSlotGPUHandle, and GetFreeSRVSlotCount.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Hoppity-hop through descriptors galore,
Sixty-four slots, who could ask for more?
A mutex stands guard at the heap's little door,
Allocate, free — keep the double-frees at bay,
CPU and GPU handles found right away!
The shader-visible heap is now stocked to the brim,
Thanks to a rabbit with pool-management whim. 🎩

🚥 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 pull request title accurately describes the main change: adding an SRV descriptor slot allocator to the D3D12 graphics backend. It is concise, specific, and clearly summarizes the primary contribution.
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 and usage tips.

@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

🧹 Nitpick comments (2)
code/framework/src/graphics/backend/d3d12.cpp (2)

108-122: 💤 Low value

Inconsistent nulling of heap pointers after Release.

_srvHeap is set to nullptr after release (line 112), but _rtvHeap is not. For consistency and to guard against accidental use-after-free, consider nulling both.

♻️ Proposed fix
         // release objects
         _rtvHeap->Release();
+        _rtvHeap = nullptr;
         _srvHeap->Release();
         _srvHeap = nullptr;
🤖 Prompt for 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.

In `@code/framework/src/graphics/backend/d3d12.cpp` around lines 108 - 122, In the
D3D12Backend::Shutdown() method, after calling _rtvHeap->Release(), add _rtvHeap
= nullptr; to match the pattern already applied to _srvHeap. This ensures
consistency in nulling heap pointers after release and guards against potential
use-after-free errors. The _srvHeap is already correctly set to nullptr after
its Release() call, so apply the same pattern to _rtvHeap immediately following
its Release() call.

50-59: 💤 Low value

Consider renaming extraSrvStart for clarity.

The variable name extraSrvStart is misleading since it equals _frameBufferCount - 1, which is one less than the actual starting index of extra slots. The math is correct (slots _frameBufferCount through _frameBufferCount + 63 are pushed), but the name suggests it's the start index when it's actually used as an offset base.

♻️ Proposed refactor for clarity
             // Manage slots that are not reserved for ImGui and headroom
             _srvDescriptorSize = pD3DDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
             _srvHeapSize       = desc.NumDescriptors;
             _srvSlotInUse.assign(_srvHeapSize, false);
             _freeSrvSlots.clear();
-            const auto extraSrvStart = _frameBufferCount - 1;
-            for (UINT i = kExtraSrvSlots; i > 0; i--) {
-                _freeSrvSlots.push_back(extraSrvStart + i);
+            const UINT extraSrvStart = _frameBufferCount;
+            for (UINT i = 0; i < kExtraSrvSlots; i++) {
+                _freeSrvSlots.push_back(extraSrvStart + kExtraSrvSlots - 1 - i);
             }

Or simply:

-            const auto extraSrvStart = _frameBufferCount - 1;
-            for (UINT i = kExtraSrvSlots; i > 0; i--) {
-                _freeSrvSlots.push_back(extraSrvStart + i);
-            }
+            for (UINT i = 0; i < kExtraSrvSlots; i++) {
+                _freeSrvSlots.push_back(_frameBufferCount + kExtraSrvSlots - 1 - i);
+            }
🤖 Prompt for 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.

In `@code/framework/src/graphics/backend/d3d12.cpp` around lines 50 - 59, The
variable extraSrvStart is misleadingly named because it is assigned the value
_frameBufferCount - 1 and used as an offset base (added to loop counter i in the
subsequent for loop), not as an actual starting index. Rename extraSrvStart to a
more descriptive name that better reflects its purpose as an offset base value
(such as extraSrvBaseOffset or slotBaseOffset) to clarify that it represents an
adjustment factor rather than a true starting index, then update the reference
to this variable in the _freeSrvSlots.push_back call.
🤖 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 63-67: Correct the spelling error in the documentation comments
for GetSRVSlotCPUHandle and GetSRVSlotGPUHandle methods by changing "Retreives"
to "Retrieves" in both comment lines to fix the grammar and improve
documentation quality.

---

Nitpick comments:
In `@code/framework/src/graphics/backend/d3d12.cpp`:
- Around line 108-122: In the D3D12Backend::Shutdown() method, after calling
_rtvHeap->Release(), add _rtvHeap = nullptr; to match the pattern already
applied to _srvHeap. This ensures consistency in nulling heap pointers after
release and guards against potential use-after-free errors. The _srvHeap is
already correctly set to nullptr after its Release() call, so apply the same
pattern to _rtvHeap immediately following its Release() call.
- Around line 50-59: The variable extraSrvStart is misleadingly named because it
is assigned the value _frameBufferCount - 1 and used as an offset base (added to
loop counter i in the subsequent for loop), not as an actual starting index.
Rename extraSrvStart to a more descriptive name that better reflects its purpose
as an offset base value (such as extraSrvBaseOffset or slotBaseOffset) to
clarify that it represents an adjustment factor rather than a true starting
index, then update the reference to this variable in the _freeSrvSlots.push_back
call.
🪄 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: 3bde4d04-db29-44f9-95ec-f70b9eb39c51

📥 Commits

Reviewing files that changed from the base of the PR and between 560fb1f and 79b9dbf.

📒 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 Outdated
Adds a bounded, shader-visible SRV slot pool on the D3D12 backend for
upcoming web-view textures. The heap grows by a fixed kExtraSrvSlots
(64) past the ImGui-reserved slots; AllocateSRVSlot/FreeSRVSlot hand
out and reclaim indices into that range, and the slots share ImGui's
heap so handles double as ImTextureID.

Guards, since the eventual consumer (CEF views) renders partly
untrusted content into a heap shared with the trusted in-game UI:
- the slot getters bounds-check and return a null handle for any
  out-of-range index, so an exhausted -1 or a stray id can never
  produce an out-of-heap descriptor
- FreeSRVSlot rejects out-of-pool indices and double-frees via an
  in-use bitmap, so a bad id can't re-enter the free list and alias
  a live slot
- a mutex serializes allocate/free against concurrent view lifecycle

Bounded by the fixed 64-slot cap. Gating (opt-in reservation) is left
as a follow-up pending the rendering backend's configuration story; no
consumer allocates slots yet.
@Kheartz Kheartz force-pushed the d3d12-srv-allocator branch from 79b9dbf to 1fb9e4a Compare June 15, 2026 17:19
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