rdc-cli 0.6.2__tar.gz → 0.6.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rdc_cli-0.6.2/src/rdc_cli.egg-info → rdc_cli-0.6.3}/PKG-INFO +1 -1
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/data/commands.json +1 -1
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/_skills/references/commands-quick-ref.md +1 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/export.py +12 -2
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/_helpers.py +15 -6
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/texture.py +65 -5
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/vfs/router.py +6 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/vfs/tree_cache.py +13 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3/src/rdc_cli.egg-info}/PKG-INFO +1 -1
- rdc_cli-0.6.3/src/rdc_cli.egg-info/scm_version.json +8 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_export_commands.py +24 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_tex_stats_handler.py +146 -9
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_vfs_router.py +7 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_vfs_tree_cache.py +15 -0
- rdc_cli-0.6.2/src/rdc_cli.egg-info/scm_version.json +0 -8
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.commitlintrc.yml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.githooks/pre-commit +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.githooks/pre-push +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/CODEOWNERS +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/workflows/aur.yml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/workflows/ci.yml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/workflows/commitlint.yml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.github/workflows/docs.yml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.gitignore +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.python-version +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/.release-please-manifest.json +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/CONTRIBUTING.md +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/LICENSE +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/Makefile +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/README.md +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/SECURITY.md +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/aur/PKGBUILD +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/aur/stable/PKGBUILD +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docker/Dockerfile +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/astro.config.mjs +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/package-lock.json +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/package.json +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/public/.nojekyll +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/public/favicon.svg +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Commands.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Demo.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Features.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Footer.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Hero.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Install.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Navbar.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Philosophy.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/Terminal.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/components/ThemeSwitcher.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/data/replay.json +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/data/stats.json +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/layouts/Base.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/layouts/Docs.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/ai-integration.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/commands.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/design.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/examples.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/index.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/install.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/remote.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/usage.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/docs/vfs.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/pages/index.astro +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/src/styles/global.css +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/tailwind.config.mjs +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/tapes/pipeline.tape +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/tapes/quickstart.tape +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/tests/validate.mjs +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/docs-astro/tsconfig.json +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/mypy.ini +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/pixi.lock +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/pixi.toml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/pyproject.toml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/release-please-config.json +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/ruff.toml +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/build-renderdoc.sh +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/build_renderdoc.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/capture_fixture.sh +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/dev_install.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/e2e_test.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/ensure-renderdoc.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/ensure-renderdoc.sh +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/ensure-skill-link.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/gen-commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/gen-replay.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/gen-skill-ref.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/gen-stats.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/gen_and_check.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/setup-renderdoc.sh +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/setup-vulkan-samples.sh +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/setup_android_tools.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/setup_vulkan_samples.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/verify-package.sh +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/scripts/verify_package.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/setup.cfg +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/__init__.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/_build_renderdoc.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/_platform.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/_progress.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/_skills/SKILL.md +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/_skills/__init__.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/_transport.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/adapter.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/capture_core.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/cli.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/_helpers.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/android.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/assert_ci.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/assert_image.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/capture.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/capture_control.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/capturefile.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/cbuffer.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/completion.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/counters.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/debug.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/descriptors.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/diff.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/doctor.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/events.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/info.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/install_skill.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/mesh.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/pick_pixel.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/pipeline.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/pixel.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/remote.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/resources.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/script.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/search.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/serve.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/session.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/setup_renderdoc.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/shader_edit.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/snapshot.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/tex_stats.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/unix_helpers.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/unused_targets.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/usage.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/commands/vfs.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/daemon_client.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/daemon_server.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/diff/__init__.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/diff/alignment.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/diff/draws.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/diff/framebuffer.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/diff/pipeline.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/diff/resources.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/diff/stats.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/diff/summary.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/discover.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/formatters/json_fmt.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/formatters/kv.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/formatters/options.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/formatters/tsv.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/__init__.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/_types.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/buffer.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/capture.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/capturefile.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/core.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/debug.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/descriptor.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/pipe_state.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/pixel.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/query.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/script.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/shader.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/shader_edit.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/unused.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/handlers/vfs.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/image_compare.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/protocol.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/remote_core.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/remote_state.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/services/__init__.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/services/diff_service.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/services/query_service.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/services/session_service.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/session_state.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/target_state.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/vfs/__init__.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc/vfs/formatter.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc_cli.egg-info/SOURCES.txt +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc_cli.egg-info/dependency_links.txt +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc_cli.egg-info/entry_points.txt +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc_cli.egg-info/requires.txt +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc_cli.egg-info/scm_file_list.json +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/src/rdc_cli.egg-info/top_level.txt +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/conftest.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/__init__.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/blackbox_test_catalog.md +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/conftest.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/e2e_helpers.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_advanced.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_assert.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_capture.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_capturefile.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_debug.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_diff.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_export.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_formats.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_presession.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_query.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_session.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_shader_edit.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/e2e/test_vfs.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/fixtures/gles-multipass-debug.apk +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/fixtures/gles-triangle-debug.apk +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/fixtures/gles_android_mali.rdc +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/fixtures/gles_multipass_mali.rdc +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/fixtures/hello_triangle.rdc +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/fixtures/vkcube.rdc +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/fixtures/vkcube_validation.rdc +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/integration/test_build_renderdoc_integration.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/integration/test_daemon_handlers_real.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/integration/test_mock_api_sync.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/integration/test_real_replay.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/integration/test_vulkan_samples.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/mocks/mock_renderdoc.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/conftest.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_adapter.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_android_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_assert_ci_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_assert_image_command.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_binary_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_buffer_decode.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_build_renderdoc.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_capture.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_capture_control.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_capture_core.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_capture_handlers.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_capturefile_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_capturefile_handlers.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_cbuffer_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_ci_files.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_cli.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_cli_session_flag.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_completion.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_count_shadermap.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_counters_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_counters_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_daemon_crash_regression.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_daemon_output_quality.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_daemon_pipeline_extended.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_daemon_server_unit.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_daemon_shader_api_fix.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_daemon_shader_extended.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_daemon_transport.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_debug_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_debug_handlers.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_descriptors_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_descriptors_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_dev_install.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_alignment.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_command.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_draws.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_framebuffer.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_pipeline.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_resources.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_service.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_stats.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_diff_summary.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_discover.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_doctor.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_doctor_hints.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_draws_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_draws_events_cli.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_draws_events_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_eid_completion.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_events_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_export_overlay.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_fix1_draws_pass_name.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_fix2_vfs_intermediate_dirs.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_fix3_friendly_pass_name.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_formatters.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_formatters_kv.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_gen_skill_ref.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_handlers_remote.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_image_compare.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_info_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_install_skill.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_json_errors.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_keep_remote.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_mesh_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_mesh_handler.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_mock_capture_types.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_mock_renderdoc.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_open_remote.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_output_options.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_overlay_handler.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pass_deps.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pick_pixel_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pick_pixel_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pipeline_cli_phase27.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pipeline_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pipeline_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pipeline_section_routing.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pipeline_shader.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pipeline_state.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pixel_history_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pixel_history_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_pixi_files.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_platform.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_progress.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_protocol.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_query_service.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_quickfix_batch.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_remote_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_remote_core.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_remote_replay.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_remote_setup.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_remote_state.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_remote_status_disconnect.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_require_pipe.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_resource_semantic_completion.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_resources_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_resources_filter.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_script_command.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_script_handler.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_search.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_semantic_completion.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_serve.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_session_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_session_completion.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_session_service.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_session_state.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_setup_renderdoc.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_setup_vulkan_samples.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_shader_edit_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_shader_edit_handlers.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_shader_preload.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_skill_structure.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_snapshot_command.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_split_binary.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_split_core.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_stats_event_count.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_target_state.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_tex_stats_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_tooling_files.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_unix_helpers_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_unused_targets.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_usage_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_usage_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_vfs_binary.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_vfs_commands.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_vfs_completion.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_vfs_daemon.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_vfs_formatter.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/tests/unit/test_windows_compat.py +0 -0
- {rdc_cli-0.6.2 → rdc_cli-0.6.3}/uv.lock +0 -0
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
"name": "texture",
|
|
200
200
|
"id": "texture",
|
|
201
201
|
"help": "Export texture as PNG.",
|
|
202
|
-
"usage": "rdc texture <ID> [-o PATH] [--mip INTEGER] [--raw]"
|
|
202
|
+
"usage": "rdc texture <ID> [-o PATH] [--mip INTEGER] [--slice INTEGER RANGE] [--raw]"
|
|
203
203
|
},
|
|
204
204
|
{
|
|
205
205
|
"name": "buffer",
|
|
@@ -1206,6 +1206,7 @@ Export texture as PNG.
|
|
|
1206
1206
|
|------|------|------|---------|
|
|
1207
1207
|
| `-o, --output` | Write to file | path | |
|
|
1208
1208
|
| `--mip` | Mip level (default 0) | integer | 0 |
|
|
1209
|
+
| `--slice` | Texture array or 3D depth slice (default 0) | integer range | 0 |
|
|
1209
1210
|
| `--raw` | Force raw output even on TTY | flag | |
|
|
1210
1211
|
|
|
1211
1212
|
## `rdc thumbnail`
|
|
@@ -119,10 +119,20 @@ def _complete_rt_target(
|
|
|
119
119
|
@click.argument("id", type=int, shell_complete=_complete_texture_id)
|
|
120
120
|
@click.option("-o", "--output", type=click.Path(), default=None, help="Write to file")
|
|
121
121
|
@click.option("--mip", default=0, type=int, help="Mip level (default 0)")
|
|
122
|
+
@click.option(
|
|
123
|
+
"--slice",
|
|
124
|
+
"array_slice",
|
|
125
|
+
default=0,
|
|
126
|
+
type=click.IntRange(min=0),
|
|
127
|
+
help="Texture array or 3D depth slice (default 0)",
|
|
128
|
+
)
|
|
122
129
|
@click.option("--raw", is_flag=True, help="Force raw output even on TTY")
|
|
123
|
-
def texture_cmd(id: int, output: str | None, mip: int, raw: bool) -> None:
|
|
130
|
+
def texture_cmd(id: int, output: str | None, mip: int, array_slice: int, raw: bool) -> None:
|
|
124
131
|
"""Export texture as PNG."""
|
|
125
|
-
|
|
132
|
+
if array_slice > 0:
|
|
133
|
+
vfs_path = f"/textures/{id}/mips/{mip}/slices/{array_slice}.png"
|
|
134
|
+
else:
|
|
135
|
+
vfs_path = f"/textures/{id}/mips/{mip}.png" if mip > 0 else f"/textures/{id}/image.png"
|
|
126
136
|
_export_vfs_path(vfs_path, output, raw)
|
|
127
137
|
|
|
128
138
|
|
|
@@ -235,21 +235,22 @@ def _build_shader_cache(state: DaemonState) -> None:
|
|
|
235
235
|
populate_shaders_subtree(state.vfs_tree, state.shader_meta)
|
|
236
236
|
|
|
237
237
|
|
|
238
|
-
def _make_texsave(rd: Any, resource_id: Any, mip: int = 0) -> Any:
|
|
238
|
+
def _make_texsave(rd: Any, resource_id: Any, mip: int = 0, array_slice: int = 0) -> Any:
|
|
239
239
|
"""Create a TextureSave object using the renderdoc module."""
|
|
240
240
|
ts = rd.TextureSave()
|
|
241
241
|
ts.resourceId = resource_id
|
|
242
242
|
ts.mip = mip
|
|
243
243
|
ts.slice = rd.TextureSliceMapping()
|
|
244
|
+
ts.slice.sliceIndex = array_slice
|
|
244
245
|
ts.destType = rd.FileType.PNG
|
|
245
246
|
return ts
|
|
246
247
|
|
|
247
248
|
|
|
248
|
-
def _make_subresource(rd: Any, mip: int = 0) -> Any:
|
|
249
|
+
def _make_subresource(rd: Any, mip: int = 0, array_slice: int = 0) -> Any:
|
|
249
250
|
"""Create a Subresource object using the renderdoc module."""
|
|
250
251
|
sub = rd.Subresource()
|
|
251
252
|
sub.mip = mip
|
|
252
|
-
sub.slice =
|
|
253
|
+
sub.slice = array_slice
|
|
253
254
|
sub.sample = 0
|
|
254
255
|
return sub
|
|
255
256
|
|
|
@@ -340,7 +341,15 @@ def _unpack_r9g9b9e5(words: Any) -> Any:
|
|
|
340
341
|
return np.stack([rm * scale, gm * scale, bm * scale], axis=-1).astype(np.float32)
|
|
341
342
|
|
|
342
343
|
|
|
343
|
-
def _decode_texture_png(
|
|
344
|
+
def _decode_texture_png(
|
|
345
|
+
rd: Any,
|
|
346
|
+
tex: Any,
|
|
347
|
+
raw: bytes,
|
|
348
|
+
mip: int,
|
|
349
|
+
*,
|
|
350
|
+
is_depth: bool,
|
|
351
|
+
depth_override: int | None = None,
|
|
352
|
+
) -> bytes | None:
|
|
344
353
|
"""Decode tightly packed GetTextureData bytes into PNG bytes.
|
|
345
354
|
|
|
346
355
|
Handles the full ``ResourceFormatType.Regular`` space deliberately: every
|
|
@@ -384,7 +393,7 @@ def _decode_texture_png(rd: Any, tex: Any, raw: bytes, mip: int, *, is_depth: bo
|
|
|
384
393
|
return None
|
|
385
394
|
width = max(1, tex.width >> mip)
|
|
386
395
|
height = max(1, tex.height >> mip)
|
|
387
|
-
depth_lvl = max(1, getattr(tex, "depth", 1) >> mip)
|
|
396
|
+
depth_lvl = depth_override or max(1, getattr(tex, "depth", 1) >> mip)
|
|
388
397
|
if len(raw) != width * height * depth_lvl * 4:
|
|
389
398
|
return None
|
|
390
399
|
words = np.frombuffer(raw, dtype=np.dtype("<u4")).reshape((depth_lvl * height, width))
|
|
@@ -410,7 +419,7 @@ def _decode_texture_png(rd: Any, tex: Any, raw: bytes, mip: int, *, is_depth: bo
|
|
|
410
419
|
|
|
411
420
|
width = max(1, tex.width >> mip)
|
|
412
421
|
height = max(1, tex.height >> mip)
|
|
413
|
-
depth_lvl = max(1, getattr(tex, "depth", 1) >> mip)
|
|
422
|
+
depth_lvl = depth_override or max(1, getattr(tex, "depth", 1) >> mip)
|
|
414
423
|
cc = fmt.compCount
|
|
415
424
|
cbw = fmt.compByteWidth
|
|
416
425
|
if cc <= 0 or len(raw) != width * height * depth_lvl * cc * cbw:
|
|
@@ -33,6 +33,33 @@ _OVERLAY_MAP: dict[str, int] = {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def _is_block_compressed(fmt: Any) -> bool:
|
|
37
|
+
"""Return whether RenderDoc identifies a format as block-compressed."""
|
|
38
|
+
block_format = getattr(fmt, "BlockFormat", None)
|
|
39
|
+
renderdoc_result = bool(block_format()) if callable(block_format) else False
|
|
40
|
+
return renderdoc_result or fmt.Name().upper().startswith(("ASTC", "BC", "EAC", "ETC", "PVRTC"))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _select_3d_slice(tex: Any, raw: bytes, mip: int, array_slice: int, rd: Any) -> bytes:
|
|
44
|
+
"""Return one depth slice when remote GetTextureData returns a whole 3D mip."""
|
|
45
|
+
depth = max(1, tex.depth >> mip)
|
|
46
|
+
if depth == 1:
|
|
47
|
+
return raw
|
|
48
|
+
width = max(1, tex.width >> mip)
|
|
49
|
+
height = max(1, tex.height >> mip)
|
|
50
|
+
fmt = tex.format
|
|
51
|
+
if fmt.type == rd.ResourceFormatType.Regular:
|
|
52
|
+
slice_size = width * height * fmt.compCount * fmt.compByteWidth
|
|
53
|
+
elif fmt.type in (rd.ResourceFormatType.R11G11B10, rd.ResourceFormatType.R9G9B9E5):
|
|
54
|
+
slice_size = width * height * 4
|
|
55
|
+
else:
|
|
56
|
+
return raw
|
|
57
|
+
if len(raw) != slice_size * depth:
|
|
58
|
+
return raw
|
|
59
|
+
start = array_slice * slice_size
|
|
60
|
+
return raw[start : start + slice_size]
|
|
61
|
+
|
|
62
|
+
|
|
36
63
|
def _handle_tex_info(
|
|
37
64
|
request_id: int, params: dict[str, Any], state: DaemonState
|
|
38
65
|
) -> tuple[dict[str, Any], bool]:
|
|
@@ -70,20 +97,36 @@ def _export_remote(
|
|
|
70
97
|
resource_id: Any,
|
|
71
98
|
temp_path: Path,
|
|
72
99
|
mip: int,
|
|
100
|
+
array_slice: int = 0,
|
|
73
101
|
*,
|
|
74
102
|
is_depth: bool = False,
|
|
103
|
+
allow_save_fallback: bool = False,
|
|
75
104
|
) -> tuple[dict[str, Any], bool]:
|
|
76
105
|
"""Fetch raw pixels over the wire and decode them locally to a PNG."""
|
|
77
106
|
controller = state.adapter.controller # type: ignore[union-attr]
|
|
78
|
-
sub = _make_subresource(state.rd, mip)
|
|
107
|
+
sub = _make_subresource(state.rd, mip, array_slice)
|
|
79
108
|
try:
|
|
80
109
|
raw = controller.GetTextureData(resource_id, sub)
|
|
81
110
|
except Exception as exc: # noqa: BLE001
|
|
82
111
|
return _error_response(request_id, -32002, f"GetTextureData failed: {exc}"), True
|
|
83
112
|
if not raw:
|
|
84
113
|
return _error_response(request_id, -32002, "no texture data returned"), True
|
|
85
|
-
|
|
114
|
+
if tex.type == state.rd.TextureType.Texture3D:
|
|
115
|
+
raw = _select_3d_slice(tex, raw, mip, array_slice, state.rd)
|
|
116
|
+
depth_override = 1 if tex.type == state.rd.TextureType.Texture3D else None
|
|
117
|
+
png = _decode_texture_png(
|
|
118
|
+
state.rd, tex, raw, mip, is_depth=is_depth, depth_override=depth_override
|
|
119
|
+
)
|
|
86
120
|
if png is None:
|
|
121
|
+
if allow_save_fallback and _is_block_compressed(tex.format):
|
|
122
|
+
texsave = _make_texsave(state.rd, resource_id, mip, array_slice)
|
|
123
|
+
success = controller.SaveTexture(texsave, str(temp_path))
|
|
124
|
+
if success and temp_path.exists():
|
|
125
|
+
return _result_response(
|
|
126
|
+
request_id,
|
|
127
|
+
{"path": str(temp_path), "size": temp_path.stat().st_size},
|
|
128
|
+
), True
|
|
129
|
+
return _error_response(request_id, -32002, "SaveTexture fallback failed"), True
|
|
87
130
|
fmt_name = tex.format.Name() if hasattr(tex.format, "Name") else ""
|
|
88
131
|
return _error_response(
|
|
89
132
|
request_id, -32002, f"format {fmt_name} not supported for remote decode"
|
|
@@ -107,6 +150,7 @@ def _handle_tex_export(
|
|
|
107
150
|
return _error_response(request_id, -32002, "temp directory not available"), True
|
|
108
151
|
res_id = int(params.get("id", 0))
|
|
109
152
|
mip = int(params.get("mip", 0))
|
|
153
|
+
array_slice = int(params.get("slice", 0))
|
|
110
154
|
tex = state.tex_map.get(res_id)
|
|
111
155
|
if tex is None:
|
|
112
156
|
return _error_response(request_id, -32001, f"texture {res_id} not found"), True
|
|
@@ -114,15 +158,31 @@ def _handle_tex_export(
|
|
|
114
158
|
return _error_response(
|
|
115
159
|
request_id, -32001, f"mip {mip} out of range (max: {tex.mips - 1})"
|
|
116
160
|
), True
|
|
161
|
+
slice_count = tex.arraysize
|
|
162
|
+
if tex.type == state.rd.TextureType.Texture3D:
|
|
163
|
+
slice_count = max(1, tex.depth >> mip)
|
|
164
|
+
if array_slice < 0 or array_slice >= slice_count:
|
|
165
|
+
return _error_response(
|
|
166
|
+
request_id, -32001, f"slice {array_slice} out of range (max: {slice_count - 1})"
|
|
167
|
+
), True
|
|
117
168
|
eid = int(params.get("eid", state.current_eid))
|
|
118
169
|
err = _set_frame_event(state, eid)
|
|
119
170
|
if err:
|
|
120
171
|
return _error_response(request_id, -32002, err), True
|
|
121
|
-
temp_path = state.temp_dir / f"tex_{res_id}_mip{mip}.png"
|
|
172
|
+
temp_path = state.temp_dir / f"tex_{res_id}_mip{mip}_slice{array_slice}.png"
|
|
122
173
|
if state.is_remote:
|
|
123
|
-
return _export_remote(
|
|
174
|
+
return _export_remote(
|
|
175
|
+
request_id,
|
|
176
|
+
state,
|
|
177
|
+
tex,
|
|
178
|
+
tex.resourceId,
|
|
179
|
+
temp_path,
|
|
180
|
+
mip,
|
|
181
|
+
array_slice,
|
|
182
|
+
allow_save_fallback=True,
|
|
183
|
+
)
|
|
124
184
|
controller = state.adapter.controller
|
|
125
|
-
texsave = _make_texsave(state.rd, tex.resourceId, mip)
|
|
185
|
+
texsave = _make_texsave(state.rd, tex.resourceId, mip, array_slice)
|
|
126
186
|
success = controller.SaveTexture(texsave, str(temp_path))
|
|
127
187
|
if not success or not temp_path.exists():
|
|
128
188
|
return _error_response(request_id, -32002, "SaveTexture failed"), True
|
|
@@ -206,6 +206,12 @@ _r(
|
|
|
206
206
|
"tex_export",
|
|
207
207
|
[("id", int), ("mip", int)],
|
|
208
208
|
)
|
|
209
|
+
_r(
|
|
210
|
+
r"/textures/(?P<id>\d+)/mips/(?P<mip>\d+)/slices/(?P<slice>\d+)\.png",
|
|
211
|
+
"leaf_bin",
|
|
212
|
+
"tex_export",
|
|
213
|
+
[("id", int), ("mip", int), ("slice", int)],
|
|
214
|
+
)
|
|
209
215
|
_r(r"/textures/(?P<id>\d+)/data", "leaf_bin", "tex_raw", [("id", int)])
|
|
210
216
|
|
|
211
217
|
_r("/buffers", "dir")
|
|
@@ -221,6 +221,19 @@ def build_vfs_skeleton(
|
|
|
221
221
|
tree.static[f"{prefix}/mips"] = VfsNode("mips", "dir", list(mip_children))
|
|
222
222
|
for i in range(mip_count):
|
|
223
223
|
tree.static[f"{prefix}/mips/{i}.png"] = VfsNode(f"{i}.png", "leaf_bin")
|
|
224
|
+
if getattr(getattr(t, "type", None), "name", "") == "Texture3D":
|
|
225
|
+
slice_count = max(1, getattr(t, "depth", 1) >> i)
|
|
226
|
+
else:
|
|
227
|
+
slice_count = getattr(t, "arraysize", 1)
|
|
228
|
+
if slice_count > 1:
|
|
229
|
+
mip_path = f"{prefix}/mips/{i}"
|
|
230
|
+
tree.static[f"{prefix}/mips"].children.append(str(i))
|
|
231
|
+
tree.static[mip_path] = VfsNode(str(i), "dir", ["slices"])
|
|
232
|
+
slices_path = f"{prefix}/mips/{i}/slices"
|
|
233
|
+
slice_children = [f"{j}.png" for j in range(1, slice_count)]
|
|
234
|
+
tree.static[slices_path] = VfsNode("slices", "dir", slice_children)
|
|
235
|
+
for j in range(1, slice_count):
|
|
236
|
+
tree.static[f"{slices_path}/{j}.png"] = VfsNode(f"{j}.png", "leaf_bin")
|
|
224
237
|
|
|
225
238
|
# /buffers
|
|
226
239
|
buf_ids = [str(int(getattr(b, "resourceId", 0))) for b in _buffers]
|
|
@@ -57,6 +57,30 @@ class TestTextureCmd:
|
|
|
57
57
|
vfs_calls = [c for c in calls if c[0] == "vfs_ls"]
|
|
58
58
|
assert any("/textures/42/mips/2.png" in str(c) for c in vfs_calls)
|
|
59
59
|
|
|
60
|
+
def test_texture_slice_path(self, monkeypatch: Any, tmp_path: Path) -> None:
|
|
61
|
+
"""--slice should encode the requested subresource in the VFS path."""
|
|
62
|
+
calls: list[tuple[str, dict[str, Any]]] = []
|
|
63
|
+
|
|
64
|
+
def mock_call(method: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
65
|
+
calls.append((method, dict(params) if params else {}))
|
|
66
|
+
if method == "vfs_ls":
|
|
67
|
+
return {"kind": "leaf_bin", "path": params.get("path", "/") if params else "/"}
|
|
68
|
+
temp = tmp_path / "export.bin"
|
|
69
|
+
temp.write_bytes(b"\x89PNG" + b"\x00" * 50)
|
|
70
|
+
return {"path": str(temp), "size": 54}
|
|
71
|
+
|
|
72
|
+
monkeypatch.setattr("rdc.commands.export.call", mock_call)
|
|
73
|
+
monkeypatch.setattr("rdc.commands.vfs.call", mock_call)
|
|
74
|
+
monkeypatch.setattr("rdc.commands.vfs._stdout_is_tty", lambda: False)
|
|
75
|
+
out_file = tmp_path / "slice.png"
|
|
76
|
+
runner = click.testing.CliRunner()
|
|
77
|
+
result = runner.invoke(
|
|
78
|
+
texture_cmd, ["42", "--mip", "2", "--slice", "3", "-o", str(out_file)]
|
|
79
|
+
)
|
|
80
|
+
assert result.exit_code == 0
|
|
81
|
+
vfs_calls = [c for c in calls if c[0] == "vfs_ls"]
|
|
82
|
+
assert any("/textures/42/mips/2/slices/3.png" in str(c) for c in vfs_calls)
|
|
83
|
+
|
|
60
84
|
def test_texture_tty_protection(self, monkeypatch: Any, tmp_path: Path) -> None:
|
|
61
85
|
mock = _make_mockcall(tmp_path)
|
|
62
86
|
monkeypatch.setattr("rdc.commands.export.call", mock)
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import io
|
|
6
6
|
import struct
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
|
|
8
9
|
import mock_renderdoc as rd
|
|
9
10
|
import numpy as np
|
|
@@ -432,8 +433,10 @@ def test_tex_export_remote_length_mismatch_errors(tmp_path: object) -> None:
|
|
|
432
433
|
assert resp["error"]["code"] == -32002
|
|
433
434
|
|
|
434
435
|
|
|
435
|
-
def
|
|
436
|
-
fmt = rd.ResourceFormat(
|
|
436
|
+
def test_tex_export_remote_non_block_special_format_rejected(tmp_path: object) -> None:
|
|
437
|
+
fmt = rd.ResourceFormat(
|
|
438
|
+
name="R10G10B10A2_UNORM", compByteWidth=4, compCount=4, compType=2, type=12
|
|
439
|
+
)
|
|
437
440
|
tex = rd.TextureDescription(resourceId=rd.ResourceId(96), width=4, height=4, format=fmt)
|
|
438
441
|
state = _remote_state(tex, b"\x00" * 8, tmp_path)
|
|
439
442
|
resp, _ = _handle_request(rpc_request("tex_export", {"id": 96}), state)
|
|
@@ -736,23 +739,117 @@ def test_tex_export_remote_no_data_rejected(tmp_path: object) -> None:
|
|
|
736
739
|
assert "no texture data" in resp["error"]["message"]
|
|
737
740
|
|
|
738
741
|
|
|
739
|
-
def
|
|
740
|
-
#
|
|
741
|
-
# Slices are tiled vertically into one (depth*height, width) image.
|
|
742
|
+
def test_tex_export_remote_3d_defaults_to_slice_zero(tmp_path: object) -> None:
|
|
743
|
+
# Remote GetTextureData returns the whole 3D mip, but the export API returns one slice.
|
|
742
744
|
fmt = rd.ResourceFormat(name="R8G8B8A8_UNORM", compByteWidth=1, compCount=4, compType=2)
|
|
743
745
|
tex = rd.TextureDescription(
|
|
744
|
-
resourceId=rd.ResourceId(70),
|
|
746
|
+
resourceId=rd.ResourceId(70),
|
|
747
|
+
type=rd.TextureType.Texture3D,
|
|
748
|
+
width=2,
|
|
749
|
+
height=2,
|
|
750
|
+
depth=2,
|
|
751
|
+
format=fmt,
|
|
745
752
|
)
|
|
746
753
|
raw = bytes(range(2 * 2 * 2 * 4)) # depth*height*width*cc
|
|
747
754
|
state = _remote_state(tex, raw, tmp_path)
|
|
748
755
|
resp, running = _handle_request(rpc_request("tex_export", {"id": 70}), state)
|
|
749
756
|
assert running
|
|
750
757
|
img = _read_png(resp["result"]["path"])
|
|
751
|
-
assert img.size == (2,
|
|
758
|
+
assert img.size == (2, 2)
|
|
752
759
|
assert img.mode == "RGBA"
|
|
753
|
-
# First pixel of slice 0 and first pixel of slice 1 differ.
|
|
754
760
|
assert img.getpixel((0, 0)) == (0, 1, 2, 3)
|
|
755
|
-
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
def test_tex_export_remote_texture3d_exports_requested_slice(tmp_path: object) -> None:
|
|
764
|
+
fmt = rd.ResourceFormat(name="R8G8B8A8_UNORM", compByteWidth=1, compCount=4, compType=2)
|
|
765
|
+
tex = rd.TextureDescription(
|
|
766
|
+
resourceId=rd.ResourceId(170),
|
|
767
|
+
type=rd.TextureType.Texture3D,
|
|
768
|
+
width=2,
|
|
769
|
+
height=2,
|
|
770
|
+
depth=2,
|
|
771
|
+
format=fmt,
|
|
772
|
+
)
|
|
773
|
+
state = _remote_state(tex, b"", tmp_path)
|
|
774
|
+
ctrl = state.adapter.controller # type: ignore[union-attr]
|
|
775
|
+
slices = [bytes(range(16)), bytes(range(16, 32))]
|
|
776
|
+
|
|
777
|
+
def _get_texture_data(resource_id: object, sub: object) -> bytes:
|
|
778
|
+
del resource_id, sub
|
|
779
|
+
return b"".join(slices)
|
|
780
|
+
|
|
781
|
+
ctrl.GetTextureData = _get_texture_data # type: ignore[method-assign]
|
|
782
|
+
resp, _ = _handle_request(rpc_request("tex_export", {"id": 170, "slice": 1}), state)
|
|
783
|
+
img = _read_png(resp["result"]["path"])
|
|
784
|
+
assert img.size == (2, 2)
|
|
785
|
+
assert img.getpixel((0, 0)) == (16, 17, 18, 19)
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
def test_tex_export_remote_astc3d_falls_back_to_savetexture(tmp_path: object) -> None:
|
|
789
|
+
fmt = rd.ResourceFormat(name="ASTC6x6_UNORM", type=99)
|
|
790
|
+
tex = rd.TextureDescription(
|
|
791
|
+
resourceId=rd.ResourceId(173),
|
|
792
|
+
type=rd.TextureType.Texture3D,
|
|
793
|
+
width=64,
|
|
794
|
+
height=64,
|
|
795
|
+
depth=4,
|
|
796
|
+
mips=7,
|
|
797
|
+
format=fmt,
|
|
798
|
+
)
|
|
799
|
+
state = _remote_state(tex, b"\x00" * 256, tmp_path)
|
|
800
|
+
save_calls: list[tuple[int, int, str]] = []
|
|
801
|
+
controller = state.adapter.controller # type: ignore[union-attr]
|
|
802
|
+
original_save = controller.SaveTexture
|
|
803
|
+
|
|
804
|
+
def _spy(texsave: object, path: str) -> bool:
|
|
805
|
+
save_calls.append((texsave.mip, texsave.slice.sliceIndex, path))
|
|
806
|
+
return original_save(texsave, path)
|
|
807
|
+
|
|
808
|
+
controller.SaveTexture = _spy # type: ignore[method-assign]
|
|
809
|
+
resp, running = _handle_request(
|
|
810
|
+
rpc_request("tex_export", {"id": 173, "mip": 1, "slice": 1}), state
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
assert running
|
|
814
|
+
assert "result" in resp
|
|
815
|
+
assert save_calls == [(1, 1, resp["result"]["path"])]
|
|
816
|
+
assert Path(resp["result"]["path"]).read_bytes().startswith(b"\x89PNG")
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
def test_tex_export_remote_astc3d_reports_savetexture_fallback_failure(tmp_path: object) -> None:
|
|
820
|
+
fmt = rd.ResourceFormat(name="ASTC6x6_UNORM", type=99)
|
|
821
|
+
tex = rd.TextureDescription(
|
|
822
|
+
resourceId=rd.ResourceId(174),
|
|
823
|
+
type=rd.TextureType.Texture3D,
|
|
824
|
+
width=64,
|
|
825
|
+
height=64,
|
|
826
|
+
depth=4,
|
|
827
|
+
format=fmt,
|
|
828
|
+
)
|
|
829
|
+
state = _remote_state(tex, b"\x00" * 256, tmp_path)
|
|
830
|
+
state.adapter.controller._save_texture_fails = True # type: ignore[union-attr]
|
|
831
|
+
|
|
832
|
+
resp, _ = _handle_request(rpc_request("tex_export", {"id": 174, "slice": 1}), state)
|
|
833
|
+
|
|
834
|
+
assert resp["error"]["code"] == -32002
|
|
835
|
+
assert resp["error"]["message"] == "SaveTexture fallback failed"
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
def test_tex_export_texture3d_rejects_invalid_slice_for_mip(tmp_path: object) -> None:
|
|
839
|
+
fmt = rd.ResourceFormat(name="R8G8B8A8_UNORM", compByteWidth=1, compCount=4, compType=2)
|
|
840
|
+
tex = rd.TextureDescription(
|
|
841
|
+
resourceId=rd.ResourceId(171),
|
|
842
|
+
type=rd.TextureType.Texture3D,
|
|
843
|
+
width=2,
|
|
844
|
+
height=2,
|
|
845
|
+
depth=4,
|
|
846
|
+
mips=2,
|
|
847
|
+
format=fmt,
|
|
848
|
+
)
|
|
849
|
+
state = _remote_state(tex, bytes(16), tmp_path)
|
|
850
|
+
resp, _ = _handle_request(rpc_request("tex_export", {"id": 171, "mip": 1, "slice": 2}), state)
|
|
851
|
+
assert resp["error"]["code"] == -32001
|
|
852
|
+
assert resp["error"]["message"] == "slice 2 out of range (max: 1)"
|
|
756
853
|
|
|
757
854
|
|
|
758
855
|
def test_tex_export_remote_float_nan_renders_black(tmp_path: object, recwarn: object) -> None:
|
|
@@ -1001,3 +1098,43 @@ def test_tex_export_local_uses_savetexture(tmp_path: object) -> None:
|
|
|
1001
1098
|
resp, _ = _handle_request(rpc_request("tex_export", {"id": 42}), state)
|
|
1002
1099
|
assert "result" in resp
|
|
1003
1100
|
assert len(save_calls) == 1
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
def test_tex_export_local_texture3d_sets_requested_slice(tmp_path: object) -> None:
|
|
1104
|
+
fmt = rd.ResourceFormat(name="R8G8B8A8_UNORM", compByteWidth=1, compCount=4, compType=2)
|
|
1105
|
+
tex = rd.TextureDescription(
|
|
1106
|
+
resourceId=rd.ResourceId(172),
|
|
1107
|
+
type=rd.TextureType.Texture3D,
|
|
1108
|
+
width=2,
|
|
1109
|
+
height=2,
|
|
1110
|
+
depth=2,
|
|
1111
|
+
format=fmt,
|
|
1112
|
+
)
|
|
1113
|
+
ctrl = rd.MockReplayController()
|
|
1114
|
+
ctrl._textures = [tex]
|
|
1115
|
+
ctrl._actions = [
|
|
1116
|
+
rd.ActionDescription(eventId=100, flags=rd.ActionFlags.Drawcall, _name="vkCmdDraw"),
|
|
1117
|
+
]
|
|
1118
|
+
slice_indices: list[int] = []
|
|
1119
|
+
orig_save = ctrl.SaveTexture
|
|
1120
|
+
|
|
1121
|
+
def _spy(texsave: object, path: str) -> bool:
|
|
1122
|
+
slice_indices.append(texsave.slice.sliceIndex)
|
|
1123
|
+
return orig_save(texsave, path)
|
|
1124
|
+
|
|
1125
|
+
ctrl.SaveTexture = _spy # type: ignore[method-assign]
|
|
1126
|
+
state = make_daemon_state(
|
|
1127
|
+
ctrl=ctrl,
|
|
1128
|
+
current_eid=100,
|
|
1129
|
+
rd=rd,
|
|
1130
|
+
tmp_path=tmp_path,
|
|
1131
|
+
tex_map={172: tex},
|
|
1132
|
+
is_remote=False,
|
|
1133
|
+
)
|
|
1134
|
+
resp, _ = _handle_request(rpc_request("tex_export", {"id": 172, "slice": 1}), state)
|
|
1135
|
+
assert "result" in resp
|
|
1136
|
+
|
|
1137
|
+
resp0, _ = _handle_request(rpc_request("tex_export", {"id": 172, "slice": 0}), state)
|
|
1138
|
+
assert "result" in resp0
|
|
1139
|
+
|
|
1140
|
+
assert slice_indices == [1, 0]
|
|
@@ -364,6 +364,13 @@ def test_textures_id_mips_png(mip: int) -> None:
|
|
|
364
364
|
assert m == PathMatch(kind="leaf_bin", handler="tex_export", args={"id": 42, "mip": mip})
|
|
365
365
|
|
|
366
366
|
|
|
367
|
+
def test_textures_id_mips_slice_png() -> None:
|
|
368
|
+
m = resolve_path("/textures/42/mips/2/slices/3.png")
|
|
369
|
+
assert m == PathMatch(
|
|
370
|
+
kind="leaf_bin", handler="tex_export", args={"id": 42, "mip": 2, "slice": 3}
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
|
|
367
374
|
def test_textures_id_data() -> None:
|
|
368
375
|
m = resolve_path("/textures/42/data")
|
|
369
376
|
assert m == PathMatch(kind="leaf_bin", handler="tex_raw", args={"id": 42})
|
|
@@ -14,6 +14,7 @@ from mock_renderdoc import (
|
|
|
14
14
|
ShaderReflection,
|
|
15
15
|
ShaderResource,
|
|
16
16
|
TextureDescription,
|
|
17
|
+
TextureType,
|
|
17
18
|
)
|
|
18
19
|
|
|
19
20
|
from rdc.vfs.formatter import render_ls, render_tree_root
|
|
@@ -326,6 +327,20 @@ class TestTextureBufferSkeleton:
|
|
|
326
327
|
def test_texture_mips_1(self, typed_skeleton: VfsTree) -> None:
|
|
327
328
|
assert typed_skeleton.static["/textures/10/mips"].children == ["0.png"]
|
|
328
329
|
|
|
330
|
+
def test_texture3d_slice_leaf_is_available_to_vfs(self) -> None:
|
|
331
|
+
texture = TextureDescription(
|
|
332
|
+
resourceId=ResourceId(30), type=TextureType.Texture3D, depth=4, mips=2
|
|
333
|
+
)
|
|
334
|
+
tree = build_vfs_skeleton(_make_actions(), _make_typed_resources(), textures=[texture])
|
|
335
|
+
|
|
336
|
+
assert "0" in tree.static["/textures/30/mips"].children
|
|
337
|
+
assert tree.static["/textures/30/mips/0"].children == ["slices"]
|
|
338
|
+
assert tree.static["/textures/30/mips/0/slices"].children == ["1.png", "2.png", "3.png"]
|
|
339
|
+
assert tree.static["/textures/30/mips/0/slices/1.png"].kind == "leaf_bin"
|
|
340
|
+
assert tree.static["/textures/30/mips/1"].children == ["slices"]
|
|
341
|
+
assert tree.static["/textures/30/mips/1/slices"].children == ["1.png"]
|
|
342
|
+
assert tree.static["/textures/30/mips/1/slices/1.png"].kind == "leaf_bin"
|
|
343
|
+
|
|
329
344
|
def test_buffers_children(self, typed_skeleton: VfsTree) -> None:
|
|
330
345
|
assert typed_skeleton.static["/buffers"].children == ["20"]
|
|
331
346
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|