rt(d3d12): make descriptor heap lockfree

This commit is contained in:
chyyran 2024-02-28 17:55:25 -05:00 committed by Ronny Chan
parent 8a9adebb96
commit 10ad2d927c
4 changed files with 119 additions and 122 deletions

129
Cargo.lock generated
View file

@ -37,9 +37,9 @@ dependencies = [
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.9" version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"getrandom", "getrandom",
@ -157,7 +157,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
] ]
[[package]] [[package]]
@ -324,9 +324,9 @@ checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.15.2" version = "3.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3b1be7772ee4501dba05acbe66bb1e8760f6a6c474a36035631638e4415f130" checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b"
[[package]] [[package]]
name = "bytecount" name = "bytecount"
@ -351,7 +351,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
] ]
[[package]] [[package]]
@ -413,9 +413,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.86" version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730" checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -948,7 +948,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
] ]
[[package]] [[package]]
@ -1015,9 +1015,9 @@ dependencies = [
[[package]] [[package]]
name = "gif" name = "gif"
version = "0.12.0" version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
dependencies = [ dependencies = [
"color_quant", "color_quant",
"weezl", "weezl",
@ -1182,9 +1182,9 @@ dependencies = [
[[package]] [[package]]
name = "half" name = "half"
version = "2.3.1" version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crunchy", "crunchy",
@ -1214,7 +1214,7 @@ version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [ dependencies = [
"ahash 0.8.9", "ahash 0.8.10",
] ]
[[package]] [[package]]
@ -1223,7 +1223,7 @@ version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [ dependencies = [
"ahash 0.8.9", "ahash 0.8.10",
"allocator-api2", "allocator-api2",
] ]
@ -1259,9 +1259,9 @@ dependencies = [
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.3.6" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]] [[package]]
name = "hexf-parse" name = "hexf-parse"
@ -1298,9 +1298,9 @@ dependencies = [
[[package]] [[package]]
name = "image" name = "image"
version = "0.24.8" version = "0.24.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"byteorder", "byteorder",
@ -1340,7 +1340,7 @@ version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
dependencies = [ dependencies = [
"hermit-abi 0.3.6", "hermit-abi 0.3.9",
"libc", "libc",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@ -1639,7 +1639,6 @@ dependencies = [
"librashader-reflect", "librashader-reflect",
"librashader-runtime", "librashader-runtime",
"mach-siegbert-vogt-dxcsa", "mach-siegbert-vogt-dxcsa",
"parking_lot",
"rayon", "rayon",
"thiserror", "thiserror",
"widestring", "widestring",
@ -1787,9 +1786,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.20" version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]] [[package]]
name = "mach-siegbert-vogt-dxcsa" name = "mach-siegbert-vogt-dxcsa"
@ -2027,7 +2026,7 @@ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
] ]
[[package]] [[package]]
@ -2218,7 +2217,7 @@ dependencies = [
"pest_meta", "pest_meta",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
] ]
[[package]] [[package]]
@ -2460,9 +2459,9 @@ dependencies = [
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.8.1" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd"
dependencies = [ dependencies = [
"either", "either",
"rayon-core", "rayon-core",
@ -2655,7 +2654,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
] ]
[[package]] [[package]]
@ -2822,9 +2821,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.50" version = "2.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2839,9 +2838,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.10.0" version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
@ -2881,7 +2880,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
] ]
[[package]] [[package]]
@ -3074,7 +3073,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -3108,7 +3107,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -3404,7 +3403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [ dependencies = [
"windows-core", "windows-core",
"windows-targets 0.52.0", "windows-targets 0.52.4",
] ]
[[package]] [[package]]
@ -3413,7 +3412,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [ dependencies = [
"windows-targets 0.52.0", "windows-targets 0.52.4",
] ]
[[package]] [[package]]
@ -3440,7 +3439,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets 0.52.0", "windows-targets 0.52.4",
] ]
[[package]] [[package]]
@ -3475,17 +3474,17 @@ dependencies = [
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.0" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm 0.52.0", "windows_aarch64_gnullvm 0.52.4",
"windows_aarch64_msvc 0.52.0", "windows_aarch64_msvc 0.52.4",
"windows_i686_gnu 0.52.0", "windows_i686_gnu 0.52.4",
"windows_i686_msvc 0.52.0", "windows_i686_msvc 0.52.4",
"windows_x86_64_gnu 0.52.0", "windows_x86_64_gnu 0.52.4",
"windows_x86_64_gnullvm 0.52.0", "windows_x86_64_gnullvm 0.52.4",
"windows_x86_64_msvc 0.52.0", "windows_x86_64_msvc 0.52.4",
] ]
[[package]] [[package]]
@ -3502,9 +3501,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.0" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
@ -3520,9 +3519,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.0" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
@ -3538,9 +3537,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.0" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
@ -3556,9 +3555,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.0" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
@ -3574,9 +3573,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.0" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
@ -3592,9 +3591,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.0" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
@ -3610,17 +3609,17 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.0" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.29.10" version = "0.29.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf" checksum = "272be407f804517512fdf408f0fe6c067bf24659a913c61af97af176bfd5aa92"
dependencies = [ dependencies = [
"ahash 0.8.9", "ahash 0.8.10",
"android-activity", "android-activity",
"atomic-waker", "atomic-waker",
"bitflags 2.4.2", "bitflags 2.4.2",
@ -3770,7 +3769,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.52",
] ]
[[package]] [[package]]

View file

@ -20,7 +20,6 @@ librashader-runtime = { path = "../librashader-runtime", version = "0.2.3" }
librashader-cache = { path = "../librashader-cache", version = "0.2.3", features = ["d3d"] } librashader-cache = { path = "../librashader-cache", version = "0.2.3", features = ["d3d"] }
thiserror = "1.0.37" thiserror = "1.0.37"
parking_lot = "0.12.1"
bytemuck = { version = "1.12.3", features = ["derive"] } bytemuck = { version = "1.12.3", features = ["derive"] }
array-init = "2.1.0" array-init = "2.1.0"

View file

@ -1,9 +1,10 @@
use crate::error; use crate::error;
use bitvec::bitvec; use bitvec::bitvec;
use bitvec::boxed::BitBox; use bitvec::boxed::BitBox;
use parking_lot::RwLock; use bitvec::order::Lsb0;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::Deref; use std::ops::Deref;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc; use std::sync::Arc;
use crate::error::FilterChainError; use crate::error::FilterChainError;
@ -102,7 +103,7 @@ pub type D3D12DescriptorHeapSlot<T> = Arc<D3D12DescriptorHeapSlotInner<T>>;
pub struct D3D12DescriptorHeapSlotInner<T> { pub struct D3D12DescriptorHeapSlotInner<T> {
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>, gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
heap: Arc<RwLock<D3D12DescriptorHeapInner>>, heap: Arc<D3D12DescriptorHeapInner>,
slot: usize, slot: usize,
_pd: PhantomData<T>, _pd: PhantomData<T>,
} }
@ -116,7 +117,7 @@ impl<T> D3D12DescriptorHeapSlotInner<T> {
/// unsafe because type must match /// unsafe because type must match
pub unsafe fn copy_descriptor(&self, source: D3D12_CPU_DESCRIPTOR_HANDLE) { pub unsafe fn copy_descriptor(&self, source: D3D12_CPU_DESCRIPTOR_HANDLE) {
unsafe { unsafe {
let heap = self.heap.deref().read(); let heap = self.heap.deref();
heap.device heap.device
.CopyDescriptorsSimple(1, self.cpu_handle, source, heap.ty) .CopyDescriptorsSimple(1, self.cpu_handle, source, heap.ty)
@ -141,7 +142,7 @@ impl<T: D3D12ShaderVisibleHeapType> AsRef<D3D12_GPU_DESCRIPTOR_HANDLE>
impl<T: D3D12ShaderVisibleHeapType> From<&D3D12DescriptorHeap<T>> for ID3D12DescriptorHeap { impl<T: D3D12ShaderVisibleHeapType> From<&D3D12DescriptorHeap<T>> for ID3D12DescriptorHeap {
fn from(value: &D3D12DescriptorHeap<T>) -> Self { fn from(value: &D3D12DescriptorHeap<T>) -> Self {
value.0.read().heap.clone() value.0.heap.clone()
} }
} }
@ -153,12 +154,12 @@ struct D3D12DescriptorHeapInner {
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE,
gpu_start: Option<D3D12_GPU_DESCRIPTOR_HANDLE>, gpu_start: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
handle_size: usize, handle_size: usize,
start: usize, start: AtomicUsize,
num_descriptors: usize, num_descriptors: usize,
map: BitBox, map: BitBox<AtomicUsize>,
} }
pub struct D3D12DescriptorHeap<T>(Arc<RwLock<D3D12DescriptorHeapInner>>, PhantomData<T>); pub struct D3D12DescriptorHeap<T>(Arc<D3D12DescriptorHeapInner>, PhantomData<T>);
impl<T: D3D12HeapType> D3D12DescriptorHeap<T> { impl<T: D3D12HeapType> D3D12DescriptorHeap<T> {
pub fn new(device: &ID3D12Device, size: usize) -> error::Result<D3D12DescriptorHeap<T>> { pub fn new(device: &ID3D12Device, size: usize) -> error::Result<D3D12DescriptorHeap<T>> {
@ -170,7 +171,7 @@ impl<T: D3D12HeapType> D3D12DescriptorHeap<T> {
impl<T> D3D12DescriptorHeap<T> { impl<T> D3D12DescriptorHeap<T> {
/// Gets a cloned handle to the inner heap /// Gets a cloned handle to the inner heap
pub fn handle(&self) -> ID3D12DescriptorHeap { pub fn handle(&self) -> ID3D12DescriptorHeap {
let inner = self.0.read(); let inner = &self.0;
inner.heap.clone() inner.heap.clone()
} }
@ -189,17 +190,18 @@ impl<T> D3D12DescriptorHeap<T> {
}; };
Ok(D3D12DescriptorHeap( Ok(D3D12DescriptorHeap(
Arc::new(RwLock::new(D3D12DescriptorHeapInner { Arc::new(D3D12DescriptorHeapInner {
device: device.clone(), device: device.clone(),
heap, heap,
ty: desc.Type, ty: desc.Type,
cpu_start, cpu_start,
gpu_start, gpu_start,
handle_size: device.GetDescriptorHandleIncrementSize(desc.Type) as usize, handle_size: device.GetDescriptorHandleIncrementSize(desc.Type) as usize,
start: 0, start: AtomicUsize::new(0),
num_descriptors: desc.NumDescriptors as usize, num_descriptors: desc.NumDescriptors as usize,
map: bitvec![0; desc.NumDescriptors as usize].into_boxed_bitslice(), map: bitvec![AtomicUsize, Lsb0; 0; desc.NumDescriptors as usize]
})), .into_boxed_bitslice(),
}),
PhantomData::default(), PhantomData::default(),
)) ))
} }
@ -228,9 +230,9 @@ impl<T> D3D12DescriptorHeap<T> {
"D3D12DescriptorHeap::suballocate can only be callled immediately after creation." "D3D12DescriptorHeap::suballocate can only be callled immediately after creation."
); );
let inner = Arc::try_unwrap(self.0) let Ok(inner) = Arc::try_unwrap(self.0) else {
.expect("[d3d12] undefined behaviour to suballocate a descriptor heap with live descriptors.") panic!("[d3d12] undefined behaviour to suballocate a descriptor heap with live descriptors.")
.into_inner(); };
let num_descriptors = inner.num_descriptors - reserved; let num_descriptors = inner.num_descriptors - reserved;
@ -263,9 +265,9 @@ impl<T> D3D12DescriptorHeap<T> {
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE { ptr: new_cpu_start }, cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE { ptr: new_cpu_start },
gpu_start: new_gpu_start, gpu_start: new_gpu_start,
handle_size: inner.handle_size, handle_size: inner.handle_size,
start: 0, start: AtomicUsize::new(0),
num_descriptors: size, num_descriptors: size,
map: bitvec![0; size].into_boxed_bitslice(), map: bitvec![AtomicUsize, Lsb0; 0; size].into_boxed_bitslice(),
}); });
start += size; start += size;
@ -290,22 +292,18 @@ impl<T> D3D12DescriptorHeap<T> {
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE { ptr: new_cpu_start }, cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE { ptr: new_cpu_start },
gpu_start: new_gpu_start, gpu_start: new_gpu_start,
handle_size: inner.handle_size, handle_size: inner.handle_size,
start: 0, start: AtomicUsize::new(0),
num_descriptors: reserved, num_descriptors: reserved,
map: bitvec![0; reserved].into_boxed_bitslice(), map: bitvec![AtomicUsize, Lsb0; 0; reserved].into_boxed_bitslice(),
}); });
} }
( (
heaps heaps
.into_iter() .into_iter()
.map(|inner| { .map(|inner| D3D12DescriptorHeap(Arc::new(inner), PhantomData::default()))
D3D12DescriptorHeap(Arc::new(RwLock::new(inner)), PhantomData::default())
})
.collect(), .collect(),
reserved_heap.map(|inner| { reserved_heap.map(|inner| D3D12DescriptorHeap(Arc::new(inner), PhantomData::default())),
D3D12DescriptorHeap(Arc::new(RwLock::new(inner)), PhantomData::default())
}),
inner.heap, inner.heap,
) )
} }
@ -313,12 +311,13 @@ impl<T> D3D12DescriptorHeap<T> {
pub fn alloc_slot(&mut self) -> error::Result<D3D12DescriptorHeapSlot<T>> { pub fn alloc_slot(&mut self) -> error::Result<D3D12DescriptorHeapSlot<T>> {
let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 }; let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 };
let mut inner = self.0.write(); let inner = &self.0;
for i in inner.start..inner.num_descriptors { let start = inner.start.load(Ordering::Acquire);
for i in start..inner.num_descriptors {
if !inner.map[i] { if !inner.map[i] {
inner.map.set(i, true); inner.map.set_aliased(i, true);
handle.ptr = inner.cpu_start.ptr + (i * inner.handle_size); handle.ptr = inner.cpu_start.ptr + (i * inner.handle_size);
inner.start = i + 1; inner.start.store(i + 1, Ordering::Release);
let gpu_handle = inner let gpu_handle = inner
.gpu_start .gpu_start
@ -351,10 +350,9 @@ impl<T> D3D12DescriptorHeap<T> {
impl<T> Drop for D3D12DescriptorHeapSlotInner<T> { impl<T> Drop for D3D12DescriptorHeapSlotInner<T> {
fn drop(&mut self) { fn drop(&mut self) {
let mut inner = self.heap.write(); let inner = &self.heap;
inner.map.set(self.slot, false); inner.map.set_aliased(self.slot, false);
if inner.start > self.slot { // inner.start > self.slot => inner.start = self.slot
inner.start = self.slot inner.start.fetch_min(self.slot, Ordering::AcqRel);
}
} }
} }

View file

@ -1,8 +1,9 @@
use bitvec::bitvec; use bitvec::bitvec;
use bitvec::boxed::BitBox; use bitvec::boxed::BitBox;
use parking_lot::RwLock; use bitvec::order::Lsb0;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::Deref; use std::ops::Deref;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc; use std::sync::Arc;
use windows::Win32::Graphics::Direct3D12::{ use windows::Win32::Graphics::Direct3D12::{
@ -38,7 +39,7 @@ pub type D3D12DescriptorHeapSlot<T> = Arc<D3D12DescriptorHeapSlotInner<T>>;
pub struct D3D12DescriptorHeapSlotInner<T> { pub struct D3D12DescriptorHeapSlotInner<T> {
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>, gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
heap: Arc<RwLock<D3D12DescriptorHeapInner>>, heap: Arc<D3D12DescriptorHeapInner>,
slot: usize, slot: usize,
_pd: PhantomData<T>, _pd: PhantomData<T>,
} }
@ -52,7 +53,7 @@ impl<T> D3D12DescriptorHeapSlotInner<T> {
/// unsafe because type must match /// unsafe because type must match
pub unsafe fn copy_descriptor(&self, source: D3D12_CPU_DESCRIPTOR_HANDLE) { pub unsafe fn copy_descriptor(&self, source: D3D12_CPU_DESCRIPTOR_HANDLE) {
unsafe { unsafe {
let heap = self.heap.deref().read(); let heap = &self.heap.deref();
heap.device heap.device
.CopyDescriptorsSimple(1, self.cpu_handle, source, heap.ty) .CopyDescriptorsSimple(1, self.cpu_handle, source, heap.ty)
@ -77,7 +78,7 @@ impl<T: D3D12ShaderVisibleHeapType> AsRef<D3D12_GPU_DESCRIPTOR_HANDLE>
impl<T: D3D12ShaderVisibleHeapType> From<&D3D12DescriptorHeap<T>> for ID3D12DescriptorHeap { impl<T: D3D12ShaderVisibleHeapType> From<&D3D12DescriptorHeap<T>> for ID3D12DescriptorHeap {
fn from(value: &D3D12DescriptorHeap<T>) -> Self { fn from(value: &D3D12DescriptorHeap<T>) -> Self {
value.0.read().heap.clone() value.0.heap.clone()
} }
} }
@ -89,12 +90,12 @@ struct D3D12DescriptorHeapInner {
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE,
gpu_start: Option<D3D12_GPU_DESCRIPTOR_HANDLE>, gpu_start: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
handle_size: usize, handle_size: usize,
start: usize, start: AtomicUsize,
num_descriptors: usize, num_descriptors: usize,
map: BitBox, map: BitBox<AtomicUsize>,
} }
pub struct D3D12DescriptorHeap<T>(Arc<RwLock<D3D12DescriptorHeapInner>>, PhantomData<T>); pub struct D3D12DescriptorHeap<T>(Arc<D3D12DescriptorHeapInner>, PhantomData<T>);
impl<T: D3D12HeapType> D3D12DescriptorHeap<T> { impl<T: D3D12HeapType> D3D12DescriptorHeap<T> {
pub fn new( pub fn new(
@ -109,8 +110,7 @@ impl<T: D3D12HeapType> D3D12DescriptorHeap<T> {
impl<T> D3D12DescriptorHeap<T> { impl<T> D3D12DescriptorHeap<T> {
/// Gets a cloned handle to the inner heap /// Gets a cloned handle to the inner heap
pub fn handle(&self) -> ID3D12DescriptorHeap { pub fn handle(&self) -> ID3D12DescriptorHeap {
let inner = self.0.read(); self.0.heap.clone()
inner.heap.clone()
} }
pub unsafe fn new_with_desc( pub unsafe fn new_with_desc(
@ -128,17 +128,18 @@ impl<T> D3D12DescriptorHeap<T> {
}; };
Ok(D3D12DescriptorHeap( Ok(D3D12DescriptorHeap(
Arc::new(RwLock::new(D3D12DescriptorHeapInner { Arc::new(D3D12DescriptorHeapInner {
device: device.clone(), device: device.clone(),
heap, heap,
ty: desc.Type, ty: desc.Type,
cpu_start, cpu_start,
gpu_start, gpu_start,
handle_size: device.GetDescriptorHandleIncrementSize(desc.Type) as usize, handle_size: device.GetDescriptorHandleIncrementSize(desc.Type) as usize,
start: 0, start: AtomicUsize::new(0),
num_descriptors: desc.NumDescriptors as usize, num_descriptors: desc.NumDescriptors as usize,
map: bitvec![0; desc.NumDescriptors as usize].into_boxed_bitslice(), map: bitvec![AtomicUsize, Lsb0; 0; desc.NumDescriptors as usize]
})), .into_boxed_bitslice(),
}),
PhantomData::default(), PhantomData::default(),
)) ))
} }
@ -147,12 +148,13 @@ impl<T> D3D12DescriptorHeap<T> {
pub fn alloc_slot(&mut self) -> D3D12DescriptorHeapSlot<T> { pub fn alloc_slot(&mut self) -> D3D12DescriptorHeapSlot<T> {
let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 }; let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 };
let mut inner = self.0.write(); let inner = &self.0;
for i in inner.start..inner.num_descriptors { let start = inner.start.load(Ordering::Acquire);
for i in start..inner.num_descriptors {
if !inner.map[i] { if !inner.map[i] {
inner.map.set(i, true); inner.map.set_aliased(i, true);
handle.ptr = inner.cpu_start.ptr + (i * inner.handle_size); handle.ptr = inner.cpu_start.ptr + (i * inner.handle_size);
inner.start = i + 1; inner.start.store(i + 1, Ordering::Release);
let gpu_handle = inner let gpu_handle = inner
.gpu_start .gpu_start
@ -176,10 +178,9 @@ impl<T> D3D12DescriptorHeap<T> {
impl<T> Drop for D3D12DescriptorHeapSlotInner<T> { impl<T> Drop for D3D12DescriptorHeapSlotInner<T> {
fn drop(&mut self) { fn drop(&mut self) {
let mut inner = self.heap.write(); let inner = &self.heap;
inner.map.set(self.slot, false); inner.map.set_aliased(self.slot, false);
if inner.start > self.slot { // inner.start > self.slot => inner.start = self.slot
inner.start = self.slot inner.start.fetch_min(self.slot, Ordering::AcqRel);
}
} }
} }