├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── examples ├── shader.wgsl └── triangle.rs ├── renderdoc-sys ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── generate_bindings.sh └── src │ ├── bindings.rs │ └── lib.rs └── src ├── error.rs ├── handles.rs ├── lib.rs ├── renderdoc.rs ├── settings.rs └── version.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "21:00" 8 | open-pull-requests-limit: 10 9 | assignees: 10 | - ebkalderon 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - release/* 8 | pull_request: 9 | branches: 10 | - master 11 | - release/* 12 | 13 | jobs: 14 | cargo-test: 15 | name: cargo test (${{ matrix.rust-version }}) 16 | runs-on: ubuntu-latest 17 | strategy: 18 | matrix: 19 | rust-version: [1.64.0, beta, nightly] 20 | include: 21 | - rust-version: nightly 22 | continue-on-error: true 23 | steps: 24 | - uses: actions/checkout@v2 25 | - name: Setup RenderDoc 26 | shell: bash 27 | run: | 28 | wget -qO renderdoc_1.24.tar.gz https://renderdoc.org/stable/1.24/renderdoc_1.24.tar.gz 29 | tar zxvf renderdoc_1.24.tar.gz 30 | sudo rsync -r --ignore-existing --keep-dirlinks renderdoc_1.24/* / 31 | - name: Install Rust toolchain 32 | uses: actions-rs/toolchain@v1 33 | with: 34 | profile: minimal 35 | toolchain: ${{ matrix.rust-version }} 36 | - name: Run cargo test 37 | continue-on-error: ${{ matrix.continue-on-error || false }} 38 | uses: actions-rs/cargo@v1 39 | with: 40 | command: test 41 | args: --workspace --all-features 42 | - name: Check examples 43 | continue-on-error: ${{ matrix.continue-on-error || false }} 44 | uses: actions-rs/cargo@v1 45 | with: 46 | command: check 47 | args: --examples 48 | 49 | cargo-audit: 50 | name: cargo audit 51 | runs-on: ubuntu-latest 52 | steps: 53 | - uses: actions/checkout@v1 54 | - uses: actions-rs/audit-check@v1 55 | with: 56 | token: ${{ secrets.GITHUB_TOKEN }} 57 | 58 | cargo-clippy: 59 | name: cargo clippy 60 | runs-on: ubuntu-latest 61 | steps: 62 | - uses: actions/checkout@v2 63 | - name: Install Rust toolchain 64 | uses: actions-rs/toolchain@v1 65 | with: 66 | profile: minimal 67 | toolchain: stable 68 | components: clippy 69 | - name: Run cargo clippy 70 | uses: actions-rs/clippy-check@v1 71 | with: 72 | token: ${{ secrets.GITHUB_TOKEN }} 73 | args: --all-targets --all-features -- -D warnings 74 | 75 | cargo-fmt: 76 | name: cargo fmt 77 | runs-on: ubuntu-latest 78 | steps: 79 | - uses: actions/checkout@v2 80 | - name: Install Rust toolchain 81 | uses: actions-rs/toolchain@v1 82 | with: 83 | profile: minimal 84 | toolchain: stable 85 | components: rustfmt 86 | - name: Run cargo fmt 87 | uses: actions-rs/cargo@v1 88 | with: 89 | command: fmt 90 | args: --all -- --check 91 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build artifacts 2 | **/target 3 | **/Cargo.lock 4 | 5 | # Backup files 6 | .DS_Store 7 | thumbs.db 8 | *~ 9 | *.rs.bk 10 | *.swp 11 | 12 | # IDE / Editor files 13 | *.iml 14 | .idea 15 | .vscode 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## [0.12.1] - 2024-03-01 11 | 12 | ### Added 13 | 14 | * Add `eRENDERDOC_Option_SoftMemoryLimit` symbol to `renderdoc-sys` (PR #151). 15 | 16 | ### Changed 17 | 18 | * Update `renderdoc-sys` dependency to 1.1.0 (PR #152). 19 | 20 | ## [0.12.0] - 2024-03-01 21 | 22 | ### Changed 23 | 24 | * Update `bitflags` dependency to 2.0. 25 | * Update `libloading` dependency to 0.8. 26 | 27 | ## [0.11.0] - 2023-02-20 28 | 29 | ### Changed 30 | 31 | * Update `renderdoc-sys` dependency to 1.0.0. 32 | * Update `float-cmp` dependency to 0.9. 33 | * Update optional `glutin` dependency to 0.30. 34 | * Update optional `winit` dependency to 0.28. 35 | * Improve crate-level documentation. 36 | 37 | ### Fixed 38 | 39 | * Fix loading strategy of `renderdoc` library (PR #140). 40 | * Fix typo in `start_frame_capture` and `end_frame_capture` docs (PR #122). 41 | * Fix undefined behavior and crash in `get_capture` (PR #143). 42 | 43 | ## [0.10.1] - 2021-02-10 44 | 45 | ### Changed 46 | 47 | * Bump `libloading` dependency to 0.7. 48 | 49 | ## [0.10.0] - 2020-12-17 50 | 51 | ### Changed 52 | 53 | * Bump `glutin` dependency to 0.26. 54 | 55 | ## [0.9.1] - 2020-08-05 56 | 57 | ### Changed 58 | 59 | * Allow global synchronized access to RenderDoc (see #79). 60 | * Exclude `vendor` subdirectory from `renderdoc-sys` crate. 61 | * Enable all crate features when generating docs for docs.rs. 62 | 63 | ### Fixed 64 | 65 | * Expose `V141` version selector. 66 | 67 | ## [0.9.0] - 2020-05-17 68 | 69 | ### Added 70 | 71 | * Implement preliminary support for API version 1.4.1 (see #93). 72 | 73 | ### Changed 74 | 75 | * Bump `glutin` dependency to 0.24, disable integration by default (PR #94). 76 | 77 | ## [0.8.1] - 2020-05-01 78 | 79 | ### Fixed 80 | 81 | * Fix copy-paste documentation mistake for `end_frame_capture()`. 82 | * Fix formatting for `unload_crash_handler()` docs. 83 | * Fix subtle spacing issue around `$PATH` in docs. 84 | 85 | ## [0.8.0] - 2020-05-01 86 | 87 | ### Added 88 | 89 | * Add dedicated `Error` type to be used throughout the library. 90 | 91 | ### Changed 92 | 93 | * Expand API documentation and improve existing documentation quality (PR #81). 94 | * Accept and return `PathBuf` or `&Path` in places instead of String and `&str` 95 | (PR #82). 96 | * Accept `Into` and `Into` instead of `AsRef` in places where 97 | we are going to be allocating anyway (PR #82). 98 | * Return `std::time::SystemTime` instead of a raw `u64` in `get_capture()`. 99 | * Convert crate to Rust 2018 edition. 100 | * Bump `float-cmp` dependency to 0.7. 101 | * Bump `libloading` dependency to 0.6. 102 | * Switch to Circle CI Rust 1.40.0 image. 103 | 104 | ### Deprecated 105 | 106 | * Mark `get_log_file_path_template()` and `set_log_file_path_template()` as 107 | deprecated for all RenderDoc API versions after 1.1.2 (PR #83). 108 | 109 | ## [0.7.1] - 2019-10-07 110 | 111 | ### Fixed 112 | 113 | * Fix build without `glutin` enabled (PR #69). 114 | 115 | ## [0.7.0] - 2019-08-23 116 | 117 | ### Added 118 | 119 | * Write more doc comments and add doc tests. 120 | 121 | ### Changed 122 | 123 | * Bump `float-cmp` dependency to 0.5. 124 | * Switch to Circle CI Rust 1.33.0 image. 125 | * Change error type of `launch_replay_ui()` from `()` to `String`. 126 | * Mark `Deref` block as `#[doc(hidden)]` for cleaner generated docs. 127 | 128 | ### Removed 129 | 130 | * Remove internal `renderdoc-derive` crate in favor of declarative macro. 131 | * Eliminate unnecessary `unsafe` blocks. 132 | 133 | ### Fixed 134 | 135 | * Define `CaptureOption`, `InputButton`, and `OverlayBits` in terms of 136 | `renderdoc-sys` types. 137 | * Add missing discriminant values to `InputButton` enum. 138 | * Fix broken Windows build (PR #61). 139 | 140 | ## [0.6.0] - 2019-05-19 141 | 142 | ### Added 143 | 144 | * Redesign crate to use inherent impls over traits (PR #35). 145 | * Add `HasPrevious` trait to recursively determine version compatibility at 146 | compile-time. 147 | 148 | ### Changed 149 | 150 | * Rename `Version` enum to `VersionCode` and `ApiVersion` trait to `Version`. 151 | * Use a single `Entry` type, since the aliases point to the same struct. 152 | * Update crate metadata and improve documentation. 153 | * Manually implement `Debug`, derive `Eq`, `Hash`, `PartialEq` for most types 154 | (PR #41). 155 | * Apply Clippy suggestions (PR #43). 156 | 157 | ### Deprecated 158 | 159 | * Mark `is_remote_access_connected()` as deprecated for all RenderDoc API 160 | versions after 1.1.1 (PR #42). 161 | 162 | ### Removed 163 | 164 | * Remove `prelude` module. 165 | * Remove `RenderDocV###` traits. 166 | * Remove `RenderDocV###` trait boilerplate code from `renderdoc-derive`. 167 | * Remove unused `__uint32_t` and `__uint64_t` type aliases from `renderdoc-sys` 168 | (PR #39). 169 | 170 | ## [0.5.0] - 2019-05-19 171 | 172 | ### Added 173 | 174 | * Add CI and documentation badges. 175 | * Implement support for API versions 1.3.0 and 1.4.0. 176 | * Allow string slices with lifetimes in `set_capture_file_comments()`. 177 | 178 | ### Changed 179 | 180 | * Bump `glutin` dependency to 0.21. 181 | * Bump `gfx` dev-dependency to 0.18.1. 182 | * Bump `gfx_window_glutin` dev-dependency to 0.31. 183 | * Upgrade CircleCI Rust image to 1.34.1. 184 | * Convert top-level crate to workspace. 185 | * Clean up `renderdoc-sys` crate layout. 186 | * Minor code formatting tweaks. 187 | 188 | ### Fixed 189 | 190 | * Switch `set_capture_file_comments()` and `trigger_multi_frame_capture()` to 191 | take `&mut self` (PR #32). 192 | * Unimplement `Clone`, `Send`, and `Sync` for `RenderDoc` struct (PR #29). 193 | * Correct default setting in the `get_set_capture_option()` unit test. 194 | * Fix improperly designed `launch_replay_ui()` method, update `triangle` example 195 | to match. 196 | * Set correct RenderDoc library path for Android clients. 197 | * Add missing trait re-exports to `prelude` module (PR #31). 198 | * Fix erroneous doc comments (PR #24). 199 | 200 | ## [0.4.0] - 2018-09-16 201 | 202 | ### Added 203 | 204 | * Create `renderdoc-sys` crate for raw FFI bindings. 205 | * Create `renderdoc-derive` crate for internal codegen. 206 | * Add support for RenderDoc API 1.1.1, 1.1.2, and 1.2.0. 207 | 208 | ### Changed 209 | 210 | * Switch to `libloading` from `shared_library`. 211 | * Update `triangle` example to the latest `glutin` API. 212 | * Bump dependencies. 213 | 214 | ## [0.3.0] - 2018-06-01 215 | 216 | ### Changed 217 | 218 | * Update existing dependencies (PR #3). 219 | 220 | ## [0.2.0] - 2017-12-15 221 | 222 | ### Added 223 | 224 | * Convenient conversions for `glutin::Context`, `winapi::D3D11Device`, 225 | `winapi::D3D12Device`, and `winapi::windef::HGLRC` into RenderDoc 226 | `DevicePointer`. 227 | 228 | ### Changed 229 | 230 | * Update existing dependencies. 231 | * Optionally depend on `glutin` in place of `winit`. 232 | * Depend on `wio` for Windows targets. 233 | 234 | ### Fixed 235 | 236 | * Missing byte in `SHADER_MAGIC_DEBUG_VALUE_STRUCT` broke Windows builds. 237 | 238 | ## [0.1.0] - 2017-10-11 239 | 240 | ### Added 241 | 242 | * Initial crate release. 243 | * In-application API bindings, supporting versions 1.0 to 1.1. 244 | * Type-safe version requests and downgrading. 245 | * Convenient conversions for `winit::VirtualKeyCode` into RenderDoc `InputButton`. 246 | 247 | [Unreleased]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.12.1...HEAD 248 | [0.12.1]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.12.0...v0.12.1 249 | [0.12.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.11.0...v0.12.0 250 | [0.11.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.10.1...v0.11.0 251 | [0.10.1]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.10.0...v0.10.1 252 | [0.10.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.9.1...v0.10.0 253 | [0.9.1]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.9.0...v0.9.1 254 | [0.9.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.8.1...v0.9.0 255 | [0.8.1]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.8.0...v0.8.1 256 | [0.8.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.7.1...v0.8.0 257 | [0.7.1]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.7.0...v0.7.1 258 | [0.7.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.6.0...v0.7.0 259 | [0.6.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.5.0...v0.6.0 260 | [0.5.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.4.0...v0.5.0 261 | [0.4.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.3.0...v0.4.0 262 | [0.3.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.2.0...v0.3.0 263 | [0.2.0]: https://github.com/ebkalderon/renderdoc-rs/compare/v0.1.0...v0.2.0 264 | [0.1.0]: https://github.com/ebkalderon/renderdoc-rs/releases/tag/v0.1.0 265 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at ebkalderon@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to renderdoc-rs 2 | 3 | `renderdoc-rs` is an open-source project that values community contribution. We 4 | could always use a helping hand! What would you like to do? 5 | 6 | 1. [I want to submit issues or request features.](#submitting-issues) 7 | 2. [I want to contribute code.](#contributing-code) 8 | 3. [I want to write documentation.](#writing-documentation) 9 | 10 | ## Submitting issues 11 | 12 | One way you can help `renderdoc-rs` is to report bugs or request features on our 13 | GitHub issue trackers. We can't fix problems we don't know about, so please 14 | report early and often! 15 | 16 | When reporting a bug or asking for help, please include enough details so that 17 | the people helping you can reproduce the behavior you are seeing. For some tips 18 | on how to approach this, read about how to produce a 19 | [Minimal, Complete, and Verifiable example][mcve]. 20 | 21 | [mcve]: https://stackoverflow.com/help/mcve 22 | 23 | When making a feature request, please make it clear what problem you intend to 24 | solve with the feature, any ideas for how `renderdoc-rs` could support solving 25 | that problem, any possible alternatives, and any disadvantages. 26 | 27 | ## Contributing code 28 | 29 | The general workflow for contributing code to the `renderdoc-rs` repository is 30 | as follows: 31 | 32 | 1. Fork this repository to your own GitHub account. 33 | 2. `git clone` the forked repository to your local machine. 34 | 3. Check out the branch you wish to make changes against. 35 | 4. Make your changes and push them up to the forked repository. 36 | 5. [Open a pull request] against this repository. 37 | 38 | [Open a pull request]: https://github.com/ebkalderon/renderdoc-rs/compare 39 | 40 | Before submitting your pull request, please make sure the following conditions 41 | are satisfied: 42 | 43 | 1. The pull request is based on an up-to-date version of your respective branch. 44 | 2. If your pull request introduces new functionality, you have written test 45 | cases for them. 46 | * Unit tests are placed at the bottom of the same `.rs` file in a submodule 47 | called `tests`. See [this example] for reference. 48 | * Integration tests are placed in a separate `.rs` file in the `tests` 49 | subdirectory. 50 | 3. The codebase has been processed with `cargo fmt`. 51 | 4. All of the following commands completed without errors: 52 | * `cargo build` 53 | * `cargo test --all` 54 | * `cargo run --example server` 55 | 56 | [this example]: ./src/codec.rs#L80-L135 57 | 58 | We encourage you to check that the test suite passes locally before submitting a 59 | pull request with your changes. If anything does not pass, typically it will be 60 | easier to iterate and fix it locally than waiting for the CI servers to run 61 | tests for you. 62 | 63 | Thank you very much for your contribution! Now `renderdoc-rs` will be a little 64 | faster, more ergonomic, and more efficient. 65 | 66 | ## Writing documentation 67 | 68 | Documentation improvements are always welcome! 69 | 70 | As with most Rust projects, API documentation is generated directly from doc 71 | comments, denoted by either `///` or `//!`, using a tool called Rustdoc. See 72 | [the official Rust book's chapter on Rustdoc][rd] for more information on how 73 | this works. 74 | 75 | [rd]: https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments 76 | 77 | Documentation of any kind should adhere to the following standard: 78 | 79 | 1. Lines must not extend beyond 80 characters in length. 80 | 2. To enhance readability in text editors and terminals, use only *reference 81 | style* Markdown links, as shown in the example below. However, if the link 82 | points to an anchor that exists on the same page, the *inline style* should 83 | be used instead. 84 | 85 | ```markdown 86 | Here is some [example text] with a link in it. While we are at it, here is yet 87 | yet [another link][al], but shorter. If we are linking to [an anchor](#anchor) 88 | on the same page, we can do this inline. 89 | 90 | [example text]: https://some.url/ 91 | [al]: https://another.url/ 92 | ``` 93 | 94 | When submitting your pull requests, please follow the same workflow described in 95 | the [Contributing Code](#contributing-code) section above. 96 | 97 | ## Code of conduct 98 | 99 | Please note that this project is released with a [Contributor Code of Conduct]. 100 | By participating in this project, you agree to abide by its terms. 101 | 102 | [Contributor Code of Conduct]: ./CODE_OF_CONDUCT.md 103 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "renderdoc" 3 | version = "0.12.1" 4 | edition = "2018" 5 | resolver = "2" 6 | authors = ["Eyal Kalderon "] 7 | description = "RenderDoc application bindings for Rust" 8 | license = "MIT OR Apache-2.0" 9 | homepage = "https://github.com/ebkalderon/renderdoc-rs" 10 | repository = "https://github.com/ebkalderon/renderdoc-rs" 11 | documentation = "https://docs.rs/renderdoc/" 12 | readme = "README.md" 13 | keywords = ["graphics", "profiling", "renderdoc", "tracing"] 14 | categories = ["development-tools::debugging", "rendering"] 15 | 16 | [package.metadata.docs.rs] 17 | all-features = true 18 | 19 | [badges] 20 | maintenance = { status = "actively-developed" } 21 | 22 | [features] 23 | default = [] 24 | 25 | # Private feature only intended for doctests in CI 26 | ci = [] 27 | 28 | [dependencies] 29 | bitflags = "2.0" 30 | float-cmp = "0.9" 31 | libloading = "0.8" 32 | once_cell = "1.0" 33 | renderdoc-sys = { version = "1.1.0", path = "./renderdoc-sys" } 34 | 35 | glutin = { version = "0.30", optional = true } 36 | winit = { version = "0.28", optional = true } 37 | 38 | [target.'cfg(windows)'.dependencies] 39 | winapi = { version = "0.3", features = ["d3d12","d3d11"] } 40 | wio = "0.2" 41 | 42 | [dev-dependencies] 43 | pollster = "0.3" 44 | wgpu = "0.15" 45 | wgpu-subscriber = "0.1.0" 46 | winit = "0.28" 47 | 48 | [workspace] 49 | members = [".", "renderdoc-sys"] 50 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Eyal Kalderon 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # renderdoc-rs 2 | 3 | [![Build Status][build-badge]][build-url] 4 | [![Crates.io][crate-badge]][crate-url] 5 | [![Documentation][docs-badge]][docs-url] 6 | 7 | [build-badge]: https://github.com/ebkalderon/renderdoc-rs/actions/workflows/ci.yml/badge.svg 8 | [build-url]: https://github.com/ebkalderon/renderdoc-rs/actions 9 | [crate-badge]: https://img.shields.io/crates/v/renderdoc.svg 10 | [crate-url]: https://crates.io/crates/renderdoc 11 | [docs-badge]: https://docs.rs/renderdoc/badge.svg 12 | [docs-url]: https://docs.rs/renderdoc 13 | 14 | Rust bindings to [RenderDoc], a popular graphics debugger. 15 | 16 | [RenderDoc]: https://renderdoc.org/ 17 | 18 | RenderDoc is a free and open source debugger for real-time graphics providing 19 | quick and easy frame captures and detailed introspection of any application 20 | using [Vulkan], [Direct3D 11], [Direct3D 12], [OpenGL], and [OpenGL ES]. 21 | 22 | [Vulkan]: https://www.vulkan.org/ 23 | [Direct3D 11]: https://learn.microsoft.com/en-us/windows/win32/direct3d11/atoc-dx-graphics-direct3d-11 24 | [Direct3D 12]: https://learn.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-graphics 25 | [OpenGL]: https://www.khronos.org/opengl/ 26 | [OpenGL ES]: https://www.khronos.org/opengles/ 27 | 28 | These bindings require that RenderDoc be installed on the target machine, with 29 | either `renderdoc.dll` or `librenderdoc.so` visible from your `$PATH`. 30 | 31 | For more details on how to use this API to integrate your game or renderer with 32 | the RenderDoc profiler, consult the [in-application API][in-app] documentation. 33 | 34 | [in-app]: https://renderdoc.org/docs/in_application_api.html 35 | 36 | ## Example 37 | 38 | ```rust 39 | use renderdoc::{RenderDoc, V100, V110}; 40 | 41 | fn main() { 42 | let mut rd: RenderDoc = RenderDoc::new().expect("Unable to connect"); 43 | 44 | let (major, minor, patch) = rd.get_api_version(); 45 | assert_eq!(major, 1u32); 46 | assert!(minor >= 1u32); 47 | 48 | // When a certain key is pressed, trigger a single-frame capture like this. 49 | rd.trigger_capture(); 50 | 51 | // If you specify version `V110` or newer, you can trigger a multi-frame 52 | // capture like this. 53 | rd.trigger_multi_frame_capture(3); 54 | 55 | // Query the details of an existing capture like this. 56 | match rd.get_capture(0) { 57 | Some((path, capture_time)) => println!("ID: 0, Path: {}, Captured: {:?}", path, capture_time), 58 | None => println!("No capture found with ID of 0!"), 59 | } 60 | 61 | // Downgrade your effective API version at run-time like this. 62 | let mut rd: RenderDoc = rd.into(); 63 | 64 | // Now this line will no longer compile! 65 | // rd.trigger_multi_frame_capture(3); 66 | } 67 | ``` 68 | 69 | Working examples are available in the `examples` directory. 70 | 71 | ## License 72 | 73 | `renderdoc-rs` is free and open source software distributed under the terms of 74 | either the [MIT](LICENSE-MIT) or the [Apache 2.0](LICENSE-APACHE) license, at 75 | your option. 76 | 77 | Unless you explicitly state otherwise, any contribution intentionally submitted 78 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 79 | dual licensed as above, without any additional terms or conditions. 80 | -------------------------------------------------------------------------------- /examples/shader.wgsl: -------------------------------------------------------------------------------- 1 | @vertex 2 | fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 { 3 | let x = f32(i32(in_vertex_index) - 1); 4 | let y = f32(i32(in_vertex_index & 1u) * 2 - 1); 5 | return vec4(x, y, 0.0, 1.0); 6 | } 7 | 8 | @fragment 9 | fn fs_main() -> @location(0) vec4 { 10 | return vec4(1.0, 0.0, 0.0, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /examples/triangle.rs: -------------------------------------------------------------------------------- 1 | use std::borrow::Cow; 2 | 3 | use renderdoc::{InputButton, RenderDoc, V110}; 4 | use winit::{ 5 | event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}, 6 | event_loop::{ControlFlow, EventLoop}, 7 | window::Window, 8 | }; 9 | 10 | async fn run(event_loop: EventLoop<()>, window: Window) { 11 | let size = window.inner_size(); 12 | 13 | let instance = wgpu::Instance::default(); 14 | 15 | let surface = unsafe { instance.create_surface(&window) }.unwrap(); 16 | let adapter = instance 17 | .request_adapter(&wgpu::RequestAdapterOptions { 18 | power_preference: wgpu::PowerPreference::default(), 19 | force_fallback_adapter: false, 20 | // Request an adapter which can render to our surface 21 | compatible_surface: Some(&surface), 22 | }) 23 | .await 24 | .expect("Failed to find an appropriate adapter"); 25 | 26 | // Create the logical device and command queue 27 | let (device, queue) = adapter 28 | .request_device( 29 | &wgpu::DeviceDescriptor { 30 | label: None, 31 | features: wgpu::Features::empty(), 32 | // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. 33 | limits: wgpu::Limits::downlevel_webgl2_defaults() 34 | .using_resolution(adapter.limits()), 35 | }, 36 | None, 37 | ) 38 | .await 39 | .expect("Failed to create device"); 40 | 41 | let mut renderdoc: Result, _> = RenderDoc::new(); 42 | 43 | if let Ok(rd) = renderdoc.as_mut() { 44 | rd.set_focus_toggle_keys(&[InputButton::F]); 45 | rd.set_capture_keys(&[InputButton::C]); 46 | } 47 | 48 | // Load the shaders from disk 49 | let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { 50 | label: None, 51 | source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), 52 | }); 53 | 54 | let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { 55 | label: None, 56 | bind_group_layouts: &[], 57 | push_constant_ranges: &[], 58 | }); 59 | 60 | let swapchain_capabilities = surface.get_capabilities(&adapter); 61 | let swapchain_format = swapchain_capabilities.formats[0]; 62 | 63 | let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { 64 | label: None, 65 | layout: Some(&pipeline_layout), 66 | vertex: wgpu::VertexState { 67 | module: &shader, 68 | entry_point: "vs_main", 69 | buffers: &[], 70 | }, 71 | fragment: Some(wgpu::FragmentState { 72 | module: &shader, 73 | entry_point: "fs_main", 74 | targets: &[Some(swapchain_format.into())], 75 | }), 76 | primitive: wgpu::PrimitiveState::default(), 77 | depth_stencil: None, 78 | multisample: wgpu::MultisampleState::default(), 79 | multiview: None, 80 | }); 81 | 82 | let mut config = wgpu::SurfaceConfiguration { 83 | usage: wgpu::TextureUsages::RENDER_ATTACHMENT, 84 | format: swapchain_format, 85 | width: size.width, 86 | height: size.height, 87 | present_mode: wgpu::PresentMode::Fifo, 88 | alpha_mode: swapchain_capabilities.alpha_modes[0], 89 | view_formats: vec![], 90 | }; 91 | 92 | surface.configure(&device, &config); 93 | 94 | event_loop.run(move |event, _, control_flow| { 95 | // Have the closure take ownership of the resources. 96 | // `event_loop.run` never returns, therefore we must do this to ensure 97 | // the resources are properly cleaned up. 98 | let _ = (&instance, &adapter, &shader, &pipeline_layout); 99 | 100 | *control_flow = ControlFlow::Wait; 101 | match event { 102 | Event::WindowEvent { 103 | event: WindowEvent::Resized(size), 104 | .. 105 | } => { 106 | // Reconfigure the surface with the new size 107 | config.width = size.width; 108 | config.height = size.height; 109 | surface.configure(&device, &config); 110 | // On macos the window needs to be redrawn manually after resizing 111 | window.request_redraw(); 112 | } 113 | Event::WindowEvent { 114 | event: 115 | WindowEvent::KeyboardInput { 116 | input: 117 | KeyboardInput { 118 | virtual_keycode: Some(keycode), 119 | state: ElementState::Pressed, 120 | .. 121 | }, 122 | .. 123 | }, 124 | .. 125 | } => match (keycode, renderdoc.as_mut()) { 126 | (VirtualKeyCode::C, Ok(rd)) => rd.trigger_capture(), 127 | (VirtualKeyCode::R, Ok(rd)) => match rd.launch_replay_ui(true, None) { 128 | Ok(pid) => println!("Launched replay UI (PID {pid})"), 129 | Err(e) => eprintln!("Failed to launch replay UI: {e}"), 130 | }, 131 | _ => {} 132 | }, 133 | Event::RedrawRequested(_) => { 134 | let frame = surface 135 | .get_current_texture() 136 | .expect("Failed to acquire next swap chain texture"); 137 | let view = frame 138 | .texture 139 | .create_view(&wgpu::TextureViewDescriptor::default()); 140 | let mut encoder = 141 | device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); 142 | { 143 | let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { 144 | label: None, 145 | color_attachments: &[Some(wgpu::RenderPassColorAttachment { 146 | view: &view, 147 | resolve_target: None, 148 | ops: wgpu::Operations { 149 | load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), 150 | store: true, 151 | }, 152 | })], 153 | depth_stencil_attachment: None, 154 | }); 155 | rpass.set_pipeline(&render_pipeline); 156 | rpass.draw(0..3, 0..1); 157 | } 158 | 159 | queue.submit(Some(encoder.finish())); 160 | frame.present(); 161 | } 162 | Event::WindowEvent { 163 | event: WindowEvent::CloseRequested, 164 | .. 165 | } => *control_flow = ControlFlow::Exit, 166 | _ => {} 167 | } 168 | }); 169 | } 170 | 171 | fn main() { 172 | let event_loop = EventLoop::new(); 173 | let window = winit::window::Window::new(&event_loop).unwrap(); 174 | wgpu_subscriber::initialize_default_subscriber(None); 175 | pollster::block_on(run(event_loop, window)); 176 | } 177 | -------------------------------------------------------------------------------- /renderdoc-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "renderdoc-sys" 3 | version = "1.1.0" 4 | authors = ["Eyal Kalderon "] 5 | description = "Low-level bindings to the RenderDoc API" 6 | license = "MIT OR Apache-2.0" 7 | homepage = "https://github.com/ebkalderon/renderdoc-rs/tree/master/renderdoc-sys" 8 | repository = "https://github.com/ebkalderon/renderdoc-rs" 9 | documentation = "https://docs.rs/renderdoc-sys" 10 | readme = "README.md" 11 | keywords = ["ffi", "graphics", "profiling", "renderdoc", "tracing"] 12 | categories = ["development-tools::debugging", "external-ffi-bindings", "rendering"] 13 | 14 | [badges] 15 | maintenance = { status = "passively-maintained" } 16 | 17 | [dependencies] 18 | -------------------------------------------------------------------------------- /renderdoc-sys/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /renderdoc-sys/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 Eyal Kalderon 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /renderdoc-sys/README.md: -------------------------------------------------------------------------------- 1 | # renderdoc-sys 2 | 3 | [![Build Status][build-badge]][build-url] 4 | [![Crates.io][crate-badge]][crate-url] 5 | [![Documentation][docs-badge]][docs-url] 6 | 7 | [build-badge]: https://github.com/ebkalderon/renderdoc-rs/actions/workflows/ci.yml/badge.svg 8 | [build-url]: https://github.com/ebkalderon/renderdoc-rs/actions 9 | [crate-badge]: https://img.shields.io/crates/v/renderdoc-sys.svg 10 | [crate-url]: https://crates.io/crates/renderdoc-sys 11 | [docs-badge]: https://docs.rs/renderdoc-sys/badge.svg 12 | [docs-url]: https://docs.rs/renderdoc-sys 13 | 14 | Low-level bindings to the [RenderDoc] in-application API. 15 | 16 | [RenderDoc]: https://renderdoc.org/ 17 | 18 | RenderDoc is a free and open source debugger for real-time graphics that allows 19 | quick and easy frame captures and detailed introspection of any application 20 | using [Vulkan], [Direct3D 11], [Direct3D 12], [OpenGL], and [OpenGL ES]. 21 | 22 | [Vulkan]: https://www.vulkan.org/ 23 | [Direct3D 11]: https://learn.microsoft.com/en-us/windows/win32/direct3d11/atoc-dx-graphics-direct3d-11 24 | [Direct3D 12]: https://learn.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-graphics 25 | [OpenGL]: https://www.khronos.org/opengl/ 26 | [OpenGL ES]: https://www.khronos.org/opengles/ 27 | 28 | These bindings are automatically generated from [`renderdoc_app.h`] with 29 | [`bindgen`]. This crate does not provide nor link to `renderdoc.dll` nor 30 | `librenderdoc.so` by itself; it only contains the FFI symbols. Refer to the 31 | upstream [In-Application API][api] documentation for correct usage details. 32 | 33 | [`renderdoc_app.h`]: https://github.com/baldurk/renderdoc/blob/v1.x/renderdoc/api/app/renderdoc_app.h 34 | [bindgen]: https://github.com/rust-lang/rust-bindgen 35 | [api]: https://renderdoc.org/docs/in_application_api.html 36 | 37 | For a safe wrapper, see the [`renderdoc`](https://docs.rs/renderdoc) crate. 38 | 39 | ## License 40 | 41 | `renderdoc-sys` is free and open source software distributed under the terms of 42 | either the [MIT](LICENSE-MIT) or the [Apache 2.0](LICENSE-APACHE) license, at 43 | your option. 44 | 45 | Unless you explicitly state otherwise, any contribution intentionally submitted 46 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 47 | dual licensed as above, without any additional terms or conditions. 48 | -------------------------------------------------------------------------------- /renderdoc-sys/generate_bindings.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script generates Rust bindings to the in-application Renderdoc API. 4 | # 5 | # Dependencies: 6 | # * bindgen (>=0.63.0) 7 | # * curl 8 | 9 | set -euo pipefail 10 | 11 | readonly VERSION=v1.x 12 | readonly TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/renderdoc-rs.XXXXXXXXX")" 13 | 14 | trap -- "rm -rf '${TEMP_DIR}'" EXIT 15 | 16 | curl -o "${TEMP_DIR}/renderdoc_app.h" -L "https://raw.githubusercontent.com/baldurk/renderdoc/${VERSION}/renderdoc/api/app/renderdoc_app.h" 17 | 18 | bindgen \ 19 | --blocklist-type '__uint64_t|__uint32_t' \ 20 | --allowlist-type 'RENDERDOC.*|pRENDERDOC.*' \ 21 | --generate-inline-functions \ 22 | --no-prepend-enum-name \ 23 | --impl-debug \ 24 | "${TEMP_DIR}/renderdoc_app.h" > ./src/bindings.rs 25 | -------------------------------------------------------------------------------- /renderdoc-sys/src/bindings.rs: -------------------------------------------------------------------------------- 1 | /* automatically generated by rust-bindgen 0.69.4 */ 2 | 3 | pub const eRENDERDOC_Option_AllowVSync: RENDERDOC_CaptureOption = 0; 4 | pub const eRENDERDOC_Option_AllowFullscreen: RENDERDOC_CaptureOption = 1; 5 | pub const eRENDERDOC_Option_APIValidation: RENDERDOC_CaptureOption = 2; 6 | pub const eRENDERDOC_Option_DebugDeviceMode: RENDERDOC_CaptureOption = 2; 7 | pub const eRENDERDOC_Option_CaptureCallstacks: RENDERDOC_CaptureOption = 3; 8 | pub const eRENDERDOC_Option_CaptureCallstacksOnlyDraws: RENDERDOC_CaptureOption = 4; 9 | pub const eRENDERDOC_Option_CaptureCallstacksOnlyActions: RENDERDOC_CaptureOption = 4; 10 | pub const eRENDERDOC_Option_DelayForDebugger: RENDERDOC_CaptureOption = 5; 11 | pub const eRENDERDOC_Option_VerifyBufferAccess: RENDERDOC_CaptureOption = 6; 12 | pub const eRENDERDOC_Option_VerifyMapWrites: RENDERDOC_CaptureOption = 6; 13 | pub const eRENDERDOC_Option_HookIntoChildren: RENDERDOC_CaptureOption = 7; 14 | pub const eRENDERDOC_Option_RefAllResources: RENDERDOC_CaptureOption = 8; 15 | pub const eRENDERDOC_Option_SaveAllInitials: RENDERDOC_CaptureOption = 9; 16 | pub const eRENDERDOC_Option_CaptureAllCmdLists: RENDERDOC_CaptureOption = 10; 17 | pub const eRENDERDOC_Option_DebugOutputMute: RENDERDOC_CaptureOption = 11; 18 | pub const eRENDERDOC_Option_AllowUnsupportedVendorExtensions: RENDERDOC_CaptureOption = 12; 19 | pub const eRENDERDOC_Option_SoftMemoryLimit: RENDERDOC_CaptureOption = 13; 20 | pub type RENDERDOC_CaptureOption = ::std::os::raw::c_uint; 21 | pub type pRENDERDOC_SetCaptureOptionU32 = ::std::option::Option< 22 | unsafe extern "C" fn(opt: RENDERDOC_CaptureOption, val: u32) -> ::std::os::raw::c_int, 23 | >; 24 | pub type pRENDERDOC_SetCaptureOptionF32 = ::std::option::Option< 25 | unsafe extern "C" fn(opt: RENDERDOC_CaptureOption, val: f32) -> ::std::os::raw::c_int, 26 | >; 27 | pub type pRENDERDOC_GetCaptureOptionU32 = 28 | ::std::option::Option u32>; 29 | pub type pRENDERDOC_GetCaptureOptionF32 = 30 | ::std::option::Option f32>; 31 | pub const eRENDERDOC_Key_0: RENDERDOC_InputButton = 48; 32 | pub const eRENDERDOC_Key_1: RENDERDOC_InputButton = 49; 33 | pub const eRENDERDOC_Key_2: RENDERDOC_InputButton = 50; 34 | pub const eRENDERDOC_Key_3: RENDERDOC_InputButton = 51; 35 | pub const eRENDERDOC_Key_4: RENDERDOC_InputButton = 52; 36 | pub const eRENDERDOC_Key_5: RENDERDOC_InputButton = 53; 37 | pub const eRENDERDOC_Key_6: RENDERDOC_InputButton = 54; 38 | pub const eRENDERDOC_Key_7: RENDERDOC_InputButton = 55; 39 | pub const eRENDERDOC_Key_8: RENDERDOC_InputButton = 56; 40 | pub const eRENDERDOC_Key_9: RENDERDOC_InputButton = 57; 41 | pub const eRENDERDOC_Key_A: RENDERDOC_InputButton = 65; 42 | pub const eRENDERDOC_Key_B: RENDERDOC_InputButton = 66; 43 | pub const eRENDERDOC_Key_C: RENDERDOC_InputButton = 67; 44 | pub const eRENDERDOC_Key_D: RENDERDOC_InputButton = 68; 45 | pub const eRENDERDOC_Key_E: RENDERDOC_InputButton = 69; 46 | pub const eRENDERDOC_Key_F: RENDERDOC_InputButton = 70; 47 | pub const eRENDERDOC_Key_G: RENDERDOC_InputButton = 71; 48 | pub const eRENDERDOC_Key_H: RENDERDOC_InputButton = 72; 49 | pub const eRENDERDOC_Key_I: RENDERDOC_InputButton = 73; 50 | pub const eRENDERDOC_Key_J: RENDERDOC_InputButton = 74; 51 | pub const eRENDERDOC_Key_K: RENDERDOC_InputButton = 75; 52 | pub const eRENDERDOC_Key_L: RENDERDOC_InputButton = 76; 53 | pub const eRENDERDOC_Key_M: RENDERDOC_InputButton = 77; 54 | pub const eRENDERDOC_Key_N: RENDERDOC_InputButton = 78; 55 | pub const eRENDERDOC_Key_O: RENDERDOC_InputButton = 79; 56 | pub const eRENDERDOC_Key_P: RENDERDOC_InputButton = 80; 57 | pub const eRENDERDOC_Key_Q: RENDERDOC_InputButton = 81; 58 | pub const eRENDERDOC_Key_R: RENDERDOC_InputButton = 82; 59 | pub const eRENDERDOC_Key_S: RENDERDOC_InputButton = 83; 60 | pub const eRENDERDOC_Key_T: RENDERDOC_InputButton = 84; 61 | pub const eRENDERDOC_Key_U: RENDERDOC_InputButton = 85; 62 | pub const eRENDERDOC_Key_V: RENDERDOC_InputButton = 86; 63 | pub const eRENDERDOC_Key_W: RENDERDOC_InputButton = 87; 64 | pub const eRENDERDOC_Key_X: RENDERDOC_InputButton = 88; 65 | pub const eRENDERDOC_Key_Y: RENDERDOC_InputButton = 89; 66 | pub const eRENDERDOC_Key_Z: RENDERDOC_InputButton = 90; 67 | pub const eRENDERDOC_Key_NonPrintable: RENDERDOC_InputButton = 256; 68 | pub const eRENDERDOC_Key_Divide: RENDERDOC_InputButton = 257; 69 | pub const eRENDERDOC_Key_Multiply: RENDERDOC_InputButton = 258; 70 | pub const eRENDERDOC_Key_Subtract: RENDERDOC_InputButton = 259; 71 | pub const eRENDERDOC_Key_Plus: RENDERDOC_InputButton = 260; 72 | pub const eRENDERDOC_Key_F1: RENDERDOC_InputButton = 261; 73 | pub const eRENDERDOC_Key_F2: RENDERDOC_InputButton = 262; 74 | pub const eRENDERDOC_Key_F3: RENDERDOC_InputButton = 263; 75 | pub const eRENDERDOC_Key_F4: RENDERDOC_InputButton = 264; 76 | pub const eRENDERDOC_Key_F5: RENDERDOC_InputButton = 265; 77 | pub const eRENDERDOC_Key_F6: RENDERDOC_InputButton = 266; 78 | pub const eRENDERDOC_Key_F7: RENDERDOC_InputButton = 267; 79 | pub const eRENDERDOC_Key_F8: RENDERDOC_InputButton = 268; 80 | pub const eRENDERDOC_Key_F9: RENDERDOC_InputButton = 269; 81 | pub const eRENDERDOC_Key_F10: RENDERDOC_InputButton = 270; 82 | pub const eRENDERDOC_Key_F11: RENDERDOC_InputButton = 271; 83 | pub const eRENDERDOC_Key_F12: RENDERDOC_InputButton = 272; 84 | pub const eRENDERDOC_Key_Home: RENDERDOC_InputButton = 273; 85 | pub const eRENDERDOC_Key_End: RENDERDOC_InputButton = 274; 86 | pub const eRENDERDOC_Key_Insert: RENDERDOC_InputButton = 275; 87 | pub const eRENDERDOC_Key_Delete: RENDERDOC_InputButton = 276; 88 | pub const eRENDERDOC_Key_PageUp: RENDERDOC_InputButton = 277; 89 | pub const eRENDERDOC_Key_PageDn: RENDERDOC_InputButton = 278; 90 | pub const eRENDERDOC_Key_Backspace: RENDERDOC_InputButton = 279; 91 | pub const eRENDERDOC_Key_Tab: RENDERDOC_InputButton = 280; 92 | pub const eRENDERDOC_Key_PrtScrn: RENDERDOC_InputButton = 281; 93 | pub const eRENDERDOC_Key_Pause: RENDERDOC_InputButton = 282; 94 | pub const eRENDERDOC_Key_Max: RENDERDOC_InputButton = 283; 95 | pub type RENDERDOC_InputButton = ::std::os::raw::c_uint; 96 | pub type pRENDERDOC_SetFocusToggleKeys = ::std::option::Option< 97 | unsafe extern "C" fn(keys: *mut RENDERDOC_InputButton, num: ::std::os::raw::c_int), 98 | >; 99 | pub type pRENDERDOC_SetCaptureKeys = ::std::option::Option< 100 | unsafe extern "C" fn(keys: *mut RENDERDOC_InputButton, num: ::std::os::raw::c_int), 101 | >; 102 | pub const eRENDERDOC_Overlay_Enabled: RENDERDOC_OverlayBits = 1; 103 | pub const eRENDERDOC_Overlay_FrameRate: RENDERDOC_OverlayBits = 2; 104 | pub const eRENDERDOC_Overlay_FrameNumber: RENDERDOC_OverlayBits = 4; 105 | pub const eRENDERDOC_Overlay_CaptureList: RENDERDOC_OverlayBits = 8; 106 | pub const eRENDERDOC_Overlay_Default: RENDERDOC_OverlayBits = 15; 107 | pub const eRENDERDOC_Overlay_All: RENDERDOC_OverlayBits = 4294967295; 108 | pub const eRENDERDOC_Overlay_None: RENDERDOC_OverlayBits = 0; 109 | pub type RENDERDOC_OverlayBits = ::std::os::raw::c_uint; 110 | pub type pRENDERDOC_GetOverlayBits = ::std::option::Option u32>; 111 | pub type pRENDERDOC_MaskOverlayBits = 112 | ::std::option::Option; 113 | pub type pRENDERDOC_RemoveHooks = ::std::option::Option; 114 | pub type pRENDERDOC_Shutdown = pRENDERDOC_RemoveHooks; 115 | pub type pRENDERDOC_UnloadCrashHandler = ::std::option::Option; 116 | pub type pRENDERDOC_SetCaptureFilePathTemplate = 117 | ::std::option::Option; 118 | pub type pRENDERDOC_GetCaptureFilePathTemplate = 119 | ::std::option::Option *const ::std::os::raw::c_char>; 120 | pub type pRENDERDOC_SetLogFilePathTemplate = pRENDERDOC_SetCaptureFilePathTemplate; 121 | pub type pRENDERDOC_GetLogFilePathTemplate = pRENDERDOC_GetCaptureFilePathTemplate; 122 | pub type pRENDERDOC_GetNumCaptures = ::std::option::Option u32>; 123 | pub type pRENDERDOC_GetCapture = ::std::option::Option< 124 | unsafe extern "C" fn( 125 | idx: u32, 126 | filename: *mut ::std::os::raw::c_char, 127 | pathlength: *mut u32, 128 | timestamp: *mut u64, 129 | ) -> u32, 130 | >; 131 | pub type pRENDERDOC_SetCaptureFileComments = ::std::option::Option< 132 | unsafe extern "C" fn( 133 | filePath: *const ::std::os::raw::c_char, 134 | comments: *const ::std::os::raw::c_char, 135 | ), 136 | >; 137 | pub type pRENDERDOC_IsTargetControlConnected = ::std::option::Option u32>; 138 | pub type pRENDERDOC_IsRemoteAccessConnected = pRENDERDOC_IsTargetControlConnected; 139 | pub type pRENDERDOC_LaunchReplayUI = ::std::option::Option< 140 | unsafe extern "C" fn(connectTargetControl: u32, cmdline: *const ::std::os::raw::c_char) -> u32, 141 | >; 142 | pub type pRENDERDOC_GetAPIVersion = ::std::option::Option< 143 | unsafe extern "C" fn( 144 | major: *mut ::std::os::raw::c_int, 145 | minor: *mut ::std::os::raw::c_int, 146 | patch: *mut ::std::os::raw::c_int, 147 | ), 148 | >; 149 | pub type pRENDERDOC_ShowReplayUI = ::std::option::Option u32>; 150 | pub type RENDERDOC_DevicePointer = *mut ::std::os::raw::c_void; 151 | pub type RENDERDOC_WindowHandle = *mut ::std::os::raw::c_void; 152 | pub type pRENDERDOC_SetActiveWindow = ::std::option::Option< 153 | unsafe extern "C" fn(device: RENDERDOC_DevicePointer, wndHandle: RENDERDOC_WindowHandle), 154 | >; 155 | pub type pRENDERDOC_TriggerCapture = ::std::option::Option; 156 | pub type pRENDERDOC_TriggerMultiFrameCapture = 157 | ::std::option::Option; 158 | pub type pRENDERDOC_StartFrameCapture = ::std::option::Option< 159 | unsafe extern "C" fn(device: RENDERDOC_DevicePointer, wndHandle: RENDERDOC_WindowHandle), 160 | >; 161 | pub type pRENDERDOC_IsFrameCapturing = ::std::option::Option u32>; 162 | pub type pRENDERDOC_EndFrameCapture = ::std::option::Option< 163 | unsafe extern "C" fn(device: RENDERDOC_DevicePointer, wndHandle: RENDERDOC_WindowHandle) -> u32, 164 | >; 165 | pub type pRENDERDOC_DiscardFrameCapture = ::std::option::Option< 166 | unsafe extern "C" fn(device: RENDERDOC_DevicePointer, wndHandle: RENDERDOC_WindowHandle) -> u32, 167 | >; 168 | pub type pRENDERDOC_SetCaptureTitle = 169 | ::std::option::Option; 170 | pub const eRENDERDOC_API_Version_1_0_0: RENDERDOC_Version = 10000; 171 | pub const eRENDERDOC_API_Version_1_0_1: RENDERDOC_Version = 10001; 172 | pub const eRENDERDOC_API_Version_1_0_2: RENDERDOC_Version = 10002; 173 | pub const eRENDERDOC_API_Version_1_1_0: RENDERDOC_Version = 10100; 174 | pub const eRENDERDOC_API_Version_1_1_1: RENDERDOC_Version = 10101; 175 | pub const eRENDERDOC_API_Version_1_1_2: RENDERDOC_Version = 10102; 176 | pub const eRENDERDOC_API_Version_1_2_0: RENDERDOC_Version = 10200; 177 | pub const eRENDERDOC_API_Version_1_3_0: RENDERDOC_Version = 10300; 178 | pub const eRENDERDOC_API_Version_1_4_0: RENDERDOC_Version = 10400; 179 | pub const eRENDERDOC_API_Version_1_4_1: RENDERDOC_Version = 10401; 180 | pub const eRENDERDOC_API_Version_1_4_2: RENDERDOC_Version = 10402; 181 | pub const eRENDERDOC_API_Version_1_5_0: RENDERDOC_Version = 10500; 182 | pub const eRENDERDOC_API_Version_1_6_0: RENDERDOC_Version = 10600; 183 | pub type RENDERDOC_Version = ::std::os::raw::c_uint; 184 | #[repr(C)] 185 | #[derive(Copy, Clone)] 186 | pub struct RENDERDOC_API_1_6_0 { 187 | pub GetAPIVersion: pRENDERDOC_GetAPIVersion, 188 | pub SetCaptureOptionU32: pRENDERDOC_SetCaptureOptionU32, 189 | pub SetCaptureOptionF32: pRENDERDOC_SetCaptureOptionF32, 190 | pub GetCaptureOptionU32: pRENDERDOC_GetCaptureOptionU32, 191 | pub GetCaptureOptionF32: pRENDERDOC_GetCaptureOptionF32, 192 | pub SetFocusToggleKeys: pRENDERDOC_SetFocusToggleKeys, 193 | pub SetCaptureKeys: pRENDERDOC_SetCaptureKeys, 194 | pub GetOverlayBits: pRENDERDOC_GetOverlayBits, 195 | pub MaskOverlayBits: pRENDERDOC_MaskOverlayBits, 196 | pub __bindgen_anon_1: RENDERDOC_API_1_6_0__bindgen_ty_1, 197 | pub UnloadCrashHandler: pRENDERDOC_UnloadCrashHandler, 198 | pub __bindgen_anon_2: RENDERDOC_API_1_6_0__bindgen_ty_2, 199 | pub __bindgen_anon_3: RENDERDOC_API_1_6_0__bindgen_ty_3, 200 | pub GetNumCaptures: pRENDERDOC_GetNumCaptures, 201 | pub GetCapture: pRENDERDOC_GetCapture, 202 | pub TriggerCapture: pRENDERDOC_TriggerCapture, 203 | pub __bindgen_anon_4: RENDERDOC_API_1_6_0__bindgen_ty_4, 204 | pub LaunchReplayUI: pRENDERDOC_LaunchReplayUI, 205 | pub SetActiveWindow: pRENDERDOC_SetActiveWindow, 206 | pub StartFrameCapture: pRENDERDOC_StartFrameCapture, 207 | pub IsFrameCapturing: pRENDERDOC_IsFrameCapturing, 208 | pub EndFrameCapture: pRENDERDOC_EndFrameCapture, 209 | pub TriggerMultiFrameCapture: pRENDERDOC_TriggerMultiFrameCapture, 210 | pub SetCaptureFileComments: pRENDERDOC_SetCaptureFileComments, 211 | pub DiscardFrameCapture: pRENDERDOC_DiscardFrameCapture, 212 | pub ShowReplayUI: pRENDERDOC_ShowReplayUI, 213 | pub SetCaptureTitle: pRENDERDOC_SetCaptureTitle, 214 | } 215 | #[repr(C)] 216 | #[derive(Copy, Clone)] 217 | pub union RENDERDOC_API_1_6_0__bindgen_ty_1 { 218 | pub Shutdown: pRENDERDOC_Shutdown, 219 | pub RemoveHooks: pRENDERDOC_RemoveHooks, 220 | } 221 | #[test] 222 | fn bindgen_test_layout_RENDERDOC_API_1_6_0__bindgen_ty_1() { 223 | const UNINIT: ::std::mem::MaybeUninit = 224 | ::std::mem::MaybeUninit::uninit(); 225 | let ptr = UNINIT.as_ptr(); 226 | assert_eq!( 227 | ::std::mem::size_of::(), 228 | 8usize, 229 | concat!("Size of: ", stringify!(RENDERDOC_API_1_6_0__bindgen_ty_1)) 230 | ); 231 | assert_eq!( 232 | ::std::mem::align_of::(), 233 | 8usize, 234 | concat!( 235 | "Alignment of ", 236 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_1) 237 | ) 238 | ); 239 | assert_eq!( 240 | unsafe { ::std::ptr::addr_of!((*ptr).Shutdown) as usize - ptr as usize }, 241 | 0usize, 242 | concat!( 243 | "Offset of field: ", 244 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_1), 245 | "::", 246 | stringify!(Shutdown) 247 | ) 248 | ); 249 | assert_eq!( 250 | unsafe { ::std::ptr::addr_of!((*ptr).RemoveHooks) as usize - ptr as usize }, 251 | 0usize, 252 | concat!( 253 | "Offset of field: ", 254 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_1), 255 | "::", 256 | stringify!(RemoveHooks) 257 | ) 258 | ); 259 | } 260 | impl ::std::fmt::Debug for RENDERDOC_API_1_6_0__bindgen_ty_1 { 261 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { 262 | write!(f, "RENDERDOC_API_1_6_0__bindgen_ty_1 {{ union }}") 263 | } 264 | } 265 | #[repr(C)] 266 | #[derive(Copy, Clone)] 267 | pub union RENDERDOC_API_1_6_0__bindgen_ty_2 { 268 | pub SetLogFilePathTemplate: pRENDERDOC_SetLogFilePathTemplate, 269 | pub SetCaptureFilePathTemplate: pRENDERDOC_SetCaptureFilePathTemplate, 270 | } 271 | #[test] 272 | fn bindgen_test_layout_RENDERDOC_API_1_6_0__bindgen_ty_2() { 273 | const UNINIT: ::std::mem::MaybeUninit = 274 | ::std::mem::MaybeUninit::uninit(); 275 | let ptr = UNINIT.as_ptr(); 276 | assert_eq!( 277 | ::std::mem::size_of::(), 278 | 8usize, 279 | concat!("Size of: ", stringify!(RENDERDOC_API_1_6_0__bindgen_ty_2)) 280 | ); 281 | assert_eq!( 282 | ::std::mem::align_of::(), 283 | 8usize, 284 | concat!( 285 | "Alignment of ", 286 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_2) 287 | ) 288 | ); 289 | assert_eq!( 290 | unsafe { ::std::ptr::addr_of!((*ptr).SetLogFilePathTemplate) as usize - ptr as usize }, 291 | 0usize, 292 | concat!( 293 | "Offset of field: ", 294 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_2), 295 | "::", 296 | stringify!(SetLogFilePathTemplate) 297 | ) 298 | ); 299 | assert_eq!( 300 | unsafe { ::std::ptr::addr_of!((*ptr).SetCaptureFilePathTemplate) as usize - ptr as usize }, 301 | 0usize, 302 | concat!( 303 | "Offset of field: ", 304 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_2), 305 | "::", 306 | stringify!(SetCaptureFilePathTemplate) 307 | ) 308 | ); 309 | } 310 | impl ::std::fmt::Debug for RENDERDOC_API_1_6_0__bindgen_ty_2 { 311 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { 312 | write!(f, "RENDERDOC_API_1_6_0__bindgen_ty_2 {{ union }}") 313 | } 314 | } 315 | #[repr(C)] 316 | #[derive(Copy, Clone)] 317 | pub union RENDERDOC_API_1_6_0__bindgen_ty_3 { 318 | pub GetLogFilePathTemplate: pRENDERDOC_GetLogFilePathTemplate, 319 | pub GetCaptureFilePathTemplate: pRENDERDOC_GetCaptureFilePathTemplate, 320 | } 321 | #[test] 322 | fn bindgen_test_layout_RENDERDOC_API_1_6_0__bindgen_ty_3() { 323 | const UNINIT: ::std::mem::MaybeUninit = 324 | ::std::mem::MaybeUninit::uninit(); 325 | let ptr = UNINIT.as_ptr(); 326 | assert_eq!( 327 | ::std::mem::size_of::(), 328 | 8usize, 329 | concat!("Size of: ", stringify!(RENDERDOC_API_1_6_0__bindgen_ty_3)) 330 | ); 331 | assert_eq!( 332 | ::std::mem::align_of::(), 333 | 8usize, 334 | concat!( 335 | "Alignment of ", 336 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_3) 337 | ) 338 | ); 339 | assert_eq!( 340 | unsafe { ::std::ptr::addr_of!((*ptr).GetLogFilePathTemplate) as usize - ptr as usize }, 341 | 0usize, 342 | concat!( 343 | "Offset of field: ", 344 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_3), 345 | "::", 346 | stringify!(GetLogFilePathTemplate) 347 | ) 348 | ); 349 | assert_eq!( 350 | unsafe { ::std::ptr::addr_of!((*ptr).GetCaptureFilePathTemplate) as usize - ptr as usize }, 351 | 0usize, 352 | concat!( 353 | "Offset of field: ", 354 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_3), 355 | "::", 356 | stringify!(GetCaptureFilePathTemplate) 357 | ) 358 | ); 359 | } 360 | impl ::std::fmt::Debug for RENDERDOC_API_1_6_0__bindgen_ty_3 { 361 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { 362 | write!(f, "RENDERDOC_API_1_6_0__bindgen_ty_3 {{ union }}") 363 | } 364 | } 365 | #[repr(C)] 366 | #[derive(Copy, Clone)] 367 | pub union RENDERDOC_API_1_6_0__bindgen_ty_4 { 368 | pub IsRemoteAccessConnected: pRENDERDOC_IsRemoteAccessConnected, 369 | pub IsTargetControlConnected: pRENDERDOC_IsTargetControlConnected, 370 | } 371 | #[test] 372 | fn bindgen_test_layout_RENDERDOC_API_1_6_0__bindgen_ty_4() { 373 | const UNINIT: ::std::mem::MaybeUninit = 374 | ::std::mem::MaybeUninit::uninit(); 375 | let ptr = UNINIT.as_ptr(); 376 | assert_eq!( 377 | ::std::mem::size_of::(), 378 | 8usize, 379 | concat!("Size of: ", stringify!(RENDERDOC_API_1_6_0__bindgen_ty_4)) 380 | ); 381 | assert_eq!( 382 | ::std::mem::align_of::(), 383 | 8usize, 384 | concat!( 385 | "Alignment of ", 386 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_4) 387 | ) 388 | ); 389 | assert_eq!( 390 | unsafe { ::std::ptr::addr_of!((*ptr).IsRemoteAccessConnected) as usize - ptr as usize }, 391 | 0usize, 392 | concat!( 393 | "Offset of field: ", 394 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_4), 395 | "::", 396 | stringify!(IsRemoteAccessConnected) 397 | ) 398 | ); 399 | assert_eq!( 400 | unsafe { ::std::ptr::addr_of!((*ptr).IsTargetControlConnected) as usize - ptr as usize }, 401 | 0usize, 402 | concat!( 403 | "Offset of field: ", 404 | stringify!(RENDERDOC_API_1_6_0__bindgen_ty_4), 405 | "::", 406 | stringify!(IsTargetControlConnected) 407 | ) 408 | ); 409 | } 410 | impl ::std::fmt::Debug for RENDERDOC_API_1_6_0__bindgen_ty_4 { 411 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { 412 | write!(f, "RENDERDOC_API_1_6_0__bindgen_ty_4 {{ union }}") 413 | } 414 | } 415 | #[test] 416 | fn bindgen_test_layout_RENDERDOC_API_1_6_0() { 417 | const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); 418 | let ptr = UNINIT.as_ptr(); 419 | assert_eq!( 420 | ::std::mem::size_of::(), 421 | 216usize, 422 | concat!("Size of: ", stringify!(RENDERDOC_API_1_6_0)) 423 | ); 424 | assert_eq!( 425 | ::std::mem::align_of::(), 426 | 8usize, 427 | concat!("Alignment of ", stringify!(RENDERDOC_API_1_6_0)) 428 | ); 429 | assert_eq!( 430 | unsafe { ::std::ptr::addr_of!((*ptr).GetAPIVersion) as usize - ptr as usize }, 431 | 0usize, 432 | concat!( 433 | "Offset of field: ", 434 | stringify!(RENDERDOC_API_1_6_0), 435 | "::", 436 | stringify!(GetAPIVersion) 437 | ) 438 | ); 439 | assert_eq!( 440 | unsafe { ::std::ptr::addr_of!((*ptr).SetCaptureOptionU32) as usize - ptr as usize }, 441 | 8usize, 442 | concat!( 443 | "Offset of field: ", 444 | stringify!(RENDERDOC_API_1_6_0), 445 | "::", 446 | stringify!(SetCaptureOptionU32) 447 | ) 448 | ); 449 | assert_eq!( 450 | unsafe { ::std::ptr::addr_of!((*ptr).SetCaptureOptionF32) as usize - ptr as usize }, 451 | 16usize, 452 | concat!( 453 | "Offset of field: ", 454 | stringify!(RENDERDOC_API_1_6_0), 455 | "::", 456 | stringify!(SetCaptureOptionF32) 457 | ) 458 | ); 459 | assert_eq!( 460 | unsafe { ::std::ptr::addr_of!((*ptr).GetCaptureOptionU32) as usize - ptr as usize }, 461 | 24usize, 462 | concat!( 463 | "Offset of field: ", 464 | stringify!(RENDERDOC_API_1_6_0), 465 | "::", 466 | stringify!(GetCaptureOptionU32) 467 | ) 468 | ); 469 | assert_eq!( 470 | unsafe { ::std::ptr::addr_of!((*ptr).GetCaptureOptionF32) as usize - ptr as usize }, 471 | 32usize, 472 | concat!( 473 | "Offset of field: ", 474 | stringify!(RENDERDOC_API_1_6_0), 475 | "::", 476 | stringify!(GetCaptureOptionF32) 477 | ) 478 | ); 479 | assert_eq!( 480 | unsafe { ::std::ptr::addr_of!((*ptr).SetFocusToggleKeys) as usize - ptr as usize }, 481 | 40usize, 482 | concat!( 483 | "Offset of field: ", 484 | stringify!(RENDERDOC_API_1_6_0), 485 | "::", 486 | stringify!(SetFocusToggleKeys) 487 | ) 488 | ); 489 | assert_eq!( 490 | unsafe { ::std::ptr::addr_of!((*ptr).SetCaptureKeys) as usize - ptr as usize }, 491 | 48usize, 492 | concat!( 493 | "Offset of field: ", 494 | stringify!(RENDERDOC_API_1_6_0), 495 | "::", 496 | stringify!(SetCaptureKeys) 497 | ) 498 | ); 499 | assert_eq!( 500 | unsafe { ::std::ptr::addr_of!((*ptr).GetOverlayBits) as usize - ptr as usize }, 501 | 56usize, 502 | concat!( 503 | "Offset of field: ", 504 | stringify!(RENDERDOC_API_1_6_0), 505 | "::", 506 | stringify!(GetOverlayBits) 507 | ) 508 | ); 509 | assert_eq!( 510 | unsafe { ::std::ptr::addr_of!((*ptr).MaskOverlayBits) as usize - ptr as usize }, 511 | 64usize, 512 | concat!( 513 | "Offset of field: ", 514 | stringify!(RENDERDOC_API_1_6_0), 515 | "::", 516 | stringify!(MaskOverlayBits) 517 | ) 518 | ); 519 | assert_eq!( 520 | unsafe { ::std::ptr::addr_of!((*ptr).UnloadCrashHandler) as usize - ptr as usize }, 521 | 80usize, 522 | concat!( 523 | "Offset of field: ", 524 | stringify!(RENDERDOC_API_1_6_0), 525 | "::", 526 | stringify!(UnloadCrashHandler) 527 | ) 528 | ); 529 | assert_eq!( 530 | unsafe { ::std::ptr::addr_of!((*ptr).GetNumCaptures) as usize - ptr as usize }, 531 | 104usize, 532 | concat!( 533 | "Offset of field: ", 534 | stringify!(RENDERDOC_API_1_6_0), 535 | "::", 536 | stringify!(GetNumCaptures) 537 | ) 538 | ); 539 | assert_eq!( 540 | unsafe { ::std::ptr::addr_of!((*ptr).GetCapture) as usize - ptr as usize }, 541 | 112usize, 542 | concat!( 543 | "Offset of field: ", 544 | stringify!(RENDERDOC_API_1_6_0), 545 | "::", 546 | stringify!(GetCapture) 547 | ) 548 | ); 549 | assert_eq!( 550 | unsafe { ::std::ptr::addr_of!((*ptr).TriggerCapture) as usize - ptr as usize }, 551 | 120usize, 552 | concat!( 553 | "Offset of field: ", 554 | stringify!(RENDERDOC_API_1_6_0), 555 | "::", 556 | stringify!(TriggerCapture) 557 | ) 558 | ); 559 | assert_eq!( 560 | unsafe { ::std::ptr::addr_of!((*ptr).LaunchReplayUI) as usize - ptr as usize }, 561 | 136usize, 562 | concat!( 563 | "Offset of field: ", 564 | stringify!(RENDERDOC_API_1_6_0), 565 | "::", 566 | stringify!(LaunchReplayUI) 567 | ) 568 | ); 569 | assert_eq!( 570 | unsafe { ::std::ptr::addr_of!((*ptr).SetActiveWindow) as usize - ptr as usize }, 571 | 144usize, 572 | concat!( 573 | "Offset of field: ", 574 | stringify!(RENDERDOC_API_1_6_0), 575 | "::", 576 | stringify!(SetActiveWindow) 577 | ) 578 | ); 579 | assert_eq!( 580 | unsafe { ::std::ptr::addr_of!((*ptr).StartFrameCapture) as usize - ptr as usize }, 581 | 152usize, 582 | concat!( 583 | "Offset of field: ", 584 | stringify!(RENDERDOC_API_1_6_0), 585 | "::", 586 | stringify!(StartFrameCapture) 587 | ) 588 | ); 589 | assert_eq!( 590 | unsafe { ::std::ptr::addr_of!((*ptr).IsFrameCapturing) as usize - ptr as usize }, 591 | 160usize, 592 | concat!( 593 | "Offset of field: ", 594 | stringify!(RENDERDOC_API_1_6_0), 595 | "::", 596 | stringify!(IsFrameCapturing) 597 | ) 598 | ); 599 | assert_eq!( 600 | unsafe { ::std::ptr::addr_of!((*ptr).EndFrameCapture) as usize - ptr as usize }, 601 | 168usize, 602 | concat!( 603 | "Offset of field: ", 604 | stringify!(RENDERDOC_API_1_6_0), 605 | "::", 606 | stringify!(EndFrameCapture) 607 | ) 608 | ); 609 | assert_eq!( 610 | unsafe { ::std::ptr::addr_of!((*ptr).TriggerMultiFrameCapture) as usize - ptr as usize }, 611 | 176usize, 612 | concat!( 613 | "Offset of field: ", 614 | stringify!(RENDERDOC_API_1_6_0), 615 | "::", 616 | stringify!(TriggerMultiFrameCapture) 617 | ) 618 | ); 619 | assert_eq!( 620 | unsafe { ::std::ptr::addr_of!((*ptr).SetCaptureFileComments) as usize - ptr as usize }, 621 | 184usize, 622 | concat!( 623 | "Offset of field: ", 624 | stringify!(RENDERDOC_API_1_6_0), 625 | "::", 626 | stringify!(SetCaptureFileComments) 627 | ) 628 | ); 629 | assert_eq!( 630 | unsafe { ::std::ptr::addr_of!((*ptr).DiscardFrameCapture) as usize - ptr as usize }, 631 | 192usize, 632 | concat!( 633 | "Offset of field: ", 634 | stringify!(RENDERDOC_API_1_6_0), 635 | "::", 636 | stringify!(DiscardFrameCapture) 637 | ) 638 | ); 639 | assert_eq!( 640 | unsafe { ::std::ptr::addr_of!((*ptr).ShowReplayUI) as usize - ptr as usize }, 641 | 200usize, 642 | concat!( 643 | "Offset of field: ", 644 | stringify!(RENDERDOC_API_1_6_0), 645 | "::", 646 | stringify!(ShowReplayUI) 647 | ) 648 | ); 649 | assert_eq!( 650 | unsafe { ::std::ptr::addr_of!((*ptr).SetCaptureTitle) as usize - ptr as usize }, 651 | 208usize, 652 | concat!( 653 | "Offset of field: ", 654 | stringify!(RENDERDOC_API_1_6_0), 655 | "::", 656 | stringify!(SetCaptureTitle) 657 | ) 658 | ); 659 | } 660 | impl ::std::fmt::Debug for RENDERDOC_API_1_6_0 { 661 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { 662 | write ! (f , "RENDERDOC_API_1_6_0 {{ GetAPIVersion: {:?}, SetCaptureOptionU32: {:?}, SetCaptureOptionF32: {:?}, GetCaptureOptionU32: {:?}, GetCaptureOptionF32: {:?}, SetFocusToggleKeys: {:?}, SetCaptureKeys: {:?}, GetOverlayBits: {:?}, MaskOverlayBits: {:?}, __bindgen_anon_1: {:?}, UnloadCrashHandler: {:?}, __bindgen_anon_2: {:?}, __bindgen_anon_3: {:?}, GetNumCaptures: {:?}, GetCapture: {:?}, TriggerCapture: {:?}, __bindgen_anon_4: {:?}, LaunchReplayUI: {:?}, SetActiveWindow: {:?}, StartFrameCapture: {:?}, IsFrameCapturing: {:?}, EndFrameCapture: {:?}, TriggerMultiFrameCapture: {:?}, SetCaptureFileComments: {:?}, DiscardFrameCapture: {:?}, ShowReplayUI: {:?}, SetCaptureTitle: {:?} }}" , self . GetAPIVersion , self . SetCaptureOptionU32 , self . SetCaptureOptionF32 , self . GetCaptureOptionU32 , self . GetCaptureOptionF32 , self . SetFocusToggleKeys , self . SetCaptureKeys , self . GetOverlayBits , self . MaskOverlayBits , self . __bindgen_anon_1 , self . UnloadCrashHandler , self . __bindgen_anon_2 , self . __bindgen_anon_3 , self . GetNumCaptures , self . GetCapture , self . TriggerCapture , self . __bindgen_anon_4 , self . LaunchReplayUI , self . SetActiveWindow , self . StartFrameCapture , self . IsFrameCapturing , self . EndFrameCapture , self . TriggerMultiFrameCapture , self . SetCaptureFileComments , self . DiscardFrameCapture , self . ShowReplayUI , self . SetCaptureTitle) 663 | } 664 | } 665 | pub type RENDERDOC_API_1_0_0 = RENDERDOC_API_1_6_0; 666 | pub type RENDERDOC_API_1_0_1 = RENDERDOC_API_1_6_0; 667 | pub type RENDERDOC_API_1_0_2 = RENDERDOC_API_1_6_0; 668 | pub type RENDERDOC_API_1_1_0 = RENDERDOC_API_1_6_0; 669 | pub type RENDERDOC_API_1_1_1 = RENDERDOC_API_1_6_0; 670 | pub type RENDERDOC_API_1_1_2 = RENDERDOC_API_1_6_0; 671 | pub type RENDERDOC_API_1_2_0 = RENDERDOC_API_1_6_0; 672 | pub type RENDERDOC_API_1_3_0 = RENDERDOC_API_1_6_0; 673 | pub type RENDERDOC_API_1_4_0 = RENDERDOC_API_1_6_0; 674 | pub type RENDERDOC_API_1_4_1 = RENDERDOC_API_1_6_0; 675 | pub type RENDERDOC_API_1_4_2 = RENDERDOC_API_1_6_0; 676 | pub type RENDERDOC_API_1_5_0 = RENDERDOC_API_1_6_0; 677 | pub type pRENDERDOC_GetAPI = ::std::option::Option< 678 | unsafe extern "C" fn( 679 | version: RENDERDOC_Version, 680 | outAPIPointers: *mut *mut ::std::os::raw::c_void, 681 | ) -> ::std::os::raw::c_int, 682 | >; 683 | -------------------------------------------------------------------------------- /renderdoc-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Low-level bindings to the [RenderDoc](https://renderdoc.org/) in-application API. 2 | //! 3 | //! RenderDoc is a free and open source debugger for real-time graphics providing quick and easy 4 | //! frame captures and detailed introspection of any application using [Vulkan], [Direct3D 11], 5 | //! [Direct3D 12], [OpenGL], and [OpenGL ES]. 6 | //! 7 | //! [Vulkan]: https://www.vulkan.org/ 8 | //! [Direct3D 11]: https://learn.microsoft.com/en-us/windows/win32/direct3d11/atoc-dx-graphics-direct3d-11 9 | //! [Direct3D 12]: https://learn.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-graphics 10 | //! [OpenGL]: https://www.khronos.org/opengl/ 11 | //! [OpenGL ES]: https://www.khronos.org/opengles/ 12 | //! 13 | //! These bindings are automatically generated from [`renderdoc_app.h`] with [`bindgen`]. This 14 | //! crate does not provide nor link to the `renderdoc.dll` or `librenderdoc.so` libraries on its 15 | //! own; it only contains FFI symbols. Refer to the official [In-Application API][api] 16 | //! documentation for correct usage. 17 | //! 18 | //! [`renderdoc_app.h`]: https://github.com/baldurk/renderdoc/blob/v1.x/renderdoc/api/app/renderdoc_app.h 19 | //! [`bindgen`]: https://github.com/rust-lang/rust-bindgen 20 | //! [api]: https://renderdoc.org/docs/in_application_api.html 21 | //! 22 | //! For a safe wrapper, see the [`renderdoc`](https://docs.rs/renderdoc) crate. 23 | 24 | #![allow(non_camel_case_types)] 25 | #![allow(non_snake_case)] 26 | #![allow(non_upper_case_globals)] 27 | 28 | include!("./bindings.rs"); 29 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | //! Common library error types. 2 | 3 | use std::fmt::{self, Display, Formatter}; 4 | 5 | /// Errors that can occur with the RenderDoc in-application API. 6 | #[derive(Debug)] 7 | pub struct Error(ErrorKind); 8 | 9 | impl Error { 10 | pub(crate) fn library(cause: libloading::Error) -> Self { 11 | Error(ErrorKind::Library(cause)) 12 | } 13 | 14 | pub(crate) fn symbol(cause: libloading::Error) -> Self { 15 | Error(ErrorKind::Symbol(cause)) 16 | } 17 | 18 | pub(crate) fn no_compatible_api() -> Self { 19 | Error(ErrorKind::NoCompatibleApi) 20 | } 21 | 22 | pub(crate) fn launch_replay_ui() -> Self { 23 | Error(ErrorKind::LaunchReplayUi) 24 | } 25 | } 26 | 27 | impl Display for Error { 28 | fn fmt(&self, f: &mut Formatter) -> fmt::Result { 29 | match self.0 { 30 | ErrorKind::Library(_) => write!(f, "Unable to load RenderDoc shared library"), 31 | ErrorKind::Symbol(_) => write!(f, "Unable to find `RENDERDOC_GetAPI` symbol"), 32 | ErrorKind::NoCompatibleApi => write!(f, "Library could not provide compatible API"), 33 | ErrorKind::LaunchReplayUi => write!(f, "Failed to launch replay UI"), 34 | } 35 | } 36 | } 37 | 38 | impl std::error::Error for Error { 39 | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 40 | match self.0 { 41 | ErrorKind::Library(ref e) | ErrorKind::Symbol(ref e) => Some(e), 42 | _ => None, 43 | } 44 | } 45 | } 46 | 47 | #[derive(Debug)] 48 | enum ErrorKind { 49 | Library(libloading::Error), 50 | Symbol(libloading::Error), 51 | NoCompatibleApi, 52 | LaunchReplayUi, 53 | } 54 | -------------------------------------------------------------------------------- /src/handles.rs: -------------------------------------------------------------------------------- 1 | //! Portable wrapper types around platform specific window and device handles. 2 | 3 | use std::os::raw::c_void; 4 | 5 | #[cfg(windows)] 6 | use wio::com::ComPtr; 7 | 8 | /// Raw mutable pointer to the OS-provided window handle. 9 | pub type WindowHandle = *const c_void; 10 | 11 | /// Raw mutable pointer to the API's root handle. 12 | /// 13 | /// For example, this could be a pointer to an `ID3D11Device`, `HGLRC`/`GLXContext`, 14 | /// `ID3D12Device`, etc. 15 | #[derive(Clone, Debug, Eq, Hash, PartialEq)] 16 | pub struct DevicePointer(pub(crate) *const c_void); 17 | 18 | impl From<*const c_void> for DevicePointer { 19 | fn from(ptr: *const c_void) -> Self { 20 | DevicePointer(ptr) 21 | } 22 | } 23 | 24 | impl From<*mut c_void> for DevicePointer { 25 | fn from(ptr: *mut c_void) -> Self { 26 | DevicePointer(ptr) 27 | } 28 | } 29 | 30 | #[cfg(windows)] 31 | impl From for DevicePointer { 32 | fn from(ctx: winapi::shared::windef::HGLRC) -> Self { 33 | DevicePointer(ctx as *mut _ as *const c_void) 34 | } 35 | } 36 | 37 | #[cfg(windows)] 38 | impl From<*mut winapi::um::d3d11::ID3D11Device> for DevicePointer { 39 | fn from(ctx: *mut winapi::um::d3d11::ID3D11Device) -> Self { 40 | DevicePointer(ctx as *mut _ as *const c_void) 41 | } 42 | } 43 | 44 | #[cfg(windows)] 45 | impl From> for DevicePointer { 46 | fn from(ctx: wio::com::ComPtr) -> Self { 47 | DevicePointer(ctx.as_raw() as *mut _ as *const c_void) 48 | } 49 | } 50 | 51 | #[cfg(windows)] 52 | impl From<*mut winapi::um::d3d12::ID3D12Device> for DevicePointer { 53 | fn from(ctx: *mut winapi::um::d3d12::ID3D12Device) -> Self { 54 | DevicePointer(ctx as *mut _ as *const c_void) 55 | } 56 | } 57 | 58 | #[cfg(windows)] 59 | impl From> for DevicePointer { 60 | fn from(ctx: wio::com::ComPtr) -> Self { 61 | DevicePointer(ctx.as_raw() as *mut _ as *const c_void) 62 | } 63 | } 64 | 65 | #[cfg(feature = "glutin")] 66 | impl<'a, T: glutin::context::AsRawContext> From<&'a T> for DevicePointer { 67 | fn from(ctx: &'a T) -> Self { 68 | use glutin::context::RawContext; 69 | 70 | #[cfg(unix)] 71 | match ctx.raw_context() { 72 | RawContext::Egl(egl) => DevicePointer::from(egl), 73 | RawContext::Glx(glx) => DevicePointer::from(glx), 74 | } 75 | 76 | #[cfg(windows)] 77 | match ctx.raw_context() { 78 | RawContext::Egl(egl) => DevicePointer::from(egl), 79 | RawContext::Wgl(wgl) => DevicePointer::from(wgl), 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Rust bindings to [RenderDoc], a popular graphics debugger. 2 | //! 3 | //! [RenderDoc]: https://renderdoc.org/ 4 | //! 5 | //! RenderDoc is a free and open source debugger for real-time graphics providing quick and easy 6 | //! frame captures and detailed introspection of any application using [Vulkan], [Direct3D 11], 7 | //! [Direct3D 12], [OpenGL], and [OpenGL ES]. 8 | //! 9 | //! [Vulkan]: https://www.vulkan.org/ 10 | //! [Direct3D 11]: https://learn.microsoft.com/en-us/windows/win32/direct3d11/atoc-dx-graphics-direct3d-11 11 | //! [Direct3D 12]: https://learn.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-graphics 12 | //! [OpenGL]: https://www.khronos.org/opengl/ 13 | //! [OpenGL ES]: https://www.khronos.org/opengles/ 14 | //! 15 | //! These bindings require that RenderDoc be installed on the target machine, with either 16 | //! `renderdoc.dll` or `librenderdoc.so` visible from your `$PATH`. 17 | //! 18 | //! For more details on how to use this API to integrate your game or renderer with the RenderDoc 19 | //! profiler, consult the upstream [in-application API][in-app] documentation. 20 | //! 21 | //! [in-app]: https://renderdoc.org/docs/in_application_api.html 22 | 23 | #![deny(missing_docs)] 24 | #![deny(missing_debug_implementations)] 25 | 26 | #[cfg(any(target_os = "macos", target_os = "ios"))] 27 | compile_error!("RenderDoc does not support this platform."); 28 | 29 | pub use self::error::Error; 30 | pub use self::handles::{DevicePointer, WindowHandle}; 31 | pub use self::renderdoc::RenderDoc; 32 | pub use self::settings::{CaptureOption, InputButton, OverlayBits}; 33 | pub use self::version::{ 34 | Entry, HasPrevious, Version, V100, V110, V111, V112, V120, V130, V140, V141, 35 | }; 36 | 37 | use std::os::raw::c_ulonglong; 38 | 39 | #[cfg(windows)] 40 | use winapi::shared::guiddef::GUID; 41 | 42 | mod error; 43 | mod handles; 44 | mod renderdoc; 45 | mod settings; 46 | mod version; 47 | 48 | /// Magic value used for when applications pass a path where shader debug information can be found 49 | /// to match up with a stripped shader. 50 | /// 51 | /// Windows GUID representation intended for consumption by D3D. 52 | #[cfg(windows)] 53 | pub const SHADER_MAGIC_DEBUG_VALUE_STRUCT: GUID = GUID { 54 | Data1: 0xeab25520, 55 | Data2: 0x6670, 56 | Data3: 0x4865, 57 | Data4: [0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff], 58 | }; 59 | 60 | /// Magic value used for when applications pass a path where shader debug information can be found 61 | /// to match up with a stripped shader. 62 | /// 63 | /// Raw byte array representation (assuming x86 endianness). 64 | pub const SHADER_MAGIC_DEBUG_VALUE_BYTE_ARRAY: &[u8] = &[ 65 | 0x20, 0x55, 0xb2, 0xea, 0x70, 0x66, 0x65, 0x48, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff, 66 | ]; 67 | 68 | /// Magic value used for when applications pass a path where shader debug information can be found 69 | /// to match up with a stripped shader. 70 | /// 71 | /// Truncated version when only a `uint64_t` is available (e.g. Vulkan tags). 72 | pub const SHADER_MAGIC_DEBUG_VALUE_TRUNCATED: c_ulonglong = 0x0485_6670_eab2_5520; 73 | 74 | #[cfg(test)] 75 | mod tests { 76 | use super::*; 77 | 78 | #[test] 79 | fn get_set_capture_option_f32() { 80 | let mut rd: RenderDoc = RenderDoc::new().expect("Failed to init"); 81 | 82 | let delay = rd.get_capture_option_f32(CaptureOption::DelayForDebugger); 83 | assert_eq!(delay, 0.0f32); 84 | 85 | rd.set_capture_option_f32(CaptureOption::DelayForDebugger, 2.5f32); 86 | let delay = rd.get_capture_option_f32(CaptureOption::DelayForDebugger); 87 | assert_eq!(delay, 2.0f32); 88 | } 89 | 90 | #[test] 91 | fn get_set_capture_option_u32() { 92 | let rd: RenderDoc = RenderDoc::new().expect("Failed to init"); 93 | 94 | let vsync = rd.get_capture_option_u32(CaptureOption::AllowVSync); 95 | assert_eq!(vsync, 1u32); 96 | 97 | let is_full = rd.get_capture_option_u32(CaptureOption::AllowFullscreen); 98 | assert_eq!(is_full, 1u32); 99 | 100 | let api_val_mode = rd.get_capture_option_u32(CaptureOption::ApiValidation); 101 | let debug_mode = rd.get_capture_option_u32(CaptureOption::ApiValidation); 102 | assert_eq!(api_val_mode, 0u32); 103 | assert_eq!(api_val_mode, debug_mode); 104 | 105 | let cc = rd.get_capture_option_u32(CaptureOption::CaptureCallstacks); 106 | assert_eq!(cc, 0u32); 107 | 108 | let cc_draw = rd.get_capture_option_u32(CaptureOption::CaptureCallstacksOnlyDraws); 109 | assert_eq!(cc_draw, 0u32); 110 | 111 | let ver_map = rd.get_capture_option_u32(CaptureOption::VerifyMapWrites); 112 | assert_eq!(ver_map, 0u32); 113 | 114 | let hook_in = rd.get_capture_option_u32(CaptureOption::HookIntoChildren); 115 | assert_eq!(hook_in, 0u32); 116 | 117 | let ref_all = rd.get_capture_option_u32(CaptureOption::RefAllResources); 118 | assert_eq!(ref_all, 0u32); 119 | 120 | let intls = rd.get_capture_option_u32(CaptureOption::SaveAllInitials); 121 | assert_eq!(intls, 1u32); 122 | 123 | let cmds = rd.get_capture_option_u32(CaptureOption::CaptureAllCmdLists); 124 | assert_eq!(cmds, 0u32); 125 | 126 | let is_muted = rd.get_capture_option_u32(CaptureOption::DebugOutputMute); 127 | assert_eq!(is_muted, 1u32); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/renderdoc.rs: -------------------------------------------------------------------------------- 1 | //! Type-safe wrapper around the RenderDoc API. 2 | 3 | use std::ffi::{CStr, CString}; 4 | use std::fmt::{Debug, Formatter, Result as FmtResult}; 5 | use std::marker::PhantomData; 6 | use std::ops::{Deref, DerefMut}; 7 | use std::path::{Path, PathBuf}; 8 | use std::time::{Duration, SystemTime}; 9 | use std::{ptr, time}; 10 | 11 | use float_cmp::approx_eq; 12 | 13 | use crate::error::Error; 14 | use crate::handles::{DevicePointer, WindowHandle}; 15 | use crate::settings::{CaptureOption, InputButton, OverlayBits}; 16 | use crate::version::{Entry, HasPrevious, Version, V100, V110, V111, V112, V120, V130, V140, V141}; 17 | 18 | /// An instance of the RenderDoc API with baseline version `V`. 19 | #[repr(C)] 20 | #[derive(Eq, Hash, PartialEq)] 21 | pub struct RenderDoc(*mut Entry, PhantomData); 22 | 23 | impl RenderDoc { 24 | /// Initializes a new instance of the RenderDoc API. 25 | pub fn new() -> Result { 26 | let api = V::load()?; 27 | Ok(RenderDoc(api, PhantomData)) 28 | } 29 | 30 | /// Returns the raw entry point of the API. 31 | /// 32 | /// # Safety 33 | /// 34 | /// Using the entry point structure directly will discard any thread safety provided by 35 | /// default with this library. 36 | pub unsafe fn raw_api(&self) -> *mut Entry { 37 | self.0 38 | } 39 | 40 | /// Attempts to shut down RenderDoc. 41 | /// 42 | /// # Safety 43 | /// 44 | /// Note that this will work correctly if done _immediately_ after the dynamic library is 45 | /// loaded, before any API work happens. At that point, RenderDoc will remove its injected 46 | /// hooks and shut down. Behavior is undefined if this is called after any API functions have 47 | /// been called. 48 | /// 49 | /// # Compatibility 50 | /// 51 | /// This process is only possible on Windows, and even then it is not well defined so may not 52 | /// be possible in all circumstances. This function is provided at your own risk. 53 | // FIXME: Need to move this to `RenderDoc` and add `remove_hooks()` to `RenderDoc`. 54 | // This is currently impossible to do until https://github.com/rust-lang/rfcs/issues/997 is 55 | // resolved, since `Deref` nor `DerefMut` is sufficient for the task. 56 | pub unsafe fn shutdown(self) { 57 | ((*self.0).__bindgen_anon_1.Shutdown.unwrap())(); 58 | } 59 | } 60 | 61 | impl RenderDoc { 62 | /// Downgrades the current API version to the version immediately preceding it. 63 | /// 64 | /// # Examples 65 | /// 66 | /// ```rust 67 | /// # use renderdoc::{Error, RenderDoc, V100, V111, V112}; 68 | /// # fn main() -> Result<(), Error> { 69 | /// let current: RenderDoc = RenderDoc::new()?; 70 | /// let previous: RenderDoc = current.downgrade(); 71 | /// // let older: RenderDoc = previous.downgrade(); // This line does not compile 72 | /// # Ok(()) 73 | /// # } 74 | /// ``` 75 | pub fn downgrade(self) -> RenderDoc { 76 | let RenderDoc(entry, _) = self; 77 | RenderDoc(entry, PhantomData) 78 | } 79 | } 80 | 81 | #[doc(hidden)] 82 | impl Deref for RenderDoc { 83 | type Target = RenderDoc; 84 | 85 | fn deref(&self) -> &Self::Target { 86 | // NOTE: This transmutation is safe because the entry point type and layout does not change 87 | // between API versions. This call only serves as type-level magic to expose the inherent 88 | // methods in a backwards-compatible way. 89 | unsafe { &*(self as *const RenderDoc as *const RenderDoc<::Previous>) } 90 | } 91 | } 92 | 93 | impl DerefMut for RenderDoc { 94 | fn deref_mut(&mut self) -> &mut Self::Target { 95 | // NOTE: This transmutation is safe because the entry point type and layout does not change 96 | // between API versions. This call only serves as type-level magic to expose the inherent 97 | // methods in a backwards-compatible way. 98 | unsafe { &mut *(self as *mut RenderDoc as *mut RenderDoc<::Previous>) } 99 | } 100 | } 101 | 102 | impl RenderDoc { 103 | /// Returns the major, minor, and patch version numbers of the RenderDoc API currently in use. 104 | /// 105 | /// Note that RenderDoc will usually provide a higher API version than the one requested by 106 | /// the user if it's backwards compatible. 107 | /// 108 | /// # Examples 109 | /// 110 | /// ```rust 111 | /// # use renderdoc::{Error, RenderDoc, V100}; 112 | /// # fn main() -> Result<(), Error> { 113 | /// let renderdoc: RenderDoc = RenderDoc::new()?; 114 | /// let (major, minor, patch) = renderdoc.get_api_version(); 115 | /// assert_eq!(major, 1); 116 | /// # Ok(()) 117 | /// # } 118 | /// ``` 119 | pub fn get_api_version(&self) -> (u32, u32, u32) { 120 | unsafe { 121 | let (mut major, mut minor, mut patch) = (0, 0, 0); 122 | ((*self.0).GetAPIVersion.unwrap())(&mut major, &mut minor, &mut patch); 123 | (major as u32, minor as u32, patch as u32) 124 | } 125 | } 126 | 127 | /// Sets the specified `CaptureOption` to the given `f32` value. 128 | /// 129 | /// # Panics 130 | /// 131 | /// This method will panic if the option and/or the value are invalid. 132 | pub fn set_capture_option_f32(&mut self, opt: CaptureOption, val: f32) { 133 | let err = unsafe { ((*self.0).SetCaptureOptionF32.unwrap())(opt as u32, val) }; 134 | assert_eq!(err, 1); 135 | } 136 | 137 | /// Sets the specified `CaptureOption` to the given `u32` value. 138 | /// 139 | /// # Panics 140 | /// 141 | /// This method will panic if the option and/or the value are invalid. 142 | pub fn set_capture_option_u32(&mut self, opt: CaptureOption, val: u32) { 143 | let err = unsafe { ((*self.0).SetCaptureOptionU32.unwrap())(opt as u32, val) }; 144 | assert_eq!(err, 1); 145 | } 146 | 147 | /// Returns the value of the given `CaptureOption` as an `f32` value. 148 | /// 149 | /// # Panics 150 | /// 151 | /// This method will panic if the option is invalid. 152 | pub fn get_capture_option_f32(&self, opt: CaptureOption) -> f32 { 153 | use std::f32::MAX; 154 | let val = unsafe { ((*self.0).GetCaptureOptionF32.unwrap())(opt as u32) }; 155 | assert!(!approx_eq!(f32, val, -MAX)); 156 | val 157 | } 158 | 159 | /// Returns the value of the given `CaptureOption` as a `u32` value. 160 | /// 161 | /// # Panics 162 | /// 163 | /// This method will panic if the option is invalid. 164 | pub fn get_capture_option_u32(&self, opt: CaptureOption) -> u32 { 165 | use std::u32::MAX; 166 | let val = unsafe { ((*self.0).GetCaptureOptionU32.unwrap())(opt as u32) }; 167 | assert_ne!(val, MAX); 168 | val 169 | } 170 | 171 | /// Sets the key bindings used in-application to trigger a capture on the current window. 172 | /// 173 | /// If the `keys` slice is empty, all existing capture key bindings are disabled. 174 | pub fn set_capture_keys + Clone>(&mut self, keys: &[I]) { 175 | unsafe { 176 | let mut k: Vec<_> = keys.iter().cloned().map(|k| k.into() as u32).collect(); 177 | ((*self.0).SetCaptureKeys.unwrap())(k.as_mut_ptr(), k.len() as i32) 178 | } 179 | } 180 | 181 | /// Sets the key bindings used in-application to switch focus between windows. 182 | /// 183 | /// If the `keys` slice is empty, all existing focus toggle key bindings are disabled. 184 | pub fn set_focus_toggle_keys + Clone>(&mut self, keys: &[I]) { 185 | unsafe { 186 | let mut k: Vec<_> = keys.iter().cloned().map(|k| k.into() as u32).collect(); 187 | ((*self.0).SetFocusToggleKeys.unwrap())(k.as_mut_ptr(), k.len() as i32) 188 | } 189 | } 190 | 191 | /// Removes RenderDoc's injected crash handler from the current process. 192 | /// 193 | /// This allows you to provide your own global crash handler with which to handle exceptions, 194 | /// if you so desire. After the crash handler has been removed, subsequent calls to this method 195 | /// will do nothing. 196 | pub fn unload_crash_handler(&mut self) { 197 | unsafe { 198 | ((*self.0).UnloadCrashHandler.unwrap())(); 199 | } 200 | } 201 | 202 | /// Returns a bitmask representing which elements of the RenderDoc overlay are being rendered 203 | /// on each window. 204 | pub fn get_overlay_bits(&self) -> OverlayBits { 205 | let bits = unsafe { ((*self.0).GetOverlayBits.unwrap())() }; 206 | OverlayBits::from_bits_truncate(bits) 207 | } 208 | 209 | /// Applies the given `and` and `or` bitflags to determine which elements of the RenderDoc 210 | /// overlay should be rendered on each window. 211 | /// 212 | /// This method applies `and` to the current mask with a bitwise-and, and then applies `or` 213 | /// using a bitwise-or on top. 214 | pub fn mask_overlay_bits(&mut self, and: OverlayBits, or: OverlayBits) { 215 | unsafe { 216 | ((*self.0).MaskOverlayBits.unwrap())(and.bits(), or.bits()); 217 | } 218 | } 219 | 220 | /// Returns the path template where new captures will be stored. 221 | /// 222 | /// The template can either be a relative or absolute path, which determines where captures 223 | /// will be saved and how they will be named. Relative paths will be saved relative to the 224 | /// process' current working directory. 225 | /// 226 | /// By default, this will be in a folder controlled by the UI - initially the system temporary 227 | /// directory, and the filename is the executable's filename. 228 | /// 229 | /// # Examples 230 | /// 231 | /// ``` 232 | /// # use renderdoc::{Error, RenderDoc, V100}; 233 | /// # fn main() -> Result<(), Error> { 234 | /// let renderdoc: RenderDoc = RenderDoc::new()?; 235 | /// println!("{:?}", renderdoc.get_log_file_path_template()); // e.g. `my_captures/example` 236 | /// # Ok(()) 237 | /// # } 238 | /// ``` 239 | pub fn get_log_file_path_template(&self) -> &Path { 240 | unsafe { 241 | let raw = ((*self.0).__bindgen_anon_3.GetLogFilePathTemplate.unwrap())(); 242 | CStr::from_ptr(raw).to_str().map(Path::new).unwrap() 243 | } 244 | } 245 | 246 | /// Sets the path template where new capture files should be stored. 247 | /// 248 | /// The template can either be a relative or absolute path, which determines where captures 249 | /// will be saved and how they will be named. Relative paths will be saved relative to the 250 | /// process' current working directory. 251 | /// 252 | /// The default template is in a folder controlled by the UI - initially the system temporary 253 | /// directory, and the filename is the executable's filename. 254 | /// 255 | /// # Examples 256 | /// 257 | /// ```rust,no_run 258 | /// # use renderdoc::{Error, RenderDoc, V100}; 259 | /// # fn main() -> Result<(), Error> { 260 | /// let mut renderdoc: RenderDoc = RenderDoc::new()?; 261 | /// renderdoc.set_log_file_path_template("my_captures/example"); 262 | /// 263 | /// renderdoc.trigger_capture(); // Saved as `my_captures/example_frame123.rdc` 264 | /// renderdoc.trigger_capture(); // Saved as `my_captures/example_frame456.rdc` 265 | /// # Ok(()) 266 | /// # } 267 | /// ``` 268 | pub fn set_log_file_path_template>(&mut self, path_template: P) { 269 | unsafe { 270 | let utf8 = path_template.into().into_os_string().into_string().ok(); 271 | let path = utf8.and_then(|s| CString::new(s).ok()).unwrap(); 272 | ((*self.0).__bindgen_anon_2.SetLogFilePathTemplate.unwrap())(path.as_ptr()); 273 | } 274 | } 275 | 276 | /// Returns the number of frame captures that have been made. 277 | /// 278 | /// # Examples 279 | /// 280 | /// ``` 281 | /// # use renderdoc::{Error, RenderDoc, V100}; 282 | /// # fn main() -> Result<(), Error> { 283 | /// let renderdoc: RenderDoc = RenderDoc::new()?; 284 | /// assert_eq!(renderdoc.get_num_captures(), 0); 285 | /// # Ok(()) 286 | /// # } 287 | /// ``` 288 | pub fn get_num_captures(&self) -> u32 { 289 | unsafe { ((*self.0).GetNumCaptures.unwrap())() } 290 | } 291 | 292 | /// Retrieves the path and capture time of a capture file indexed by the number `index`. 293 | /// 294 | /// Returns `Some` if the index was within `0..get_num_captures()`, otherwise returns `None`. 295 | /// 296 | /// # Examples 297 | /// 298 | /// ```rust,no_run 299 | /// # use renderdoc::{Error, RenderDoc, V100}; 300 | /// # fn main() -> Result<(), Error> { 301 | /// let mut renderdoc: RenderDoc = RenderDoc::new()?; 302 | /// 303 | /// // Capture a frame. 304 | /// renderdoc.trigger_capture(); 305 | /// 306 | /// // Get information about the previous capture. 307 | /// let (file_path, capture_time) = renderdoc.get_capture(0).unwrap(); 308 | /// # Ok(()) 309 | /// # } 310 | /// ``` 311 | pub fn get_capture(&self, index: u32) -> Option<(PathBuf, SystemTime)> { 312 | let mut len = 0; 313 | if unsafe { 314 | (*self.0).GetCapture.unwrap()(index, ptr::null_mut(), &mut len, ptr::null_mut()) 315 | } == 0 316 | { 317 | return None; 318 | }; 319 | 320 | let mut path = Vec::with_capacity(len as usize); 321 | let mut time = 0u64; 322 | 323 | unsafe { 324 | if ((*self.0).GetCapture.unwrap())(index, path.as_mut_ptr(), &mut len, &mut time) == 1 { 325 | let capture_time = time::UNIX_EPOCH + Duration::from_secs(time); 326 | let path = CStr::from_ptr(path.as_ptr()).to_str().unwrap(); 327 | 328 | Some((path.into(), capture_time)) 329 | } else { 330 | None 331 | } 332 | } 333 | } 334 | 335 | /// Captures the next frame from the currently active window and API device. 336 | /// 337 | /// Data is saved to a capture file at the location specified by 338 | /// `set_log_file_path_template()`. 339 | /// 340 | /// ```rust,no_run 341 | /// # use renderdoc::{Error, RenderDoc, V100}; 342 | /// # fn main() -> Result<(), Error> { 343 | /// let mut renderdoc: RenderDoc = RenderDoc::new()?; 344 | /// 345 | /// // Capture the current frame and save to a file. 346 | /// renderdoc.trigger_capture(); 347 | /// # Ok(()) 348 | /// # } 349 | /// ``` 350 | pub fn trigger_capture(&mut self) { 351 | unsafe { 352 | ((*self.0).TriggerCapture.unwrap())(); 353 | } 354 | } 355 | 356 | /// Returns whether the RenderDoc UI is connected to this application. 357 | /// 358 | /// # Examples 359 | /// 360 | /// ```rust 361 | /// # use renderdoc::{Error, RenderDoc, V100}; 362 | /// # fn main() -> Result<(), Error> { 363 | /// let renderdoc: RenderDoc = RenderDoc::new()?; 364 | /// assert!(!renderdoc.is_remote_access_connected()); 365 | /// # Ok(()) 366 | /// # } 367 | /// ``` 368 | pub fn is_remote_access_connected(&self) -> bool { 369 | unsafe { ((*self.0).__bindgen_anon_4.IsRemoteAccessConnected.unwrap())() == 1 } 370 | } 371 | 372 | /// Launches the replay UI associated with the RenderDoc library injected into the running 373 | /// application. 374 | /// 375 | /// If `connect_immediately` is `true`, the replay window will automatically connect to this 376 | /// application once opened, ready to capture frames right away. Optional command-line 377 | /// arguments to the RenderDoc replay UI can be specified via the `extra_opts` parameter. 378 | /// 379 | /// Returns the PID of the RenderDoc replay process on success. 380 | /// 381 | /// # Examples 382 | /// 383 | /// ```rust,no_run 384 | /// # use renderdoc::{Error, RenderDoc, V100}; 385 | /// # fn main() -> Result<(), Error> { 386 | /// let renderdoc: RenderDoc = RenderDoc::new()?; 387 | /// let pid = renderdoc.launch_replay_ui(true, None)?; 388 | /// # Ok(()) 389 | /// # } 390 | /// ``` 391 | pub fn launch_replay_ui<'a, O>( 392 | &self, 393 | connect_immediately: bool, 394 | extra_opts: O, 395 | ) -> Result 396 | where 397 | O: Into>, 398 | { 399 | let should_connect = connect_immediately as u32; 400 | let utf8 = extra_opts.into().and_then(|s| CString::new(s).ok()); 401 | let extra_opts = utf8.as_ref().map(|s| s.as_ptr()).unwrap_or_else(ptr::null); 402 | 403 | unsafe { 404 | match ((*self.0).LaunchReplayUI.unwrap())(should_connect, extra_opts) { 405 | 0 => Err(Error::launch_replay_ui()), 406 | pid => Ok(pid), 407 | } 408 | } 409 | } 410 | 411 | /// Explicitly set which window is considered "active" by RenderDoc. 412 | /// 413 | /// The active window is the one that will be captured when the keybinding to trigger a capture 414 | /// is pressed by the user, as well as when `trigger_capture()` is called. 415 | /// 416 | /// Both `dev` and `win` must be valid handles. 417 | pub fn set_active_window(&mut self, dev: D, win: WindowHandle) 418 | where 419 | D: Into, 420 | { 421 | unsafe { 422 | let DevicePointer(dev) = dev.into(); 423 | ((*self.0).SetActiveWindow.unwrap())(dev as *mut _, win as *mut _); 424 | } 425 | } 426 | 427 | /// Begins a frame capture for the specified device/window combination. 428 | /// 429 | /// If either or both `dev` and `win` are set to `std::ptr::null()`, then RenderDoc will 430 | /// perform a wildcard match. 431 | /// 432 | /// For example, you can specify `null(), null()` for the device to capture on if you have only 433 | /// one device and only one or zero windows, and RenderDoc will capture from that device. 434 | /// 435 | /// This function must be paired with a matching `end_frame_capture()` to succeed. 436 | /// 437 | /// ```rust,no_run 438 | /// # use renderdoc::{Error, RenderDoc, V100}; 439 | /// # fn main() -> Result<(), Error> { 440 | /// let mut renderdoc: RenderDoc = RenderDoc::new()?; 441 | /// renderdoc.start_frame_capture(std::ptr::null(), std::ptr::null()); 442 | /// 443 | /// // Capturing window from here onward... 444 | /// # Ok(()) 445 | /// # } 446 | /// ``` 447 | pub fn start_frame_capture(&mut self, dev: D, win: WindowHandle) 448 | where 449 | D: Into, 450 | { 451 | unsafe { 452 | let DevicePointer(dev) = dev.into(); 453 | ((*self.0).StartFrameCapture.unwrap())(dev as *mut _, win as *mut _); 454 | } 455 | } 456 | 457 | /// Returns whether or not a frame capture is currently ongoing anywhere. 458 | /// 459 | /// # Examples 460 | /// 461 | /// ```rust,no_run 462 | /// # use renderdoc::{Error, RenderDoc, V100}; 463 | /// # fn main() -> Result<(), Error> { 464 | /// let renderdoc: RenderDoc = RenderDoc::new()?; 465 | /// if renderdoc.is_frame_capturing() { 466 | /// println!("Frames are being captured."); 467 | /// } else { 468 | /// println!("No frame capture is occurring."); 469 | /// } 470 | /// # Ok(()) 471 | /// # } 472 | /// ``` 473 | pub fn is_frame_capturing(&self) -> bool { 474 | unsafe { ((*self.0).IsFrameCapturing.unwrap())() == 1 } 475 | } 476 | 477 | /// Ends a frame capture for the specified device/window combination, saving results to disk. 478 | /// 479 | /// If either or both `dev` and `win` are set to `std::ptr::null()`, then RenderDoc will 480 | /// perform a wildcard match. 481 | /// 482 | /// For example, you can specify `null(), null()` for the device to capture on if you have only 483 | /// one device and only one or zero windows, and RenderDoc will capture from that device. 484 | /// 485 | /// This function must be paired with a matching `start_frame_capture()` to complete. 486 | /// 487 | /// ```rust,no_run 488 | /// # use renderdoc::{Error, RenderDoc, V100}; 489 | /// # fn main() -> Result<(), Error> { 490 | /// let mut renderdoc: RenderDoc = RenderDoc::new()?; 491 | /// 492 | /// renderdoc.start_frame_capture(std::ptr::null(), std::ptr::null()); 493 | /// // Do some rendering here... 494 | /// renderdoc.end_frame_capture(std::ptr::null(), std::ptr::null()); 495 | /// # Ok(()) 496 | /// # } 497 | /// ``` 498 | pub fn end_frame_capture(&mut self, dev: D, win: WindowHandle) 499 | where 500 | D: Into, 501 | { 502 | unsafe { 503 | let DevicePointer(dev) = dev.into(); 504 | ((*self.0).EndFrameCapture.unwrap())(dev as *mut _, win as *mut _); 505 | } 506 | } 507 | } 508 | 509 | impl RenderDoc { 510 | /// Captures the next _n_ frames from the currently active window and API device. 511 | /// 512 | /// Data is saved to _n_ separate capture files at the location specified via 513 | /// `set_log_file_path_template()`. 514 | pub fn trigger_multi_frame_capture(&mut self, num_frames: u32) { 515 | unsafe { 516 | ((*self.0).TriggerMultiFrameCapture.unwrap())(num_frames); 517 | } 518 | } 519 | } 520 | 521 | impl RenderDoc { 522 | /// Returns whether the RenderDoc UI is connected to this application. 523 | /// 524 | /// # Examples 525 | /// 526 | /// ```rust 527 | /// # use renderdoc::{Error, RenderDoc, V111}; 528 | /// # fn main() -> Result<(), Error> { 529 | /// let renderdoc: RenderDoc = RenderDoc::new()?; 530 | /// assert!(!renderdoc.is_target_control_connected()); 531 | /// # Ok(()) 532 | /// # } 533 | /// ``` 534 | pub fn is_target_control_connected(&self) -> bool { 535 | unsafe { ((*self.0).__bindgen_anon_4.IsTargetControlConnected.unwrap())() == 1 } 536 | } 537 | 538 | /// Returns whether the RenderDoc UI is connected to this application. 539 | #[deprecated(since = "1.1.1", note = "renamed to `is_target_control_connected`")] 540 | pub fn is_remote_access_connected(&self) -> bool { 541 | let v1: &RenderDoc = self.deref(); 542 | v1.is_remote_access_connected() 543 | } 544 | } 545 | 546 | impl RenderDoc { 547 | /// Returns the path template where new captures will be stored. 548 | /// 549 | /// The template can either be a relative or absolute path, which determines where captures 550 | /// will be saved and how they will be named. Relative paths will be saved relative to the 551 | /// process' current working directory. 552 | /// 553 | /// By default, this will be in a folder controlled by the UI - initially the system temporary 554 | /// directory, and the filename is the executable's filename. 555 | /// 556 | /// # Examples 557 | /// 558 | /// ``` 559 | /// # use renderdoc::{Error, RenderDoc, V112}; 560 | /// # fn main() -> Result<(), Error> { 561 | /// let renderdoc: RenderDoc = RenderDoc::new()?; 562 | /// println!("{:?}", renderdoc.get_capture_file_path_template()); // e.g. `my_captures/example` 563 | /// # Ok(()) 564 | /// # } 565 | /// ``` 566 | pub fn get_capture_file_path_template(&self) -> &Path { 567 | unsafe { 568 | let raw = ((*self.0) 569 | .__bindgen_anon_3 570 | .GetCaptureFilePathTemplate 571 | .unwrap())(); 572 | CStr::from_ptr(raw).to_str().map(Path::new).unwrap() 573 | } 574 | } 575 | 576 | /// Sets the path template where new capture files should be stored. 577 | /// 578 | /// The template can either be a relative or absolute path, which determines where captures 579 | /// will be saved and how they will be named. Relative paths will be saved relative to the 580 | /// process' current working directory. 581 | /// 582 | /// The default template is in a folder controlled by the UI - initially the system temporary 583 | /// directory, and the filename is the executable's filename. 584 | /// 585 | /// # Examples 586 | /// 587 | /// ```rust,no_run 588 | /// # use renderdoc::{Error, RenderDoc, V112}; 589 | /// # fn main() -> Result<(), Error> { 590 | /// let mut renderdoc: RenderDoc = RenderDoc::new()?; 591 | /// renderdoc.set_capture_file_path_template("my_captures/example"); 592 | /// 593 | /// renderdoc.trigger_capture(); // Saved as `my_captures/example_frame123.rdc` 594 | /// renderdoc.trigger_capture(); // Saved as `my_captures/example_frame456.rdc` 595 | /// # Ok(()) 596 | /// # } 597 | /// ``` 598 | pub fn set_capture_file_path_template>(&mut self, path_template: P) { 599 | let utf8 = path_template.into().into_os_string().into_string().ok(); 600 | let cstr = utf8.and_then(|s| CString::new(s).ok()).unwrap(); 601 | unsafe { 602 | ((*self.0) 603 | .__bindgen_anon_2 604 | .SetCaptureFilePathTemplate 605 | .unwrap())(cstr.as_ptr()); 606 | } 607 | } 608 | 609 | /// Returns the path template where new captures will be stored. 610 | #[deprecated(since = "1.1.2", note = "renamed to `get_capture_file_path_template`")] 611 | pub fn get_log_file_path_template(&self) -> &Path { 612 | let v1: &RenderDoc = self.deref(); 613 | v1.get_log_file_path_template() 614 | } 615 | 616 | /// Sets the path template where new capture files should be stored. 617 | #[deprecated(since = "1.1.2", note = "renamed to `set_capture_file_path_template`")] 618 | pub fn set_log_file_path_template>(&mut self, path_template: P) { 619 | let v1: &mut RenderDoc = self.deref_mut(); 620 | v1.set_log_file_path_template(path_template) 621 | } 622 | } 623 | 624 | impl RenderDoc { 625 | /// Adds or sets an arbitrary comments field to an existing capture on disk, which will then be 626 | /// displayed in the UI to anyone opening the capture file. 627 | /// 628 | /// If the `path` argument is `None`, the most recent previous capture file is used. 629 | pub fn set_capture_file_comments<'a, P, C>(&mut self, path: P, comments: C) 630 | where 631 | P: Into>, 632 | C: Into, 633 | { 634 | let utf8 = path.into().and_then(|s| CString::new(s).ok()); 635 | let path = utf8.as_ref().map(|s| s.as_ptr()).unwrap_or_else(ptr::null); 636 | let comments = CString::new(comments.into()).unwrap(); 637 | 638 | unsafe { 639 | ((*self.0).SetCaptureFileComments.unwrap())(path, comments.as_ptr()); 640 | } 641 | } 642 | } 643 | 644 | impl RenderDoc { 645 | /// Ends capturing immediately and discards any data without saving to disk. 646 | /// 647 | /// Returns `true` if the capture was discarded, or `false` if no capture is in progress. 648 | pub fn discard_frame_capture(&mut self, dev: D, win: WindowHandle) -> bool 649 | where 650 | D: Into, 651 | { 652 | let DevicePointer(dev) = dev.into(); 653 | unsafe { ((*self.0).DiscardFrameCapture.unwrap())(dev as *mut _, win as *mut _) == 1 } 654 | } 655 | } 656 | 657 | impl Debug for RenderDoc { 658 | fn fmt(&self, fmt: &mut Formatter) -> FmtResult { 659 | fmt.debug_tuple(stringify!(RenderDoc)) 660 | .field(&self.0) 661 | .field(&V::VERSION) 662 | .finish() 663 | } 664 | } 665 | 666 | unsafe impl Send for RenderDoc {} 667 | 668 | /// Generates `From` implementations that permit downgrading of API versions. 669 | /// 670 | /// Unlike the `downgrade()` method, these `From` implementations let any version to downgrade to 671 | /// any other older backwards-compatible API version in a clean way. 672 | /// 673 | /// This function takes a list of API versions sorted in descending order and recursively generates 674 | /// `From` implementations for them. For instance, given the following three API versions 675 | /// `[V200, V110, V100]`, these trait implementations will be generated: 676 | /// 677 | /// ```rust,ignore 678 | /// // V200 -> V110, V100 679 | /// 680 | /// impl From<#name> for #name 681 | /// where 682 | /// Self: Sized, 683 | /// { 684 | /// fn from(newer: #name) -> Self { 685 | /// // ... 686 | /// } 687 | /// } 688 | /// 689 | /// impl From<#name> for #name 690 | /// where 691 | /// Self: Sized, 692 | /// { 693 | /// fn from(newer: #name) -> Self { 694 | /// // ... 695 | /// } 696 | /// } 697 | /// 698 | /// // V110 -> V100 699 | /// 700 | /// impl From<#name> for #name 701 | /// where 702 | /// Self: Sized, 703 | /// { 704 | /// fn from(newer: #name) -> Self { 705 | /// // ... 706 | /// } 707 | /// } 708 | /// 709 | /// // V100 -> () 710 | /// ``` 711 | macro_rules! impl_from_versions { 712 | ($base_version:ident) => {}; 713 | 714 | ($newer:ident, $($older:ident),+) => { 715 | $( 716 | impl From> for RenderDoc<$older> 717 | where 718 | Self: Sized, 719 | { 720 | fn from(newer: RenderDoc<$newer>) -> Self { 721 | let RenderDoc(entry, _) = newer; 722 | RenderDoc(entry, PhantomData) 723 | } 724 | } 725 | )+ 726 | 727 | impl_from_versions!($($older),+); 728 | }; 729 | } 730 | 731 | impl_from_versions!(V141, V140, V130, V120, V112, V111, V110, V100); 732 | -------------------------------------------------------------------------------- /src/settings.rs: -------------------------------------------------------------------------------- 1 | //! Types for configuring the behavior of RenderDoc frame captures. 2 | 3 | use std::u32; 4 | 5 | use bitflags::bitflags; 6 | 7 | /// RenderDoc capture options. 8 | #[repr(u32)] 9 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 10 | pub enum CaptureOption { 11 | /// Let the application enable vertical synchronization. 12 | AllowVSync = renderdoc_sys::eRENDERDOC_Option_AllowVSync, 13 | /// Let the application enter fullscreen mode. 14 | AllowFullscreen = renderdoc_sys::eRENDERDOC_Option_AllowFullscreen, 15 | /// Record API debugging events and messages. 16 | /// 17 | /// This option also goes by the deprecated name of `DebugDeviceMode`. 18 | ApiValidation = renderdoc_sys::eRENDERDOC_Option_APIValidation, 19 | /// Capture CPU callstacks for API events. 20 | CaptureCallstacks = renderdoc_sys::eRENDERDOC_Option_CaptureCallstacks, 21 | /// When capturing CPU callstacks, only capture them from drawcalls. 22 | /// 23 | /// This option does nothing without the above option being enabled. 24 | CaptureCallstacksOnlyDraws = renderdoc_sys::eRENDERDOC_Option_CaptureCallstacksOnlyDraws, 25 | /// Specify a delay, measured in seconds, to wait for a debugger to attach to the application 26 | /// after being injected. 27 | DelayForDebugger = renderdoc_sys::eRENDERDOC_Option_DelayForDebugger, 28 | /// Verify any writes to mapped buffers by checking the memory after the bounds of the 29 | /// returned pointer to detect any modification. 30 | VerifyMapWrites = renderdoc_sys::eRENDERDOC_Option_VerifyMapWrites, 31 | /// Hooks any system API calls that create child processes and injects RenderDoc into them 32 | /// recursively with the same options. 33 | HookIntoChildren = renderdoc_sys::eRENDERDOC_Option_HookIntoChildren, 34 | /// Reference all resources available at the time of capture. 35 | /// 36 | /// By default, RenderDoc only includes resources in the final capture file necessary for that 37 | /// frame. This option allows you to override that behavior. 38 | RefAllResources = renderdoc_sys::eRENDERDOC_Option_RefAllResources, 39 | /// Save the initial state for all resources, regardless of usage. 40 | /// 41 | /// By default, RenderDoc skips saving initial states for resources where the previous 42 | /// contents don't appear to be used (assuming that writes before reads indicate the previous 43 | /// contents aren't used). 44 | SaveAllInitials = renderdoc_sys::eRENDERDOC_Option_SaveAllInitials, 45 | /// Capture all command lists generated from the start of the application. 46 | /// 47 | /// In APIs that allow for recording of command lists to be replayed later, RenderDoc may 48 | /// choose to not capture command lists before a frame capture is triggered to reduce 49 | /// overhead. This means any command lists that are recorded one and replayed many times will 50 | /// not be available, potentially causing a failure to capture. 51 | /// 52 | /// Note that this is only true for APIs where multithreading is difficult or otherwise 53 | /// discouraged. Newer APIs, e.g. Vulkan and D3D12, will ignore this option and always capture 54 | /// all command lists since they are heavily oriented around them and the associated overhead 55 | /// is mostly reduced due to superior API design. 56 | CaptureAllCmdLists = renderdoc_sys::eRENDERDOC_Option_CaptureAllCmdLists, 57 | /// Mute API debug output when `CaptureOption::ApiValidation` is enabled. 58 | DebugOutputMute = renderdoc_sys::eRENDERDOC_Option_DebugOutputMute, 59 | /// Allow all vendor extensions to be used, even when they may be incompatible with RenderDoc 60 | /// and could potentially cause corrupted replays or crashes. 61 | AllowUnsupportedVendorExtensions = 62 | renderdoc_sys::eRENDERDOC_Option_AllowUnsupportedVendorExtensions, 63 | } 64 | 65 | /// User input key codes. 66 | #[allow(missing_docs)] 67 | #[repr(u32)] 68 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 69 | pub enum InputButton { 70 | /// The '0' key over the letters. 71 | Key0 = renderdoc_sys::eRENDERDOC_Key_0, 72 | /// The '1' key over the letters. 73 | Key1 = renderdoc_sys::eRENDERDOC_Key_1, 74 | /// The '2' key over the letters. 75 | Key2 = renderdoc_sys::eRENDERDOC_Key_2, 76 | /// The '3' key over the letters. 77 | Key3 = renderdoc_sys::eRENDERDOC_Key_3, 78 | /// The '4' key over the letters. 79 | Key4 = renderdoc_sys::eRENDERDOC_Key_4, 80 | /// The '5' key over the letters. 81 | Key5 = renderdoc_sys::eRENDERDOC_Key_5, 82 | /// The '6' key over the letters. 83 | Key6 = renderdoc_sys::eRENDERDOC_Key_6, 84 | /// The '7' key over the letters. 85 | Key7 = renderdoc_sys::eRENDERDOC_Key_7, 86 | /// The '8' key over the letters. 87 | Key8 = renderdoc_sys::eRENDERDOC_Key_8, 88 | /// The '9' key over the letters. 89 | Key9 = renderdoc_sys::eRENDERDOC_Key_9, 90 | 91 | A = renderdoc_sys::eRENDERDOC_Key_A, 92 | B = renderdoc_sys::eRENDERDOC_Key_B, 93 | C = renderdoc_sys::eRENDERDOC_Key_C, 94 | D = renderdoc_sys::eRENDERDOC_Key_D, 95 | E = renderdoc_sys::eRENDERDOC_Key_E, 96 | F = renderdoc_sys::eRENDERDOC_Key_F, 97 | G = renderdoc_sys::eRENDERDOC_Key_G, 98 | H = renderdoc_sys::eRENDERDOC_Key_H, 99 | I = renderdoc_sys::eRENDERDOC_Key_I, 100 | J = renderdoc_sys::eRENDERDOC_Key_J, 101 | K = renderdoc_sys::eRENDERDOC_Key_K, 102 | L = renderdoc_sys::eRENDERDOC_Key_L, 103 | M = renderdoc_sys::eRENDERDOC_Key_M, 104 | N = renderdoc_sys::eRENDERDOC_Key_N, 105 | O = renderdoc_sys::eRENDERDOC_Key_O, 106 | P = renderdoc_sys::eRENDERDOC_Key_P, 107 | Q = renderdoc_sys::eRENDERDOC_Key_Q, 108 | R = renderdoc_sys::eRENDERDOC_Key_R, 109 | S = renderdoc_sys::eRENDERDOC_Key_S, 110 | T = renderdoc_sys::eRENDERDOC_Key_T, 111 | U = renderdoc_sys::eRENDERDOC_Key_U, 112 | V = renderdoc_sys::eRENDERDOC_Key_V, 113 | W = renderdoc_sys::eRENDERDOC_Key_W, 114 | X = renderdoc_sys::eRENDERDOC_Key_X, 115 | Y = renderdoc_sys::eRENDERDOC_Key_Y, 116 | Z = renderdoc_sys::eRENDERDOC_Key_Z, 117 | 118 | /// Leave the rest of the ASCII range free, in case the RenderDoc developers decide to use it 119 | /// later. 120 | NonPrintable = renderdoc_sys::eRENDERDOC_Key_NonPrintable, 121 | 122 | /// Division key on the numpad. 123 | Divide = renderdoc_sys::eRENDERDOC_Key_Divide, 124 | /// Multiplication key on the numpad. 125 | Multiply = renderdoc_sys::eRENDERDOC_Key_Multiply, 126 | /// Subtraction key on the numpad. 127 | Subtract = renderdoc_sys::eRENDERDOC_Key_Subtract, 128 | /// Addition key on the numpad. 129 | Plus = renderdoc_sys::eRENDERDOC_Key_Plus, 130 | 131 | F1 = renderdoc_sys::eRENDERDOC_Key_F1, 132 | F2 = renderdoc_sys::eRENDERDOC_Key_F2, 133 | F3 = renderdoc_sys::eRENDERDOC_Key_F3, 134 | F4 = renderdoc_sys::eRENDERDOC_Key_F4, 135 | F5 = renderdoc_sys::eRENDERDOC_Key_F5, 136 | F6 = renderdoc_sys::eRENDERDOC_Key_F6, 137 | F7 = renderdoc_sys::eRENDERDOC_Key_F7, 138 | F8 = renderdoc_sys::eRENDERDOC_Key_F8, 139 | F9 = renderdoc_sys::eRENDERDOC_Key_F9, 140 | F10 = renderdoc_sys::eRENDERDOC_Key_F10, 141 | F11 = renderdoc_sys::eRENDERDOC_Key_F11, 142 | F12 = renderdoc_sys::eRENDERDOC_Key_F12, 143 | 144 | Home = renderdoc_sys::eRENDERDOC_Key_Home, 145 | End = renderdoc_sys::eRENDERDOC_Key_End, 146 | Insert = renderdoc_sys::eRENDERDOC_Key_Insert, 147 | Delete = renderdoc_sys::eRENDERDOC_Key_Delete, 148 | PageUp = renderdoc_sys::eRENDERDOC_Key_PageUp, 149 | PageDn = renderdoc_sys::eRENDERDOC_Key_PageDn, 150 | 151 | Backspace = renderdoc_sys::eRENDERDOC_Key_Backspace, 152 | Tab = renderdoc_sys::eRENDERDOC_Key_Tab, 153 | PrtScrn = renderdoc_sys::eRENDERDOC_Key_PrtScrn, 154 | Pause = renderdoc_sys::eRENDERDOC_Key_Pause, 155 | 156 | Max = renderdoc_sys::eRENDERDOC_Key_Max, 157 | } 158 | 159 | #[cfg(feature = "winit")] 160 | impl From for InputButton { 161 | fn from(code: winit::event::VirtualKeyCode) -> InputButton { 162 | use winit::event::VirtualKeyCode; 163 | match code { 164 | VirtualKeyCode::Key1 => InputButton::Key1, 165 | VirtualKeyCode::Key2 => InputButton::Key2, 166 | VirtualKeyCode::Key3 => InputButton::Key3, 167 | VirtualKeyCode::Key4 => InputButton::Key4, 168 | VirtualKeyCode::Key5 => InputButton::Key5, 169 | VirtualKeyCode::Key6 => InputButton::Key6, 170 | VirtualKeyCode::Key7 => InputButton::Key7, 171 | VirtualKeyCode::Key8 => InputButton::Key8, 172 | VirtualKeyCode::Key9 => InputButton::Key9, 173 | VirtualKeyCode::Key0 => InputButton::Key0, 174 | VirtualKeyCode::A => InputButton::A, 175 | VirtualKeyCode::B => InputButton::B, 176 | VirtualKeyCode::C => InputButton::C, 177 | VirtualKeyCode::D => InputButton::D, 178 | VirtualKeyCode::E => InputButton::E, 179 | VirtualKeyCode::F => InputButton::F, 180 | VirtualKeyCode::G => InputButton::G, 181 | VirtualKeyCode::H => InputButton::H, 182 | VirtualKeyCode::I => InputButton::I, 183 | VirtualKeyCode::J => InputButton::J, 184 | VirtualKeyCode::K => InputButton::K, 185 | VirtualKeyCode::L => InputButton::L, 186 | VirtualKeyCode::M => InputButton::M, 187 | VirtualKeyCode::N => InputButton::N, 188 | VirtualKeyCode::O => InputButton::O, 189 | VirtualKeyCode::P => InputButton::P, 190 | VirtualKeyCode::Q => InputButton::Q, 191 | VirtualKeyCode::R => InputButton::R, 192 | VirtualKeyCode::S => InputButton::S, 193 | VirtualKeyCode::T => InputButton::T, 194 | VirtualKeyCode::U => InputButton::U, 195 | VirtualKeyCode::V => InputButton::V, 196 | VirtualKeyCode::W => InputButton::W, 197 | VirtualKeyCode::X => InputButton::X, 198 | VirtualKeyCode::Y => InputButton::Y, 199 | VirtualKeyCode::Z => InputButton::Z, 200 | VirtualKeyCode::NumpadDivide => InputButton::Divide, 201 | VirtualKeyCode::NumpadMultiply => InputButton::Multiply, 202 | VirtualKeyCode::NumpadSubtract => InputButton::Subtract, 203 | VirtualKeyCode::NumpadAdd => InputButton::Plus, 204 | VirtualKeyCode::F1 => InputButton::F1, 205 | VirtualKeyCode::F2 => InputButton::F2, 206 | VirtualKeyCode::F3 => InputButton::F3, 207 | VirtualKeyCode::F4 => InputButton::F4, 208 | VirtualKeyCode::F5 => InputButton::F5, 209 | VirtualKeyCode::F6 => InputButton::F6, 210 | VirtualKeyCode::F7 => InputButton::F7, 211 | VirtualKeyCode::F8 => InputButton::F8, 212 | VirtualKeyCode::F9 => InputButton::F9, 213 | VirtualKeyCode::F10 => InputButton::F10, 214 | VirtualKeyCode::F11 => InputButton::F11, 215 | VirtualKeyCode::F12 => InputButton::F12, 216 | VirtualKeyCode::Home => InputButton::Home, 217 | VirtualKeyCode::End => InputButton::End, 218 | VirtualKeyCode::Insert => InputButton::Insert, 219 | VirtualKeyCode::Delete => InputButton::Delete, 220 | VirtualKeyCode::PageUp => InputButton::PageUp, 221 | VirtualKeyCode::PageDown => InputButton::PageDn, 222 | VirtualKeyCode::Back => InputButton::Backspace, 223 | VirtualKeyCode::Tab => InputButton::Tab, 224 | VirtualKeyCode::Snapshot => InputButton::PrtScrn, 225 | VirtualKeyCode::Pause => InputButton::Pause, 226 | _ => InputButton::Max, 227 | } 228 | } 229 | } 230 | 231 | bitflags! { 232 | /// Bit flags for customizing the RenderDoc overlay. 233 | pub struct OverlayBits: u32 { 234 | /// Controls whether the overlay is enabled or disabled globally. 235 | const ENABLED = renderdoc_sys::eRENDERDOC_Overlay_Enabled; 236 | /// Shows the average, minimum, and maximum sampled frame rate. 237 | const FRAME_RATE = renderdoc_sys::eRENDERDOC_Overlay_FrameRate; 238 | /// Shows the current frame number. 239 | const FRAME_NUMBER = renderdoc_sys::eRENDERDOC_Overlay_FrameNumber; 240 | /// Shows a list of recent captures, out of the total captures made. 241 | const CAPTURE_LIST = renderdoc_sys::eRENDERDOC_Overlay_CaptureList; 242 | /// Sets the default configuration for the overlay. 243 | const DEFAULT = renderdoc_sys::eRENDERDOC_Overlay_Default; 244 | /// Enables all overlay configuration bits. 245 | const ALL = u32::MAX; 246 | /// Disables all overlay configuration bits. 247 | const NONE = u32::MIN; 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /src/version.rs: -------------------------------------------------------------------------------- 1 | //! Entry points for the RenderDoc API. 2 | 3 | use std::ffi::c_void; 4 | use std::ptr; 5 | 6 | use libloading::{Library, Symbol}; 7 | use once_cell::sync::OnceCell; 8 | use renderdoc_sys::RENDERDOC_API_1_4_1; 9 | 10 | use crate::error::Error; 11 | 12 | /// Entry point for the RenderDoc API. 13 | pub type Entry = RENDERDOC_API_1_4_1; 14 | 15 | /// Available versions of the RenderDoc API. 16 | #[repr(u32)] 17 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 18 | pub enum VersionCode { 19 | /// Version 1.0.0. 20 | V100 = 10000, 21 | /// Version 1.0.1. 22 | V101 = 10001, 23 | /// Version 1.0.2. 24 | V102 = 10002, 25 | /// Version 1.1.0. 26 | V110 = 10100, 27 | /// Version 1.1.1. 28 | V111 = 10101, 29 | /// Version 1.1.2. 30 | V112 = 10102, 31 | /// Version 1.2.0. 32 | V120 = 10200, 33 | /// Version 1.3.0. 34 | V130 = 10300, 35 | /// Version 1.4.0. 36 | V140 = 10400, 37 | /// Version 1.4.1. 38 | V141 = 10401, 39 | } 40 | 41 | /// Entry point into the RenderDoc API. 42 | pub trait Version { 43 | /// Minimum compatible version number. 44 | const VERSION: VersionCode; 45 | 46 | /// Initializes a new instance of the RenderDoc API. 47 | /// 48 | /// # Safety 49 | /// 50 | /// This function is not thread-safe and should not be called on multiple threads at once. 51 | fn load() -> Result<*mut Entry, Error> { 52 | static LIBRARY: OnceCell = OnceCell::new(); 53 | 54 | type GetApiFn = unsafe extern "C" fn(ver: u32, out: *mut *mut c_void) -> i32; 55 | 56 | #[cfg(windows)] 57 | let lib_path = "renderdoc.dll"; 58 | #[cfg(all(unix, not(target_os = "android")))] 59 | let lib_path = "librenderdoc.so"; 60 | #[cfg(target_os = "android")] 61 | let lib_path = "libVkLayer_GLES_RenderDoc.so"; 62 | 63 | unsafe { 64 | #[cfg(not(feature = "ci"))] 65 | #[cfg(unix)] 66 | let lib = LIBRARY 67 | .get_or_try_init(|| { 68 | // TODO: Use constant from `libloading`, once added upstream. 69 | const RTLD_NOLOAD: i32 = 0x4; 70 | 71 | let flags = libloading::os::unix::RTLD_NOW | RTLD_NOLOAD; 72 | libloading::os::unix::Library::open(Some(lib_path), flags).map(Into::into) 73 | }) 74 | .map_err(Error::library)?; 75 | 76 | #[cfg(not(feature = "ci"))] 77 | #[cfg(windows)] 78 | let lib = LIBRARY 79 | .get_or_try_init(|| { 80 | libloading::os::windows::Library::open_already_loaded(lib_path).map(Into::into) 81 | }) 82 | .map_err(Error::library)?; 83 | 84 | #[cfg(feature = "ci")] 85 | let lib = LIBRARY 86 | .get_or_try_init(|| Library::new(lib_path)) 87 | .map_err(Error::library)?; 88 | 89 | let get_api: Symbol = 90 | lib.get(b"RENDERDOC_GetAPI\0").map_err(Error::symbol)?; 91 | 92 | let mut obj = ptr::null_mut(); 93 | match get_api(Self::VERSION as u32, &mut obj) { 94 | 1 => Ok(obj as *mut Entry), 95 | _ => Err(Error::no_compatible_api()), 96 | } 97 | } 98 | } 99 | } 100 | 101 | /// Trait for statically enforcing backwards compatibility. 102 | pub trait HasPrevious: Version { 103 | /// API version which immediately precedes this one. 104 | type Previous: Version; 105 | } 106 | 107 | /// Requests a minimum version number of 1.0.0. 108 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 109 | pub enum V100 {} 110 | 111 | impl Version for V100 { 112 | const VERSION: VersionCode = VersionCode::V100; 113 | } 114 | 115 | /// Requests a minimum version number of 1.1.0. 116 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 117 | pub enum V110 {} 118 | 119 | impl Version for V110 { 120 | const VERSION: VersionCode = VersionCode::V110; 121 | } 122 | 123 | impl HasPrevious for V110 { 124 | type Previous = V100; 125 | } 126 | 127 | /// Requests a minimum version number of 1.1.1. 128 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 129 | pub enum V111 {} 130 | 131 | impl Version for V111 { 132 | const VERSION: VersionCode = VersionCode::V111; 133 | } 134 | 135 | impl HasPrevious for V111 { 136 | type Previous = V110; 137 | } 138 | 139 | /// Requests a minimum version number of 1.1.2. 140 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 141 | pub enum V112 {} 142 | 143 | impl Version for V112 { 144 | const VERSION: VersionCode = VersionCode::V112; 145 | } 146 | 147 | impl HasPrevious for V112 { 148 | type Previous = V111; 149 | } 150 | 151 | /// Requests a minimum version number of 1.2.0. 152 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 153 | pub enum V120 {} 154 | 155 | impl Version for V120 { 156 | const VERSION: VersionCode = VersionCode::V120; 157 | } 158 | 159 | impl HasPrevious for V120 { 160 | type Previous = V112; 161 | } 162 | 163 | /// Requests a minimum version number of 1.3.0. 164 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 165 | pub enum V130 {} 166 | 167 | impl Version for V130 { 168 | const VERSION: VersionCode = VersionCode::V130; 169 | } 170 | 171 | impl HasPrevious for V130 { 172 | type Previous = V120; 173 | } 174 | 175 | /// Requests a minimum version number of 1.4.0. 176 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 177 | pub enum V140 {} 178 | 179 | impl Version for V140 { 180 | const VERSION: VersionCode = VersionCode::V140; 181 | } 182 | 183 | impl HasPrevious for V140 { 184 | type Previous = V130; 185 | } 186 | 187 | /// Requests a minimum version number of 1.4.1. 188 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 189 | pub enum V141 {} 190 | 191 | impl Version for V141 { 192 | const VERSION: VersionCode = VersionCode::V141; 193 | } 194 | 195 | impl HasPrevious for V141 { 196 | type Previous = V140; 197 | } 198 | --------------------------------------------------------------------------------