Skip to content

fix(texture): export requested 3d texture slice - #271

Merged
BANANASJIM merged 2 commits into
BANANASJIM:masterfrom
Misaka-Mikoto-Tech:fix/texture3d-export-slice
Jul 22, 2026
Merged

fix(texture): export requested 3d texture slice#271
BANANASJIM merged 2 commits into
BANANASJIM:masterfrom
Misaka-Mikoto-Tech:fix/texture3d-export-slice

Conversation

@Misaka-Mikoto-Tech

@Misaka-Mikoto-Tech Misaka-Mikoto-Tech commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

What

Add rdc texture --slice so a requested 3D texture depth slice can be exported as a separate PNG.

Why

#269 fixed Texture3D metadata and tex-stats --slice validation, but rdc texture still exported only the default local slice and had inconsistent remote behavior.

Fixes #268.

How

  • Add --slice to rdc texture and route it through the texture VFS path.
  • Validate the requested slice against the mip-level depth for Texture3D (and array size for array textures).
  • In local replay, map the slice to TextureSave.slice.sliceIndex.
  • In remote replay, extract the requested slice when GetTextureData returns the full 3D mip volume.
  • Populate valid 3D slice paths in the VFS tree.
  • Add regression coverage for CLI routing, VFS availability, local export mapping, remote extraction, and invalid mip/slice combinations.

Test plan

  • pixi run check passes (lint + typecheck + tests)
  • Added/updated unit tests
  • Manual testing with a real .rdc capture (Android GLES capture: RainDropSplash01.dds, resource 8413, event 3235; exported slice 0 and slice 1 as distinct 64x64 PNGs)

Summary by CodeRabbit

  • New Features
    • Added --slice to the texture export command to select a texture-array slice or a 3D depth slice.
    • Introduced slice-specific VFS routes and per-mip slice nodes for exported PNGs.
    • Exported filenames now include the selected slice index.
  • Bug Fixes
    • Fixed 3D remote texture exporting to decode and return only the requested depth slice (defaulting to slice 0 when omitted).
    • Added clearer validation and error messages for out-of-range slice requests per mip.
  • Documentation
    • Updated the texture command quick reference to document --slice.

@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 trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0e01044c-bf15-47d4-a338-35418a706847

📥 Commits

Reviewing files that changed from the base of the PR and between fdeb5b1 and 753ec69.

📒 Files selected for processing (11)
  • docs-astro/src/data/commands.json
  • src/rdc/_skills/references/commands-quick-ref.md
  • src/rdc/commands/export.py
  • src/rdc/handlers/_helpers.py
  • src/rdc/handlers/texture.py
  • src/rdc/vfs/router.py
  • src/rdc/vfs/tree_cache.py
  • tests/unit/test_export_commands.py
  • tests/unit/test_tex_stats_handler.py
  • tests/unit/test_vfs_router.py
  • tests/unit/test_vfs_tree_cache.py
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/rdc/vfs/router.py
  • tests/unit/test_vfs_router.py
  • src/rdc/_skills/references/commands-quick-ref.md
  • src/rdc/handlers/_helpers.py
  • src/rdc/commands/export.py
  • tests/unit/test_export_commands.py
  • tests/unit/test_vfs_tree_cache.py
  • src/rdc/vfs/tree_cache.py
  • src/rdc/handlers/texture.py

📝 Walkthrough

Walkthrough

Changes

Texture export now supports array and 3D depth slices through the CLI, VFS routes, local saves, and remote PNG decoding. VFS skeletons expose slice nodes, with validation and regression tests covering default, explicit, and invalid slices.

Texture slice export

Layer / File(s) Summary
Slice-aware CLI and VFS entrypoints
src/rdc/commands/export.py, src/rdc/vfs/..., docs-astro/src/data/commands.json, src/rdc/_skills/references/commands-quick-ref.md
The --slice option, slice-specific VFS paths, generated slice nodes, routing, and command documentation are added.
Slice selection and decoding
src/rdc/handlers/_helpers.py, src/rdc/handlers/texture.py
Local and remote texture exports propagate slice indices; 3D payloads are reduced to the requested depth slice before decoding.
Slice export regression coverage
tests/unit/test_export_commands.py, tests/unit/test_tex_stats_handler.py, tests/unit/test_vfs_router.py, tests/unit/test_vfs_tree_cache.py
Tests cover CLI path selection, VFS routing and skeleton generation, default and explicit remote slices, mip-specific bounds, and local SaveTexture slice propagation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant VFS
  participant tex_export
  participant RenderDoc
  participant PNGDecoder
  CLI->>VFS: request texture mip slice path
  VFS->>tex_export: resolve id, mip, and slice
  tex_export->>RenderDoc: fetch or save requested subresource
  RenderDoc-->>tex_export: return texture data
  tex_export->>PNGDecoder: decode selected 3D depth slice
  PNGDecoder-->>CLI: return PNG output
Loading

Possibly related PRs

Suggested reviewers: bananasjim, bananasjim

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds texture export slicing, but #268 requires tex-stats slice validation and resource/descriptor depth metadata, which are not addressed here. Implement the tex-stats validation and metadata depth exposure requested by #268, or remove that issue link if this PR is only for export slicing.
Out of Scope Changes check ⚠️ Warning Most changes add rdc texture --slice export, VFS routing, docs, and tests, which are unrelated to the linked issue's tex-stats and metadata fix. Split the texture-export work into a separate PR or trim it back so this change only covers the linked tex-stats and metadata requirements.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 clearly matches the main change: adding support for exporting a requested 3D texture slice.
✨ 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

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

1048-1083: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Expand test coverage to include the slice=0 edge case.

This test verifies that slice=1 is passed down to SaveTexture, but it bypasses the falsy slice=0 edge case. Adding a check for slice=0 will guard against regressions where the default slice inadvertently falls back to -1 (exporting a grid).

♻️ Proposed refactor
     state = make_daemon_state(
         ctrl=ctrl,
         current_eid=100,
         rd=rd,
         tmp_path=tmp_path,
         tex_map={172: tex},
         is_remote=False,
     )
     resp, _ = _handle_request(rpc_request("tex_export", {"id": 172, "slice": 1}), state)
     assert "result" in resp
-    assert slice_indices == [1]
+
+    # Test explicit default (slice=0)
+    resp0, _ = _handle_request(rpc_request("tex_export", {"id": 172, "slice": 0}), state)
+    assert "result" in resp0
+
+    assert slice_indices == [1, 0]
🤖 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_tex_stats_handler.py` around lines 1048 - 1083, Extend
test_tex_export_local_texture3d_sets_requested_slice to issue a tex_export
request with slice=0 and verify SaveTexture receives sliceIndex 0, preserving
the existing slice=1 assertion and setup so the falsy value cannot fall back to
-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 `@src/rdc/handlers/_helpers.py`:
- Around line 238-247: Update _make_texsave to assign ts.slice.sliceIndex from
array_slice unconditionally, removing the truthiness guard so an explicit slice
value of 0 is preserved. Keep the existing TextureSliceMapping creation and
other export settings unchanged.

---

Nitpick comments:
In `@tests/unit/test_tex_stats_handler.py`:
- Around line 1048-1083: Extend
test_tex_export_local_texture3d_sets_requested_slice to issue a tex_export
request with slice=0 and verify SaveTexture receives sliceIndex 0, preserving
the existing slice=1 assertion and setup so the falsy value cannot fall back to
-1.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7cbb2716-2e7c-47b3-81d7-fd85bf3658b3

📥 Commits

Reviewing files that changed from the base of the PR and between dd8de12 and 05ae109.

📒 Files selected for processing (10)
  • src/rdc/_skills/references/commands-quick-ref.md
  • src/rdc/commands/export.py
  • src/rdc/handlers/_helpers.py
  • src/rdc/handlers/texture.py
  • src/rdc/vfs/router.py
  • src/rdc/vfs/tree_cache.py
  • tests/unit/test_export_commands.py
  • tests/unit/test_tex_stats_handler.py
  • tests/unit/test_vfs_router.py
  • tests/unit/test_vfs_tree_cache.py

Comment thread src/rdc/handlers/_helpers.py
@Misaka-Mikoto-Tech
Misaka-Mikoto-Tech force-pushed the fix/texture3d-export-slice branch from 05ae109 to fdeb5b1 Compare July 21, 2026 16:39

@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 trial has ended. Reactivate Greptile to resume code reviews.

@Misaka-Mikoto-Tech
Misaka-Mikoto-Tech force-pushed the fix/texture3d-export-slice branch from fdeb5b1 to fb0190c Compare July 21, 2026 16:46

@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 trial has ended. Reactivate Greptile to resume code reviews.

@BANANASJIM

Copy link
Copy Markdown
Owner

Thanks for the update. I re-reviewed the current head (fb0190c9) and reran the relevant tests. The local TextureSave.sliceIndex mapping and mip-level slice validation look good, and the focused unit tests, Ruff, formatting, and mypy all pass locally.

There are still a few blockers before merge:

  1. Remote ASTC Texture3D export still fails.

    The capture in Texture3D depth slices are rejected by tex-stats and omitted from resource metadata #268 is ASTC6x6. On the current head, I reproduced remote export with the same Texture3D, 64x64x4, seven-mip metadata; requesting slice 1 returns:

    format ASTC6x6_UNORM not supported for remote decode
    

    _select_3d_slice() only extracts Regular, R11G11B10, and R9G9B9E5 data. It returns ASTC data unchanged, after which _decode_texture_png() rejects the non-Regular format. The manual capture test is useful, but the PR description does not say whether it exercised remote replay; could you confirm that? Please add a remote ASTC Texture3D regression test. One viable implementation is to delegate block-compressed formats to the local ReplayController.SaveTexture backed by ReplayProxy, so RenderDoc performs the decode while the output path remains local.

  2. The new VFS slice path is not fully discoverable.

    The tree contains a leaf such as /textures/30/mips/0/slices/1.png, but /textures/30/mips/0 does not exist and /textures/30/mips only lists 0.png and 1.png. Direct access with a preconstructed full path works, but rdc ls/rdc tree cannot navigate to or discover the slice nodes. Please add the complete intermediate directory hierarchy, or use a layout such as /textures/<id>/slices/<slice>/mips/<mip>.png.

  3. The generated commands data is stale.

    Ruff itself passes. The Lint (ruff) job fails in the generated-file step because docs-astro/src/data/commands.json still lacks --slice. Running pixi run gen-commands and committing the generated change should resolve this.

All six Linux/Windows test-matrix jobs are passing. tex_raw --mip/--slice can remain a follow-up and is not a blocker here. Once the items above are addressed, I can re-review.

@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 trial has ended. Reactivate Greptile to resume code reviews.

@Misaka-Mikoto-Tech

Copy link
Copy Markdown
Contributor Author

Thanks — addressed the three blockers in follow-up commit 753ec69.

  1. Remote compressed Texture3D export now falls back to ReplayController.SaveTexture when local remote-data decoding is unavailable. The fallback preserves the requested mip and slice, with ASTC 3D regression coverage (including failure handling).
  2. Added the missing VFS intermediate nodes, so /textures/<id>/mips/<mip>/slices is discoverable via rdc ls / rdc tree.
  3. Ran pixi run gen-commands and committed the updated docs-astro/src/data/commands.json.

Validation:

  • PYTHONUTF8=1 pixi run check
  • PYTHONUTF8=1 pixi run check-commands
  • Manual local replay against the Android capture confirms the new VFS hierarchy is enumerable.

I will also validate the ASTC Texture3D path against a real Android remote replay capture when I have access to the device again. The current regression coverage exercises the ReplayController fallback path with the requested mip and slice.

@BANANASJIM BANANASJIM left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Re-reviewed the latest head (753ec69). The three previous blockers are resolved: remote block-compressed Texture3D export now uses the client-side ReplayController SaveTexture path with the requested mip/slice and tested failure handling; the missing VFS mip/slices intermediate nodes are present; and both generated command references are in sync.

Verification: 285 targeted unit tests passed, Ruff and mypy passed, both generator checks passed, and all required GitHub CI checks are green. An independent reviewer also verified the ReplayController -> ReplayProxy -> SaveTexture semantics against the RenderDoc source and found no P0-P3 issues.

The remaining gap is that the real Android ASTC capture was not rerun; given the regression coverage and verified RenderDoc call path, I consider that a non-blocking residual risk. Approved.

@BANANASJIM
BANANASJIM merged commit 420c568 into BANANASJIM:master Jul 22, 2026
17 checks passed
@Misaka-Mikoto-Tech
Misaka-Mikoto-Tech deleted the fix/texture3d-export-slice branch July 22, 2026 07:50
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.

Texture3D depth slices are rejected by tex-stats and omitted from resource metadata

2 participants