Skip to content

Add engine.renderingInfo for runtime memory tracking#2910

Open
GuoLei1990 wants to merge 13 commits intogalacean:dev/2.0from
GuoLei1990:suport-vram
Open

Add engine.renderingInfo for runtime memory tracking#2910
GuoLei1990 wants to merge 13 commits intogalacean:dev/2.0from
GuoLei1990:suport-vram

Conversation

@GuoLei1990
Copy link
Member

@GuoLei1990 GuoLei1990 commented Mar 1, 2026

Summary

  • Add RenderingInfo class exposed via engine.renderingInfo with three readonly properties: textureMemory, bufferMemory, and totalMemory (bytes)
  • Track memory at resource lifecycle: accumulate on creation, subtract on destruction
  • Covers Texture2D, TextureCube, Texture2DArray, Buffer, and RenderTarget renderbuffers (depth renderbuffer + MSAA color renderbuffers)
  • Handle device loss correctly: reset counters to zero on context lost, re-accumulate on resource rebuild
  • Add TextureUtils.getTextureByteCount() and getMipLevelByteCount() supporting all 30+ TextureFormat values including compressed formats (BC, ETC, PVRTC, ASTC)

Motivation

Web engines have no access to native GPU profiling tools. Unlike desktop engines where external profilers (RenderDoc, Xcode GPU Debugger) can inspect VRAM usage, WebGL provides zero visibility into how much memory resources consume. This makes several real-world problems hard to solve:

  • WebGL context loss prevention: Browsers kill the GL context when memory pressure is too high. Without tracking, developers have no way to predict or prevent this.
  • Adaptive quality control: Applications that dynamically load content (e.g. open-world scenes, user-generated assets) need a memory budget to decide when to reduce texture quality or evict resources.
  • Memory leak detection: Long-running applications (editors, dashboards) need to verify that destroyed resources actually release memory. Comparing totalMemory before and after operations makes leaks immediately visible.
  • Device loss recovery verification: After context restore, comparing totalMemory against pre-loss values confirms whether all resources were successfully rebuilt.

API

const info = engine.renderingInfo;
info.textureMemory; // bytes
info.bufferMemory;  // bytes
info.totalMemory;   // bytes
Design
Follows Godot's RenderingServer.get_rendering_info() pattern: zero-overhead bookkeeping at resource create/destroy points, no per-frame cost. RenderingInfo is designed as an extensible container for future rendering statistics (e.g. draw calls).

Test plan

  • Create textures and buffers, verify textureMemory / bufferMemory increase accordingly
  • Destroy resources, verify counters decrease back to 0
  • Verify MSAA RenderTarget accounts for extra renderbuffer memory
  • Simulate context loss, verify counters reset to 0 and recover after rebuild

Summary by CodeRabbit

  • New Features

    • Exposed rendering statistics in the engine for live GPU memory insight (textures, buffers, total); improved texture size accounting including mipmaps and multisample impact.
  • Bug Fixes

    • Memory counters reliably update during resource creation, rebuilds, destruction, and on device loss/restoration.
  • Tests

    • Added comprehensive tests validating memory accounting across textures, buffers, render targets, and device recovery.

@GuoLei1990 GuoLei1990 added the enhancement New feature or request label Mar 1, 2026
@GuoLei1990 GuoLei1990 linked an issue Mar 1, 2026 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Mar 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Rendering memory accounting added: new RenderingStatistics tracks texture and buffer memory; Engine exposes it and resets on device loss. Textures, buffers, render targets update statistics on create, rebuild, and destroy. Tests validate memory accounting and device-loss/restored behavior.

Changes

Cohort / File(s) Summary
Statistics Infrastructure
packages/core/src/asset/RenderingStatistics.ts, packages/core/src/Engine.ts, packages/core/src/index.ts
Add RenderingStatistics with textureMemory, bufferMemory, totalMemory accessors; Engine gains renderingStatistics getter and resets stats on device loss; export added to index.
Texture Memory Tracking
packages/core/src/texture/Texture.ts, packages/core/src/texture/Texture2D.ts, packages/core/src/texture/Texture2DArray.ts, packages/core/src/texture/TextureCube.ts
Add per-texture _gpuMemorySize; compute with TextureUtils on construction; increment engine texture memory on create/rebuild and decrement on destroy (respecting content-loss).
Texture Utilities
packages/core/src/texture/TextureUtils.ts
Add getTextureByteCount and getMipLevelByteCount to compute byte counts per mip and total across formats (including compressed and depth/stencil).
Buffer Memory Tracking
packages/core/src/graphic/Buffer.ts
Account buffer GPU memory: increment engine buffer memory on construction and rebuild; decrement on destruction (respecting content-loss).
Render Target Memory Tracking
packages/core/src/texture/RenderTarget.ts
Track renderbuffer GPU memory (_renderbufferGpuMemorySize); compute on create/rebuild (handles MSAA and depth formats) and decrement on destroy.
Memory Accounting Tests
tests/src/core/RenderingStatistics.test.ts
Add tests covering texture (including mipmaps and cube), buffer, render target memory accounting, destruction effects, totalMemory, and device lost/restored reset and recovery behavior.

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant Engine
  participant Texture as Texture/System
  participant Buffer as Buffer/System
  participant RenderTarget as RT/System

  rect rgba(100,150,240,0.5)
  App->>Engine: create Texture2D(width,height,format...)
  Engine->>Texture: construct Texture2D
  Texture->>Engine: compute _gpuMemorySize via TextureUtils
  Texture->>Engine: Engine.renderingStatistics._textureMemory += size
  end

  rect rgba(120,200,140,0.5)
  App->>Engine: create Buffer(data)
  Engine->>Buffer: construct Buffer
  Buffer->>Engine: Engine.renderingStatistics._bufferMemory += byteLength
  end

  rect rgba(240,180,90,0.5)
  App->>Engine: create RenderTarget(...)
  Engine->>RenderTarget: construct RT & platform target
  RenderTarget->>Engine: compute renderbuffer size
  RenderTarget->>Engine: Engine.renderingStatistics._textureMemory += rbSize
  end

  rect rgba(200,100,180,0.5)
  App->>Engine: deviceLost()
  Engine->>Engine: Engine.renderingStatistics._reset()
  App->>Engine: deviceRestored()
  Engine->>Texture: rebuild textures -> re-increment _textureMemory
  Engine->>Buffer: rebuild buffers -> re-increment _bufferMemory
  Engine->>RenderTarget: rebuild RT -> re-increment rb memory
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I counted bytes beneath the moonlit thread,
Mipmaps hummed softly, buffers snuggled bed,
Renderbuffers whispered in six-fold tune,
Engine tallied, reset, then danced at noon,
A rabbit hops—memory tracked, worries shed 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main feature: adding a renderingInfo property to the engine for runtime memory tracking, which is the core objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@GuoLei1990 GuoLei1990 requested a review from zhuxudong March 1, 2026 11:22
@GuoLei1990 GuoLei1990 self-assigned this Mar 1, 2026
@GuoLei1990 GuoLei1990 requested review from zhuxudong and removed request for zhuxudong March 1, 2026 11:25
Copy link

@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: 4

🧹 Nitpick comments (1)
packages/core/src/asset/RenderingInfo.ts (1)

6-8: Encapsulate writable counters to preserve the readonly API contract.

At Line 6 and Line 8, _textureMemory / _bufferMemory are publicly writable on an exported class. External code can mutate them directly, which undermines textureMemory, bufferMemory, and totalMemory as authoritative stats.

♻️ Proposed refactor
 export class RenderingInfo {
   /** `@internal` */
-  _textureMemory: number = 0;
+  private _textureMemory: number = 0;
   /** `@internal` */
-  _bufferMemory: number = 0;
+  private _bufferMemory: number = 0;
+
+  /** `@internal` */
+  _addTextureMemory(delta: number): void {
+    this._textureMemory = Math.max(0, this._textureMemory + delta);
+  }
+
+  /** `@internal` */
+  _addBufferMemory(delta: number): void {
+    this._bufferMemory = Math.max(0, this._bufferMemory + delta);
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/asset/RenderingInfo.ts` around lines 6 - 8, Make
_textureMemory and _bufferMemory non-public to preserve the readonly API: change
the fields on class RenderingInfo to private (e.g., private _textureMemory:
number = 0; private _bufferMemory: number = 0;) and replace external direct
mutations with internal mutator methods (e.g., add private or `@internal` methods
like addTextureMemory(amount: number) / addBufferMemory(amount: number) or
setTextureMemory(value: number) / setBufferMemory(value: number)) so external
code can only read via the existing textureMemory, bufferMemory and totalMemory
getters; update any call sites to use the new internal mutators rather than
writing to the underscored fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/texture/RenderTarget.ts`:
- Line 232: When destroying a RenderTarget, avoid unguarded subtraction of GPU
memory counters: in the RenderTarget method that currently does
"this._engine._renderingInfo._textureMemory -= this._renderbufferGpuMemorySize",
first verify the counter and size are valid (e.g. ensure
this._renderbufferGpuMemorySize > 0 and this._engine._renderingInfo and
this._engine._renderingInfo._textureMemory are defined and >=
this._renderbufferGpuMemorySize) before subtracting; after a successful subtract
set this._renderbufferGpuMemorySize = 0 so it won't be double-subtracted, and
skip the subtraction entirely if the checks fail (covers device/context-loss
reset windows).
- Line 196: The depth renderbuffer memory calculation in RenderTarget (variable
renderbufferMemory using TextureUtils.getMipLevelByteCount with depth, width,
height) is not accounting for multisampling; multiply the computed depth
mip-level byte count by the antiAliasing sample count (the same antiAliasing
value used for color renderbuffers) when antiAliasing > 1 so the depth memory
matches multisample allocations (consistent with GLRenderTarget.ts behavior
where depth uses renderbufferStorageMultisample).

In `@packages/core/src/texture/Texture.ts`:
- Line 241: The destruction path in Texture.ts always subtracts
this._gpuMemorySize from this._engine._renderingInfo._textureMemory which can go
negative if Engine._onDeviceLost() reset counters to zero; modify the destroy
logic in the Texture class (where this._engine._renderingInfo._textureMemory is
decremented) to clamp or guard the subtraction (e.g., only subtract up to the
current _textureMemory or set the result with Math.max(0, current -
this._gpuMemorySize)) so totals never become negative and undercount after
device loss/restoration.

In `@packages/core/src/texture/TextureUtils.ts`:
- Around line 153-154: In TextureUtils where TextureFormat.Depth32Stencil8 is
handled (the switch/case returning a byte count), fix the per-texel size from 5
to 8 bytes: replace the return expression currently using width * height * 5
with width * height * 8 so DEPTH32F_STENCIL8 reflects 64-bit (8-byte) allocation
per texel; keep the same function/switch structure and update only the numeric
multiplier for TextureFormat.Depth32Stencil8.

---

Nitpick comments:
In `@packages/core/src/asset/RenderingInfo.ts`:
- Around line 6-8: Make _textureMemory and _bufferMemory non-public to preserve
the readonly API: change the fields on class RenderingInfo to private (e.g.,
private _textureMemory: number = 0; private _bufferMemory: number = 0;) and
replace external direct mutations with internal mutator methods (e.g., add
private or `@internal` methods like addTextureMemory(amount: number) /
addBufferMemory(amount: number) or setTextureMemory(value: number) /
setBufferMemory(value: number)) so external code can only read via the existing
textureMemory, bufferMemory and totalMemory getters; update any call sites to
use the new internal mutators rather than writing to the underscored fields.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fab8031 and c9b782e.

📒 Files selected for processing (10)
  • packages/core/src/Engine.ts
  • packages/core/src/asset/RenderingInfo.ts
  • packages/core/src/graphic/Buffer.ts
  • packages/core/src/index.ts
  • packages/core/src/texture/RenderTarget.ts
  • packages/core/src/texture/Texture.ts
  • packages/core/src/texture/Texture2D.ts
  • packages/core/src/texture/Texture2DArray.ts
  • packages/core/src/texture/TextureCube.ts
  • packages/core/src/texture/TextureUtils.ts

Comment on lines +153 to +154
case TextureFormat.Depth32Stencil8:
return width * height * 5;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n packages/core/src/texture/TextureUtils.ts | head -170 | tail -30

Repository: galacean/engine

Length of output: 1261


🌐 Web query:

WebGL DEPTH32F_STENCIL8 texture format memory allocation bytes

💡 Result:

In WebGL 2, DEPTH32F_STENCIL8 corresponds to a 64-bit depth-stencil texel: 32-bit float depth + 8-bit stencil + 24 unused bits (padding/alignment), i.e. 8 bytes per texel. [1], [2]

So a single-level (no mipmaps) 2D texture allocation is roughly:

  • bytes ≈ width × height × 8

Actual GPU memory use can be higher due to implementation details (tiling/compression, row/page alignment, mipmaps, multisampling, etc.), but 8 B/texel is the correct nominal size for this format. [1], [2]

Sources:
[1] StackOverflow answer quoting GL_ARB_depth_buffer_float (“64-bit pixels … 32-bit float depth, 8 stencil, 24 unused”) (stackoverflow.com)
[2] Khronos Vulkan VkFormat entry for VK_FORMAT_D32_SFLOAT_S8_UINT (“optionally 24 bits unused”) (registry.khronos.org)

Citations:


Fix Depth32Stencil8 memory allocation calculation to 8 bytes.

The WebGL 2 DEPTH32F_STENCIL8 format allocates 64 bits (8 bytes) per texel: 32-bit float depth + 8-bit stencil + 24 bits padding for alignment. The current calculation of 5 bytes under-reports actual GPU memory usage.

Current code
      case TextureFormat.Depth32Stencil8:
        return width * height * 5;

Change 5 to 8.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/texture/TextureUtils.ts` around lines 153 - 154, In
TextureUtils where TextureFormat.Depth32Stencil8 is handled (the switch/case
returning a byte count), fix the per-texel size from 5 to 8 bytes: replace the
return expression currently using width * height * 5 with width * height * 8 so
DEPTH32F_STENCIL8 reflects 64-bit (8-byte) allocation per texel; keep the same
function/switch structure and update only the numeric multiplier for
TextureFormat.Depth32Stencil8.

@codecov
Copy link

codecov bot commented Mar 1, 2026

Codecov Report

❌ Patch coverage is 90.90909% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.35%. Comparing base (e42150a) to head (5fc6a16).
⚠️ Report is 5 commits behind head on dev/2.0.

Files with missing lines Patch % Lines
packages/core/src/texture/TextureUtils.ts 80.80% 19 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           dev/2.0    #2910      +/-   ##
===========================================
- Coverage    78.36%   78.35%   -0.01%     
===========================================
  Files          880      882       +2     
  Lines        96111    96513     +402     
  Branches      9602     9670      +68     
===========================================
+ Hits         75315    75624     +309     
- Misses       20634    20726      +92     
- Partials       162      163       +1     
Flag Coverage Δ
unittests 78.35% <90.90%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@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

♻️ Duplicate comments (2)
packages/core/src/texture/RenderTarget.ts (2)

196-196: ⚠️ Potential issue | 🟠 Major

Account depth renderbuffer memory with MSAA sample count.

Line 196 adds only single-sample depth bytes; for MSAA targets this under-reports memory.

🐛 Proposed fix
-      renderbufferMemory += TextureUtils.getMipLevelByteCount(<TextureFormat>depth, width, height);
+      const depthBytes = TextureUtils.getMipLevelByteCount(<TextureFormat>depth, width, height);
+      renderbufferMemory += antiAliasing > 1 ? depthBytes * antiAliasing : depthBytes;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/texture/RenderTarget.ts` at line 196, The depth
renderbuffer memory calculation in RenderTarget adds only a single-sample byte
count (renderbufferMemory += TextureUtils.getMipLevelByteCount(depth, width,
height)); update it to multiply the returned byte count by the MSAA sample count
so MSAA targets are accounted for (e.g., renderbufferMemory +=
TextureUtils.getMipLevelByteCount(depth, width, height) * Math.max(1,
this.samples || sampleCount)); reference the RenderTarget class, the
renderbufferMemory variable and TextureUtils.getMipLevelByteCount when making
the change and ensure you use the correct property name for the sample count
used by this render target.

232-232: ⚠️ Potential issue | 🟠 Major

Avoid unguarded subtraction after context-loss reset.

Line 232 can drive textureMemory negative when a render target is destroyed after counters were reset on device loss.

🐛 Proposed fix
   protected override _onDestroy(): void {
     super._onDestroy();
-    this._engine._renderingStatistics._textureMemory -= this._renderbufferGpuMemorySize;
+    const stats = this._engine._renderingStatistics;
+    stats._textureMemory = Math.max(0, stats._textureMemory - this._renderbufferGpuMemorySize);
+    this._renderbufferGpuMemorySize = 0;
     this._platformRenderTarget.destroy();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/texture/RenderTarget.ts` at line 232, When subtracting the
renderbuffer GPU memory from the engine counters in RenderTarget (the line using
this._engine._renderingStatistics._textureMemory and
this._renderbufferGpuMemorySize), guard against context-loss resets so the
counter cannot go negative: either check that _renderbufferGpuMemorySize > 0 and
that _textureMemory >= _renderbufferGpuMemorySize before subtracting, or clamp
the result with a max(0, current - size) assignment; apply this change where the
render target is destroyed/released so repeated/device-loss resets cannot drive
the counter below zero.
🧹 Nitpick comments (1)
tests/src/core/RenderingStatistics.test.ts (1)

100-127: Add regression tests for MSAA depth and destroy-during-loss paths.

Current coverage misses two important cases: (1) depth renderbuffer bytes with antiAliasing > 1, and (2) destroying resources while context is lost (counter underflow guard).

✅ Suggested test additions
+  it("RenderTarget depth renderbuffer scales with antiAliasing", () => {
+    const colorTexture = new Texture2D(engine, 64, 64, TextureFormat.R8G8B8A8, false, false);
+    const before = engine.renderingStatistics.textureMemory;
+    const rt = new RenderTarget(engine, 64, 64, colorTexture, TextureFormat.Depth24Stencil8, 4);
+    const after = engine.renderingStatistics.textureMemory;
+    // 64*64*4(depth) * 4 samples
+    expect(after - before).to.equal(64 * 64 * 4 * 4);
+    rt.destroy();
+    colorTexture.destroy();
+  });
+
+  it("destroy during device loss does not make counters negative", async () => {
+    const buffer = new Buffer(engine, BufferBindFlag.VertexBuffer, 256, BufferUsage.Static);
+    // `@ts-ignore`
+    engine._onDeviceLost();
+    buffer.destroy();
+    expect(engine.renderingStatistics.bufferMemory).to.equal(0);
+  });

Also applies to: 129-157

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/src/core/RenderingStatistics.test.ts` around lines 100 - 127, Add two
tests: (1) a MSAA depth test that creates a Texture2D and a RenderTarget with
antiAliasing > 1 (use RenderTarget(..., antiAliasing: 4) or set
renderTarget.antiAliasing = 4) and assert
engine.renderingStatistics.textureMemory increases by width * height * 4 *
samples (use the same width/height as the test); (2) a destroy-during-loss test
that simulates a lost context (set engine.isContextLost / the engine
context-lost flag) before calling RenderTarget.destroy and verify
engine.renderingStatistics.textureMemory does not underflow (i.e., equals the
value before creation/destruction). Reference the RenderTarget constructor,
renderTarget.antiAliasing, RenderTarget.destroy, Texture2D, TextureFormat and
engine.renderingStatistics.textureMemory when adding these assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/graphic/Buffer.ts`:
- Line 251: When destroying a Buffer, the line subtracting memory
(this._engine._renderingStatistics._bufferMemory -= this._byteLength) can drive
the counter negative during device-loss resets; update the Buffer.destroy logic
to guard the subtraction by either checking current value and only subtracting
Math.min(current, this._byteLength) or performing the subtraction then clamping
this._engine._renderingStatistics._bufferMemory = Math.max(0, ...). Refer to the
symbols this._engine._renderingStatistics._bufferMemory and this._byteLength in
Buffer.destroy to add the guard so stats never go below zero.

---

Duplicate comments:
In `@packages/core/src/texture/RenderTarget.ts`:
- Line 196: The depth renderbuffer memory calculation in RenderTarget adds only
a single-sample byte count (renderbufferMemory +=
TextureUtils.getMipLevelByteCount(depth, width, height)); update it to multiply
the returned byte count by the MSAA sample count so MSAA targets are accounted
for (e.g., renderbufferMemory += TextureUtils.getMipLevelByteCount(depth, width,
height) * Math.max(1, this.samples || sampleCount)); reference the RenderTarget
class, the renderbufferMemory variable and TextureUtils.getMipLevelByteCount
when making the change and ensure you use the correct property name for the
sample count used by this render target.
- Line 232: When subtracting the renderbuffer GPU memory from the engine
counters in RenderTarget (the line using
this._engine._renderingStatistics._textureMemory and
this._renderbufferGpuMemorySize), guard against context-loss resets so the
counter cannot go negative: either check that _renderbufferGpuMemorySize > 0 and
that _textureMemory >= _renderbufferGpuMemorySize before subtracting, or clamp
the result with a max(0, current - size) assignment; apply this change where the
render target is destroyed/released so repeated/device-loss resets cannot drive
the counter below zero.

---

Nitpick comments:
In `@tests/src/core/RenderingStatistics.test.ts`:
- Around line 100-127: Add two tests: (1) a MSAA depth test that creates a
Texture2D and a RenderTarget with antiAliasing > 1 (use RenderTarget(...,
antiAliasing: 4) or set renderTarget.antiAliasing = 4) and assert
engine.renderingStatistics.textureMemory increases by width * height * 4 *
samples (use the same width/height as the test); (2) a destroy-during-loss test
that simulates a lost context (set engine.isContextLost / the engine
context-lost flag) before calling RenderTarget.destroy and verify
engine.renderingStatistics.textureMemory does not underflow (i.e., equals the
value before creation/destruction). Reference the RenderTarget constructor,
renderTarget.antiAliasing, RenderTarget.destroy, Texture2D, TextureFormat and
engine.renderingStatistics.textureMemory when adding these assertions.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45f3ad2 and 56ed589.

📒 Files selected for processing (10)
  • packages/core/src/Engine.ts
  • packages/core/src/asset/RenderingStatistics.ts
  • packages/core/src/graphic/Buffer.ts
  • packages/core/src/index.ts
  • packages/core/src/texture/RenderTarget.ts
  • packages/core/src/texture/Texture.ts
  • packages/core/src/texture/Texture2D.ts
  • packages/core/src/texture/Texture2DArray.ts
  • packages/core/src/texture/TextureCube.ts
  • tests/src/core/RenderingStatistics.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/core/src/texture/TextureCube.ts
  • packages/core/src/texture/Texture2DArray.ts
  • packages/core/src/texture/Texture2D.ts
  • packages/core/src/texture/Texture.ts

Copy link

@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.

♻️ Duplicate comments (1)
packages/core/src/texture/TextureUtils.ts (1)

155-156: ⚠️ Potential issue | 🟡 Minor

Fix Depth32Stencil8 memory calculation to 8 bytes.

The WebGL 2 DEPTH32F_STENCIL8 format allocates 64 bits (8 bytes) per texel: 32-bit float depth + 8-bit stencil + 24 bits padding. The current value of 5 under-reports actual GPU memory.

🐛 Proposed fix
       case TextureFormat.Depth32Stencil8:
-        return width * height * 5;
+        return width * height * 8;

,

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/texture/TextureUtils.ts` around lines 155 - 156, The memory
calculation for TextureFormat.Depth32Stencil8 is incorrect (returns width *
height * 5); update the case handling for TextureFormat.Depth32Stencil8 in the
switch inside TextureUtils (the branch that currently returns width * height *
5) to return width * height * 8 to reflect the 64-bit (8 bytes) per-texel
allocation for DEPTH32F_STENCIL8.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/core/src/texture/TextureUtils.ts`:
- Around line 155-156: The memory calculation for TextureFormat.Depth32Stencil8
is incorrect (returns width * height * 5); update the case handling for
TextureFormat.Depth32Stencil8 in the switch inside TextureUtils (the branch that
currently returns width * height * 5) to return width * height * 8 to reflect
the 64-bit (8 bytes) per-texel allocation for DEPTH32F_STENCIL8.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56ed589 and 09e51ef.

📒 Files selected for processing (4)
  • packages/core/src/graphic/Buffer.ts
  • packages/core/src/texture/RenderTarget.ts
  • packages/core/src/texture/Texture.ts
  • packages/core/src/texture/TextureUtils.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/src/texture/Texture.ts
  • packages/core/src/graphic/Buffer.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Is there a way to get accurate or estimated VRAM usage?

1 participant