Skip to content

fix(export): unify depth export decode path across local and remote modes#242

Merged
BANANASJIM merged 1 commit into
masterfrom
fix/depth-export-consistency
Jun 10, 2026
Merged

fix(export): unify depth export decode path across local and remote modes#242
BANANASJIM merged 1 commit into
masterfrom
fix/depth-export-consistency

Conversation

@BANANASJIM

@BANANASJIM BANANASJIM commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary

Depth export previously produced different images per replay mode: local mode wrote an RGBA PNG with linear depth in the red channel (RenderDoc SaveTexture behavior), while remote mode (since #237) wrote a min-max-stretched grayscale PNG via GetTextureData + local decode. Same capture, visually different files — cross-mode golden comparisons were impossible.

Depth export now uses one pipeline in both modes: _handle_rt_depth always tries the GetTextureData + grayscale decode path first. Output is byte-identical between local and remote replay for decodable depth formats.

Behavior change

Local depth PNGs change from red-channel RGBA (linear, unstretched) to grayscale mode-L with min-max stretch — now matching remote output exactly. Color/texture export is unchanged (local still uses SaveTexture).

Fallback

When the decoder rejects a format (combined depth-stencil D16S8/D24S8/D32S8/S8, MSAA), local mode falls back to the previous SaveTexture path verbatim, preserving existing capability; remote mode returns -32002 as before. A texture-map miss stays -32001 with no fallback.

Testing

  • 5 new unit tests: local uses GetTextureData (SaveTexture stubbed to fail), grayscale mode-L output, local D24S8 SaveTexture fallback, remote D24S8 stays -32002 with SaveTexture never called, local/remote byte-identical D16. Binary-daemon mock state extended with a depth texture entry.
  • Real-GPU verification on AMD RX 7600 (RADV), vkcube D16 capture: local and remote depth PNGs are byte-identical (same sha256); color rt/texture export and rdc snapshot (depth.png + color0.png) unaffected. D24S8 could not be exercised on RADV (format unsupported by the driver); the fallback branch is covered by unit tests.
  • Full suite: 2974 passed; lint + mypy strict clean.

Note for remote testing on dual-stack hosts: use --proxy 127.0.0.1:<port> rather than localhostrenderdoccmd remoteserver binds IPv4 only while localhost may resolve to ::1.

Summary by CodeRabbit

  • Bug Fixes

    • Unified depth PNG export behavior between local and remote modes, ensuring consistent grayscale output format.
    • Added automatic fallback mechanism for unsupported depth formats to maintain export reliability.
  • Tests

    • Expanded test coverage for local and remote depth export scenarios.

…odes

Local depth export previously called SaveTexture, producing an RGBA PNG
with linear depth in the red channel, while remote mode used
GetTextureData + _decode_texture_png to produce a grayscale mode-L PNG.
The same capture yielded a different file per mode, breaking cross-mode
golden comparisons.

_handle_rt_depth now always attempts _export_remote(is_depth=True) first,
regardless of state.is_remote. For combined depth-stencil and MSAA formats
the decoder returns None (-32002); in local mode this falls back to the
existing SaveTexture path, while remote mode returns the error unchanged. A
tex_map miss stays -32001 with no fallback.

Behaviour change (changelog-worthy): local depth PNGs are now grayscale
mode-L with min-max stretch, matching remote mode; scripts reading the red
channel of a locally-exported depth PNG must be updated.
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements a unified depth PNG export behavior where local depth export (rdc rt <EID> --depth -o ...) produces the same grayscale mode-L output as remote mode via shared GetTextureData decoding, with a local fallback to SaveTexture for combined depth-stencil formats that decode to None (error -32002).

Changes

Depth Export Consistency Implementation

Layer / File(s) Summary
Specification & Planning
openspec/changes/2026-06-09-depth-export-consistency/proposal.md, tasks.md, test-plan.md
OpenSpec documents the goal (unified grayscale output), cross-mode divergence (local SaveTexture vs remote GetTextureData decode), implementation direction (_handle_rt_depth unification with -32002 fallback for D24S8), regression risks across depth formats, test implications (mock setup, grayscale assertions, byte-identical parity), and manual GPU verification steps.
Handler Implementation & Documentation
src/rdc/handlers/texture.py, src/rdc/commands/snapshot.py
_handle_rt_depth now routes both local and remote depth export through _export_remote(..., is_depth=True), then conditionally falls back to SaveTexture when decode fails with -32002 and is_remote=False; snapshot.py comment clarified to describe warning behavior for unsupported depth formats.
Test Mock Setup
tests/unit/test_binary_daemon.py
Adds ResourceFormat import and extends texture fixture with a D16 depth texture resource (ResourceId 500) and _DEPTH_500_DATA payload; mock GetTextureData returns depth bytes for that resource id.
Test Coverage
tests/unit/test_tex_stats_handler.py
Introduces _local_depth_state helper and five new test cases: local decodable formats skip SaveTexture, local D16 produces grayscale PNG, local D24S8 falls back to SaveTexture, remote D24S8 returns error unchanged, and local vs remote D16 outputs are byte-identical.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • BANANASJIM/rdc-cli#236: Proposes unifying local and remote depth export to use GetTextureData for remote and handle the -32002 decode error; this PR implements that proposal with the local fallback to SaveTexture.

Possibly related PRs

  • BANANASJIM/rdc-cli#237: Introduces the remote depth decode machinery via GetTextureData and _decode_texture_png(is_depth=True) that this PR reuses for local mode with the -32002 fallback condition.

Poem

🐰 The rabbit hops from surface to depth,
Now local and remote share one breath,
Grayscale mode-L with min-max care,
Byte-identical parity everywhere—
Where D24S8 falters, SaveTexture's there!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% 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 'fix(export): unify depth export decode path across local and remote modes' accurately summarizes the main change: unifying the depth export decode path for both local and remote modes to produce consistent output.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/depth-export-consistency

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.

@BANANASJIM

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

🧹 Nitpick comments (1)
tests/unit/test_binary_daemon.py (1)

125-126: 💤 Low value

Consider using a more varied depth pattern for better test coverage.

The current _DEPTH_500_DATA pattern is [0, 65535, 65535, 65535] (min, max, max, max), which is simple but lacks dynamic range. The depth tests in test_tex_stats_handler.py (lines 491, 548) use [0, 16384, 49152, 65535] (0%, 25%, 75%, 100%), which provides better gradient coverage and would make the shared mock more useful for future tests.

♻️ Optional refactor for consistency
-# D16 2x2 depth bytes for ResourceId(500): width*height*compCount*compByteWidth = 8.
-_DEPTH_500_DATA = (0).to_bytes(2, "little") + (65535).to_bytes(2, "little") * 3
+# D16 2x2 depth bytes for ResourceId(500): [0, 16384, 49152, 65535] gradient.
+_DEPTH_500_DATA = b"".join(
+    x.to_bytes(2, "little") for x in [0, 16384, 49152, 65535]
+)
🤖 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 `@tests/unit/test_binary_daemon.py` around lines 125 - 126, The test uses a
non-varying depth pattern in the constant _DEPTH_500_DATA (currently [0, 65535,
65535, 65535]); replace it with a more varied gradient (for example [0, 16384,
49152, 65535]) to match the depth coverage used in test_tex_stats_handler and
improve test usefulness; update the bytes construction in _DEPTH_500_DATA so
each value is converted with (value).to_bytes(2, "little") in the same order and
keep the surrounding concatenation unchanged so existing consumers of
_DEPTH_500_DATA continue to work.
🤖 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.

Nitpick comments:
In `@tests/unit/test_binary_daemon.py`:
- Around line 125-126: The test uses a non-varying depth pattern in the constant
_DEPTH_500_DATA (currently [0, 65535, 65535, 65535]); replace it with a more
varied gradient (for example [0, 16384, 49152, 65535]) to match the depth
coverage used in test_tex_stats_handler and improve test usefulness; update the
bytes construction in _DEPTH_500_DATA so each value is converted with
(value).to_bytes(2, "little") in the same order and keep the surrounding
concatenation unchanged so existing consumers of _DEPTH_500_DATA continue to
work.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9b10356b-a62d-4196-8898-59418e03275c

📥 Commits

Reviewing files that changed from the base of the PR and between f36b41e and c7c2168.

📒 Files selected for processing (7)
  • openspec/changes/2026-06-09-depth-export-consistency/proposal.md
  • openspec/changes/2026-06-09-depth-export-consistency/tasks.md
  • openspec/changes/2026-06-09-depth-export-consistency/test-plan.md
  • src/rdc/commands/snapshot.py
  • src/rdc/handlers/texture.py
  • tests/unit/test_binary_daemon.py
  • tests/unit/test_tex_stats_handler.py

@BANANASJIM BANANASJIM merged commit 8923bc6 into master Jun 10, 2026
17 checks passed
@BANANASJIM BANANASJIM deleted the fix/depth-export-consistency branch June 10, 2026 07:05
BANANASJIM added a commit that referenced this pull request Jun 10, 2026
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