mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-26 16:53:48 +00:00
Merge #330
330: New swapchain model r=grovesNL a=kvark Fixes #322 TODO: - [x] Test on Metal - [x] Test on DX12 - [x] Test on Vulkan - [x] Try embedding the backend information into `SwapChainId` - [x] Wait for https://github.com/amethyst/rendy/pull/202 Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
commit
499bf1d268
72
Cargo.lock
generated
72
Cargo.lock
generated
@ -254,13 +254,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
[[package]]
|
||||
name = "gfx-backend-dx11"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019#a084a1f2fec6c9ed928c53e2dc8c1761782b9019"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69#3d5db15661127c8cad8d85522a68ec36c82f6e69"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"range-alloc 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"range-alloc 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spirv_cross 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -270,13 +270,13 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gfx-backend-dx12"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019#a084a1f2fec6c9ed928c53e2dc8c1761782b9019"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69#3d5db15661127c8cad8d85522a68ec36c82f6e69"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"d3d12 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"range-alloc 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"range-alloc 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spirv_cross 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -285,15 +285,15 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gfx-backend-empty"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019#a084a1f2fec6c9ed928c53e2dc8c1761782b9019"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69#3d5db15661127c8cad8d85522a68ec36c82f6e69"
|
||||
dependencies = [
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gfx-backend-metal"
|
||||
version = "0.3.2"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019#a084a1f2fec6c9ed928c53e2dc8c1761782b9019"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69#3d5db15661127c8cad8d85522a68ec36c82f6e69"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -302,12 +302,12 @@ dependencies = [
|
||||
"copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"metal 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"range-alloc 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"range-alloc 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spirv_cross 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"storage-map 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -316,13 +316,13 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gfx-backend-vulkan"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019#a084a1f2fec6c9ed928c53e2dc8c1761782b9019"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69#3d5db15661127c8cad8d85522a68ec36c82f6e69"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ash 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -334,7 +334,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gfx-hal"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019#a084a1f2fec6c9ed928c53e2dc8c1761782b9019"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69#3d5db15661127c8cad8d85522a68ec36c82f6e69"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -643,7 +643,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "range-alloc"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019#a084a1f2fec6c9ed928c53e2dc8c1761782b9019"
|
||||
source = "git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69#3d5db15661127c8cad8d85522a68ec36c82f6e69"
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
@ -687,11 +687,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rendy-descriptor"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/amethyst/rendy?rev=a8ac0de977a28d09592d615f8857461622833443#a8ac0de977a28d09592d615f8857461622833443"
|
||||
source = "git+https://github.com/amethyst/rendy?rev=e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86#e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86"
|
||||
dependencies = [
|
||||
"derivative 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"relevant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -700,12 +700,12 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rendy-memory"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/amethyst/rendy?rev=a8ac0de977a28d09592d615f8857461622833443#a8ac0de977a28d09592d615f8857461622833443"
|
||||
source = "git+https://github.com/amethyst/rendy?rev=e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86#e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86"
|
||||
dependencies = [
|
||||
"colorful 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"derivative 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"hibitset 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"relevant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -906,18 +906,18 @@ dependencies = [
|
||||
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gfx-backend-dx11 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-backend-dx12 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-backend-empty 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-backend-metal 0.3.2 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-backend-vulkan 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)",
|
||||
"gfx-backend-dx11 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"gfx-backend-dx12 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"gfx-backend-empty 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"gfx-backend-metal 0.3.2 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"gfx-backend-vulkan 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"raw-window-handle 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rendy-descriptor 0.4.0 (git+https://github.com/amethyst/rendy?rev=a8ac0de977a28d09592d615f8857461622833443)",
|
||||
"rendy-memory 0.4.0 (git+https://github.com/amethyst/rendy?rev=a8ac0de977a28d09592d615f8857461622833443)",
|
||||
"rendy-descriptor 0.4.0 (git+https://github.com/amethyst/rendy?rev=e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86)",
|
||||
"rendy-memory 0.4.0 (git+https://github.com/amethyst/rendy?rev=e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86)",
|
||||
"serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1023,12 +1023,12 @@ dependencies = [
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
"checksum gfx-backend-dx11 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)" = "<none>"
|
||||
"checksum gfx-backend-dx12 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)" = "<none>"
|
||||
"checksum gfx-backend-empty 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)" = "<none>"
|
||||
"checksum gfx-backend-metal 0.3.2 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)" = "<none>"
|
||||
"checksum gfx-backend-vulkan 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)" = "<none>"
|
||||
"checksum gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)" = "<none>"
|
||||
"checksum gfx-backend-dx11 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)" = "<none>"
|
||||
"checksum gfx-backend-dx12 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)" = "<none>"
|
||||
"checksum gfx-backend-empty 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)" = "<none>"
|
||||
"checksum gfx-backend-metal 0.3.2 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)" = "<none>"
|
||||
"checksum gfx-backend-vulkan 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)" = "<none>"
|
||||
"checksum gfx-hal 0.3.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)" = "<none>"
|
||||
"checksum hibitset 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47e7292fd9f7fe89fa35c98048f2d0a69b79ed243604234d18f6f8a1aa6f408d"
|
||||
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||
"checksum ipc-channel 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79d98ee7dd1d2e796d254807fd86ea7189d07571aeaa74007603e29a79d15217"
|
||||
@ -1061,14 +1061,14 @@ dependencies = [
|
||||
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
"checksum range-alloc 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=a084a1f2fec6c9ed928c53e2dc8c1761782b9019)" = "<none>"
|
||||
"checksum range-alloc 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=3d5db15661127c8cad8d85522a68ec36c82f6e69)" = "<none>"
|
||||
"checksum raw-window-handle 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "af3d3b2e1053b3ff2171efc29a8bff3439ce6b2ce6a0432695134bc1c7ff8e87"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"
|
||||
"checksum relevant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bbc232e13d37f4547f5b9b42a5efc380cabe5dbc1807f8b893580640b2ab0308"
|
||||
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
|
||||
"checksum rendy-descriptor 0.4.0 (git+https://github.com/amethyst/rendy?rev=a8ac0de977a28d09592d615f8857461622833443)" = "<none>"
|
||||
"checksum rendy-memory 0.4.0 (git+https://github.com/amethyst/rendy?rev=a8ac0de977a28d09592d615f8857461622833443)" = "<none>"
|
||||
"checksum rendy-descriptor 0.4.0 (git+https://github.com/amethyst/rendy?rev=e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86)" = "<none>"
|
||||
"checksum rendy-memory 0.4.0 (git+https://github.com/amethyst/rendy?rev=e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86)" = "<none>"
|
||||
"checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||
|
@ -648,7 +648,6 @@ typedef struct {
|
||||
} WGPURequestAdapterOptions;
|
||||
|
||||
typedef struct {
|
||||
WGPUTextureId texture_id;
|
||||
WGPUTextureViewId view_id;
|
||||
} WGPUSwapChainOutput;
|
||||
|
||||
@ -900,7 +899,9 @@ void wgpu_render_pass_set_viewport(WGPURenderPassId pass_id,
|
||||
WGPUAdapterId wgpu_request_adapter(const WGPURequestAdapterOptions *desc);
|
||||
#endif
|
||||
|
||||
#if !defined(WGPU_REMOTE)
|
||||
WGPUSwapChainOutput wgpu_swap_chain_get_next_texture(WGPUSwapChainId swap_chain_id);
|
||||
#endif
|
||||
|
||||
void wgpu_swap_chain_present(WGPUSwapChainId swap_chain_id);
|
||||
|
||||
|
@ -28,23 +28,23 @@ bitflags = "1.0"
|
||||
copyless = "0.1"
|
||||
lazy_static = "1.1.0"
|
||||
log = "0.4"
|
||||
hal = { package = "gfx-hal", git = "https://github.com/gfx-rs/gfx", rev = "a084a1f2fec6c9ed928c53e2dc8c1761782b9019" }
|
||||
gfx-backend-empty = { git = "https://github.com/gfx-rs/gfx", rev = "a084a1f2fec6c9ed928c53e2dc8c1761782b9019" }
|
||||
hal = { package = "gfx-hal", git = "https://github.com/gfx-rs/gfx", rev = "3d5db15661127c8cad8d85522a68ec36c82f6e69" }
|
||||
gfx-backend-empty = { git = "https://github.com/gfx-rs/gfx", rev = "3d5db15661127c8cad8d85522a68ec36c82f6e69" }
|
||||
parking_lot = "0.9"
|
||||
raw-window-handle = "0.1"
|
||||
rendy-memory = { git = "https://github.com/amethyst/rendy", rev = "a8ac0de977a28d09592d615f8857461622833443" }
|
||||
rendy-descriptor = { git = "https://github.com/amethyst/rendy", rev = "a8ac0de977a28d09592d615f8857461622833443" }
|
||||
rendy-memory = { git = "https://github.com/amethyst/rendy", rev = "e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86" }
|
||||
rendy-descriptor = { git = "https://github.com/amethyst/rendy", rev = "e8ffcabc2bc74fbb282d4f71fa55c28d0ec31c86" }
|
||||
serde = { version = "1.0", features = ["serde_derive"], optional = true }
|
||||
vec_map = "0.8"
|
||||
|
||||
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
|
||||
gfx-backend-metal = { git = "https://github.com/gfx-rs/gfx", rev = "a084a1f2fec6c9ed928c53e2dc8c1761782b9019" }
|
||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "a084a1f2fec6c9ed928c53e2dc8c1761782b9019", optional = true }
|
||||
gfx-backend-metal = { git = "https://github.com/gfx-rs/gfx", rev = "3d5db15661127c8cad8d85522a68ec36c82f6e69" }
|
||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "3d5db15661127c8cad8d85522a68ec36c82f6e69", optional = true }
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies]
|
||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "a084a1f2fec6c9ed928c53e2dc8c1761782b9019", features = ["x11"] }
|
||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "3d5db15661127c8cad8d85522a68ec36c82f6e69", features = ["x11"] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
gfx-backend-dx12 = { git = "https://github.com/gfx-rs/gfx", rev = "a084a1f2fec6c9ed928c53e2dc8c1761782b9019" }
|
||||
gfx-backend-dx11 = { git = "https://github.com/gfx-rs/gfx", rev = "a084a1f2fec6c9ed928c53e2dc8c1761782b9019" }
|
||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "a084a1f2fec6c9ed928c53e2dc8c1761782b9019" }
|
||||
gfx-backend-dx12 = { git = "https://github.com/gfx-rs/gfx", rev = "3d5db15661127c8cad8d85522a68ec36c82f6e69" }
|
||||
gfx-backend-dx11 = { git = "https://github.com/gfx-rs/gfx", rev = "3d5db15661127c8cad8d85522a68ec36c82f6e69" }
|
||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "3d5db15661127c8cad8d85522a68ec36c82f6e69" }
|
||||
|
@ -87,7 +87,7 @@ impl<B: GfxBackend> CommandAllocator<B> {
|
||||
device_id,
|
||||
life_guard: LifeGuard::new(),
|
||||
trackers: TrackerSet::new(B::VARIANT),
|
||||
swap_chain_links: Vec::new(),
|
||||
used_swap_chain_image: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,7 @@ use crate::{
|
||||
gfx_select,
|
||||
hub::{GfxBackend, Storage, Token},
|
||||
id::{Input, Output},
|
||||
resource::TexturePlacement,
|
||||
swap_chain::{SwapChainLink, SwapImageEpoch},
|
||||
resource::TextureViewInner,
|
||||
track::{Stitch, TrackerSet},
|
||||
Buffer,
|
||||
BufferId,
|
||||
@ -46,7 +45,15 @@ use log::trace;
|
||||
|
||||
#[cfg(not(feature = "remote"))]
|
||||
use std::marker::PhantomData;
|
||||
use std::{collections::hash_map::Entry, iter, mem, ptr, slice, thread::ThreadId};
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
collections::hash_map::Entry,
|
||||
iter,
|
||||
mem,
|
||||
ptr,
|
||||
slice,
|
||||
thread::ThreadId,
|
||||
};
|
||||
|
||||
|
||||
pub struct RenderBundle<B: hal::Backend> {
|
||||
@ -111,7 +118,7 @@ pub struct CommandBuffer<B: hal::Backend> {
|
||||
device_id: Stored<DeviceId>,
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
pub(crate) trackers: TrackerSet,
|
||||
pub(crate) swap_chain_links: Vec<SwapChainLink<SwapImageEpoch>>,
|
||||
pub(crate) used_swap_chain_image: Option<Stored<TextureViewId>>,
|
||||
}
|
||||
|
||||
impl<B: GfxBackend> CommandBuffer<B> {
|
||||
@ -187,7 +194,13 @@ pub fn command_encoder_finish<B: GfxBackend>(
|
||||
let mut token = Token::root();
|
||||
//TODO: actually close the last recorded command buffer
|
||||
let (mut comb_guard, _) = hub.command_buffers.write(&mut token);
|
||||
comb_guard[encoder_id].is_recording = false; //TODO: check for the old value
|
||||
let comb = &mut comb_guard[encoder_id];
|
||||
assert!(comb.is_recording);
|
||||
comb.is_recording = false;
|
||||
// stop tracking the swapchain image, if used
|
||||
if let Some(ref view_id) = comb.used_swap_chain_image {
|
||||
comb.trackers.views.remove(view_id.value);
|
||||
}
|
||||
encoder_id
|
||||
}
|
||||
|
||||
@ -255,7 +268,6 @@ pub fn command_encoder_begin_render_pass<B: GfxBackend>(
|
||||
);
|
||||
let rp_key = {
|
||||
let trackers = &mut cmb.trackers;
|
||||
let swap_chain_links = &mut cmb.swap_chain_links;
|
||||
|
||||
let depth_stencil = depth_stencil_attachment.map(|at| {
|
||||
let view = trackers
|
||||
@ -267,13 +279,18 @@ pub fn command_encoder_begin_render_pass<B: GfxBackend>(
|
||||
} else {
|
||||
extent = Some(view.extent);
|
||||
}
|
||||
let texture_id = match view.inner {
|
||||
TextureViewInner::Native { ref source_id, .. } => source_id.value,
|
||||
TextureViewInner::SwapChain {..} =>
|
||||
panic!("Unexpected depth/stencil use of swapchain image!"),
|
||||
};
|
||||
|
||||
let texture = &texture_guard[view.texture_id.value];
|
||||
let texture = &texture_guard[texture_id];
|
||||
assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT));
|
||||
|
||||
let old_layout = match trackers
|
||||
.textures
|
||||
.query(view.texture_id.value, view.range.clone())
|
||||
.query(texture_id, view.range.clone())
|
||||
{
|
||||
Some(usage) => {
|
||||
conv::map_texture_state(
|
||||
@ -286,7 +303,7 @@ pub fn command_encoder_begin_render_pass<B: GfxBackend>(
|
||||
// Required sub-resources have inconsistent states, we need to
|
||||
// issue individual barriers instead of relying on the render pass.
|
||||
let pending = trackers.textures.change_replace(
|
||||
view.texture_id.value,
|
||||
texture_id,
|
||||
&texture.life_guard.ref_count,
|
||||
view.range.clone(),
|
||||
TextureUsage::OUTPUT_ATTACHMENT,
|
||||
@ -317,10 +334,7 @@ pub fn command_encoder_begin_render_pass<B: GfxBackend>(
|
||||
let mut resolves = ArrayVec::new();
|
||||
|
||||
for at in color_attachments {
|
||||
let view = trackers
|
||||
.views
|
||||
.use_extend(&*view_guard, at.attachment, (), ())
|
||||
.unwrap();
|
||||
let view = &view_guard[at.attachment];
|
||||
if let Some(ex) = extent {
|
||||
assert_eq!(ex, view.extent);
|
||||
} else {
|
||||
@ -330,47 +344,55 @@ pub fn command_encoder_begin_render_pass<B: GfxBackend>(
|
||||
view.samples, sample_count,
|
||||
"All attachments must have the same sample_count"
|
||||
);
|
||||
let first_use = trackers.views
|
||||
.init(at.attachment, &view.life_guard.ref_count, (), ());
|
||||
|
||||
if view.is_owned_by_swap_chain {
|
||||
let link = match texture_guard[view.texture_id.value].placement {
|
||||
TexturePlacement::SwapChain(ref link) => SwapChainLink {
|
||||
swap_chain_id: link.swap_chain_id.clone(),
|
||||
epoch: *link.epoch.lock(),
|
||||
image_index: link.image_index,
|
||||
},
|
||||
TexturePlacement::Memory(_) => unreachable!(),
|
||||
};
|
||||
swap_chain_links.push(link);
|
||||
}
|
||||
let layouts = match view.inner {
|
||||
TextureViewInner::Native { ref source_id, .. } => {
|
||||
let texture = &texture_guard[source_id.value];
|
||||
assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT));
|
||||
|
||||
let texture = &texture_guard[view.texture_id.value];
|
||||
assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT));
|
||||
|
||||
let old_layout = match trackers
|
||||
.textures
|
||||
.query(view.texture_id.value, view.range.clone())
|
||||
{
|
||||
Some(usage) => conv::map_texture_state(usage, hal::format::Aspects::COLOR).1,
|
||||
None => {
|
||||
// Required sub-resources have inconsistent states, we need to
|
||||
// issue individual barriers instead of relying on the render pass.
|
||||
let pending = trackers.textures.change_replace(
|
||||
view.texture_id.value,
|
||||
&texture.life_guard.ref_count,
|
||||
view.range.clone(),
|
||||
TextureUsage::OUTPUT_ATTACHMENT,
|
||||
);
|
||||
|
||||
barriers.extend(pending.map(|pending| {
|
||||
trace!("\tcolor {:?}", pending);
|
||||
hal::memory::Barrier::Image {
|
||||
states: pending.to_states(),
|
||||
target: &texture.raw,
|
||||
families: None,
|
||||
range: pending.selector,
|
||||
let old_layout = match trackers
|
||||
.textures
|
||||
.query(source_id.value, view.range.clone())
|
||||
{
|
||||
Some(usage) => conv::map_texture_state(usage, hal::format::Aspects::COLOR).1,
|
||||
None => {
|
||||
// Required sub-resources have inconsistent states, we need to
|
||||
// issue individual barriers instead of relying on the render pass.
|
||||
let pending = trackers.textures.change_replace(
|
||||
source_id.value,
|
||||
&texture.life_guard.ref_count,
|
||||
view.range.clone(),
|
||||
TextureUsage::OUTPUT_ATTACHMENT,
|
||||
);
|
||||
barriers.extend(pending.map(|pending| {
|
||||
trace!("\tcolor {:?}", pending);
|
||||
hal::memory::Barrier::Image {
|
||||
states: pending.to_states(),
|
||||
target: &texture.raw,
|
||||
families: None,
|
||||
range: pending.selector,
|
||||
}
|
||||
}));
|
||||
hal::image::Layout::ColorAttachmentOptimal
|
||||
}
|
||||
}));
|
||||
hal::image::Layout::ColorAttachmentOptimal
|
||||
};
|
||||
old_layout .. hal::image::Layout::ColorAttachmentOptimal
|
||||
}
|
||||
TextureViewInner::SwapChain { .. } => {
|
||||
if let Some(ref view_id) = cmb.used_swap_chain_image {
|
||||
assert_eq!(view_id.value, at.attachment);
|
||||
} else {
|
||||
cmb.used_swap_chain_image = Some(Stored {
|
||||
value: at.attachment,
|
||||
ref_count: view.life_guard.ref_count.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
let end = hal::image::Layout::Present;
|
||||
let start = if first_use { hal::image::Layout::Undefined } else { end };
|
||||
start .. end
|
||||
}
|
||||
};
|
||||
|
||||
@ -379,80 +401,82 @@ pub fn command_encoder_begin_render_pass<B: GfxBackend>(
|
||||
samples: view.samples,
|
||||
ops: conv::map_load_store_ops(at.load_op, at.store_op),
|
||||
stencil_ops: hal::pass::AttachmentOps::DONT_CARE,
|
||||
layouts: old_layout .. hal::image::Layout::ColorAttachmentOptimal,
|
||||
layouts,
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(resolve_target) = unsafe { at.resolve_target.as_ref() } {
|
||||
let view = trackers
|
||||
.views
|
||||
.use_extend(&*view_guard, *resolve_target, (), ())
|
||||
.unwrap();
|
||||
if let Some(ex) = extent {
|
||||
assert_eq!(ex, view.extent);
|
||||
} else {
|
||||
extent = Some(view.extent);
|
||||
}
|
||||
assert_eq!(
|
||||
view.samples, 1,
|
||||
"All resolve_targets must have a sample_count of 1"
|
||||
);
|
||||
for &resolve_target in color_attachments
|
||||
.iter()
|
||||
.flat_map(|at| unsafe { at.resolve_target.as_ref() })
|
||||
{
|
||||
let view = &view_guard[resolve_target];
|
||||
assert_eq!(extent, Some(view.extent));
|
||||
assert_eq!(
|
||||
view.samples, 1,
|
||||
"All resolve_targets must have a sample_count of 1"
|
||||
);
|
||||
let first_use = trackers.views
|
||||
.init(resolve_target, &view.life_guard.ref_count, (), ());
|
||||
|
||||
if view.is_owned_by_swap_chain {
|
||||
let link = match texture_guard[view.texture_id.value].placement {
|
||||
TexturePlacement::SwapChain(ref link) => SwapChainLink {
|
||||
swap_chain_id: link.swap_chain_id.clone(),
|
||||
epoch: *link.epoch.lock(),
|
||||
image_index: link.image_index,
|
||||
},
|
||||
TexturePlacement::Memory(_) => unreachable!(),
|
||||
let layouts = match view.inner {
|
||||
TextureViewInner::Native { ref source_id, .. } => {
|
||||
let texture = &texture_guard[source_id.value];
|
||||
assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT));
|
||||
|
||||
let old_layout = match trackers
|
||||
.textures
|
||||
.query(source_id.value, view.range.clone())
|
||||
{
|
||||
Some(usage) => conv::map_texture_state(usage, hal::format::Aspects::COLOR).1,
|
||||
None => {
|
||||
// Required sub-resources have inconsistent states, we need to
|
||||
// issue individual barriers instead of relying on the render pass.
|
||||
let pending = trackers.textures.change_replace(
|
||||
source_id.value,
|
||||
&texture.life_guard.ref_count,
|
||||
view.range.clone(),
|
||||
TextureUsage::OUTPUT_ATTACHMENT,
|
||||
);
|
||||
barriers.extend(pending.map(|pending| {
|
||||
trace!("\tresolve {:?}", pending);
|
||||
hal::memory::Barrier::Image {
|
||||
states: pending.to_states(),
|
||||
target: &texture.raw,
|
||||
families: None,
|
||||
range: pending.selector,
|
||||
}
|
||||
}));
|
||||
hal::image::Layout::ColorAttachmentOptimal
|
||||
}
|
||||
};
|
||||
swap_chain_links.push(link);
|
||||
old_layout .. hal::image::Layout::ColorAttachmentOptimal
|
||||
}
|
||||
|
||||
let texture = &texture_guard[view.texture_id.value];
|
||||
assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT));
|
||||
|
||||
let old_layout = match trackers
|
||||
.textures
|
||||
.query(view.texture_id.value, view.range.clone())
|
||||
{
|
||||
Some(usage) => {
|
||||
conv::map_texture_state(usage, hal::format::Aspects::COLOR).1
|
||||
TextureViewInner::SwapChain { .. } => {
|
||||
if let Some(ref view_id) = cmb.used_swap_chain_image {
|
||||
assert_eq!(view_id.value, resolve_target);
|
||||
} else {
|
||||
cmb.used_swap_chain_image = Some(Stored {
|
||||
value: resolve_target,
|
||||
ref_count: view.life_guard.ref_count.clone(),
|
||||
});
|
||||
}
|
||||
None => {
|
||||
// Required sub-resources have inconsistent states, we need to
|
||||
// issue individual barriers instead of relying on the render pass.
|
||||
let pending = trackers.textures.change_replace(
|
||||
view.texture_id.value,
|
||||
&texture.life_guard.ref_count,
|
||||
view.range.clone(),
|
||||
TextureUsage::OUTPUT_ATTACHMENT,
|
||||
);
|
||||
|
||||
barriers.extend(pending.map(|pending| {
|
||||
trace!("\tresolve {:?}", pending);
|
||||
hal::memory::Barrier::Image {
|
||||
states: pending.to_states(),
|
||||
target: &texture.raw,
|
||||
families: None,
|
||||
range: pending.selector,
|
||||
}
|
||||
}));
|
||||
hal::image::Layout::ColorAttachmentOptimal
|
||||
}
|
||||
};
|
||||
let end = hal::image::Layout::Present;
|
||||
let start = if first_use { hal::image::Layout::Undefined } else { end };
|
||||
start .. end
|
||||
}
|
||||
};
|
||||
|
||||
resolves.push(hal::pass::Attachment {
|
||||
format: Some(conv::map_texture_format(view.format)),
|
||||
samples: view.samples,
|
||||
ops: hal::pass::AttachmentOps::new(
|
||||
hal::pass::AttachmentLoadOp::DontCare,
|
||||
hal::pass::AttachmentStoreOp::Store,
|
||||
),
|
||||
stencil_ops: hal::pass::AttachmentOps::DONT_CARE,
|
||||
layouts: old_layout .. hal::image::Layout::ColorAttachmentOptimal,
|
||||
});
|
||||
}
|
||||
resolves.push(hal::pass::Attachment {
|
||||
format: Some(conv::map_texture_format(view.format)),
|
||||
samples: view.samples,
|
||||
ops: hal::pass::AttachmentOps::new(
|
||||
hal::pass::AttachmentLoadOp::DontCare,
|
||||
hal::pass::AttachmentStoreOp::Store,
|
||||
),
|
||||
stencil_ops: hal::pass::AttachmentOps::DONT_CARE,
|
||||
layouts,
|
||||
});
|
||||
}
|
||||
|
||||
RenderPassKey {
|
||||
@ -544,8 +568,10 @@ pub fn command_encoder_begin_render_pass<B: GfxBackend>(
|
||||
Entry::Occupied(e) => e.into_mut(),
|
||||
Entry::Vacant(e) => {
|
||||
let fb = {
|
||||
let attachments = e.key().all().map(|&id| &view_guard[id].raw);
|
||||
|
||||
let attachments = e.key().all().map(|&id| match view_guard[id].inner {
|
||||
TextureViewInner::Native { ref raw, .. } => raw,
|
||||
TextureViewInner::SwapChain { ref image, .. } => Borrow::borrow(image),
|
||||
});
|
||||
unsafe {
|
||||
device
|
||||
.raw
|
||||
|
@ -3,8 +3,6 @@ use crate::{
|
||||
device::{all_buffer_stages, all_image_stages},
|
||||
gfx_select,
|
||||
hub::{GfxBackend, Token},
|
||||
resource::TexturePlacement,
|
||||
swap_chain::SwapChainLink,
|
||||
BufferAddress,
|
||||
BufferId,
|
||||
BufferUsage,
|
||||
@ -15,7 +13,6 @@ use crate::{
|
||||
TextureUsage,
|
||||
};
|
||||
|
||||
use copyless::VecHelper as _;
|
||||
use hal::command::CommandBuffer as _;
|
||||
|
||||
use std::iter;
|
||||
@ -183,14 +180,6 @@ pub fn command_encoder_copy_buffer_to_texture<B: GfxBackend>(
|
||||
range: pending.selector,
|
||||
});
|
||||
|
||||
if let TexturePlacement::SwapChain(ref link) = dst_texture.placement {
|
||||
cmb.swap_chain_links.alloc().init(SwapChainLink {
|
||||
swap_chain_id: link.swap_chain_id.clone(),
|
||||
epoch: *link.epoch.lock(),
|
||||
image_index: link.image_index,
|
||||
});
|
||||
}
|
||||
|
||||
let aspects = dst_texture.full_range.aspects;
|
||||
let bytes_per_texel = conv::map_texture_format(dst_texture.format)
|
||||
.surface_desc()
|
||||
@ -265,10 +254,6 @@ pub fn command_encoder_copy_texture_to_buffer<B: GfxBackend>(
|
||||
families: None,
|
||||
range: pending.selector,
|
||||
});
|
||||
match src_texture.placement {
|
||||
TexturePlacement::SwapChain(_) => unimplemented!(),
|
||||
TexturePlacement::Memory(_) => (),
|
||||
}
|
||||
|
||||
let (dst_buffer, dst_barriers) = cmb.trackers.buffers.use_replace(
|
||||
&*buffer_guard,
|
||||
@ -380,14 +365,6 @@ pub fn command_encoder_copy_texture_to_texture<B: GfxBackend>(
|
||||
range: pending.selector,
|
||||
}));
|
||||
|
||||
if let TexturePlacement::SwapChain(ref link) = dst_texture.placement {
|
||||
cmb.swap_chain_links.alloc().init(SwapChainLink {
|
||||
swap_chain_id: link.swap_chain_id.clone(),
|
||||
epoch: *link.epoch.lock(),
|
||||
image_index: link.image_index,
|
||||
});
|
||||
}
|
||||
|
||||
let aspects = src_texture.full_range.aspects & dst_texture.full_range.aspects;
|
||||
let region = hal::command::ImageCopy {
|
||||
src_subresource: source.to_sub_layers(aspects),
|
||||
|
@ -1,5 +1,7 @@
|
||||
#[cfg(not(feature = "remote"))]
|
||||
use crate::instance::Limits;
|
||||
use crate::{
|
||||
instance::Limits,
|
||||
};
|
||||
use crate::{
|
||||
binding_model,
|
||||
command,
|
||||
@ -45,11 +47,9 @@ use hal::{
|
||||
backend::FastHashMap,
|
||||
command::CommandBuffer as _,
|
||||
device::Device as _,
|
||||
pool::CommandPool as _,
|
||||
queue::CommandQueue as _,
|
||||
window::Surface as _,
|
||||
window::{PresentationSurface as _, Surface as _},
|
||||
};
|
||||
use log::{info, trace};
|
||||
use parking_lot::Mutex;
|
||||
use rendy_descriptor::{DescriptorAllocator, DescriptorRanges, DescriptorSet};
|
||||
use rendy_memory::{Block, Heaps, MemoryBlock};
|
||||
@ -63,7 +63,7 @@ use std::{
|
||||
ops::Range,
|
||||
ptr,
|
||||
slice,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
sync::atomic::{Ordering},
|
||||
};
|
||||
|
||||
|
||||
@ -228,7 +228,7 @@ impl<B: GfxBackend> PendingResources<B> {
|
||||
};
|
||||
|
||||
for a in self.active.drain(.. done_count) {
|
||||
trace!("Active submission {} is done", a.index);
|
||||
log::trace!("Active submission {} is done", a.index);
|
||||
self.free.extend(a.resources.into_iter().map(|(_, r)| r));
|
||||
self.ready_to_map.extend(a.mapped);
|
||||
unsafe {
|
||||
@ -296,33 +296,32 @@ impl<B: GfxBackend> PendingResources<B> {
|
||||
continue;
|
||||
}
|
||||
trackers.buffers.remove(id);
|
||||
let buf = buffer_guard.remove(id);
|
||||
let buf = buffer_guard.remove(id).unwrap();
|
||||
#[cfg(not(feature = "remote"))]
|
||||
hub.buffers.identity.lock().free(id);
|
||||
(buf.life_guard, NativeResource::Buffer(buf.raw, buf.memory))
|
||||
}
|
||||
ResourceId::Texture(id) => {
|
||||
trackers.textures.remove(id);
|
||||
let tex = texture_guard.remove(id);
|
||||
let tex = texture_guard.remove(id).unwrap();
|
||||
#[cfg(not(feature = "remote"))]
|
||||
hub.textures.identity.lock().free(id);
|
||||
let memory = match tex.placement {
|
||||
// swapchain-owned images don't need explicit destruction
|
||||
resource::TexturePlacement::SwapChain(_) => continue,
|
||||
resource::TexturePlacement::Memory(mem) => mem,
|
||||
};
|
||||
(tex.life_guard, NativeResource::Image(tex.raw, memory))
|
||||
(tex.life_guard, NativeResource::Image(tex.raw, tex.memory))
|
||||
}
|
||||
ResourceId::TextureView(id) => {
|
||||
trackers.views.remove(id);
|
||||
let view = teview_view_guard.remove(id);
|
||||
let view = teview_view_guard.remove(id).unwrap();
|
||||
let raw = match view.inner {
|
||||
resource::TextureViewInner::Native { raw, .. } => raw,
|
||||
resource::TextureViewInner::SwapChain { .. } => unreachable!(),
|
||||
};
|
||||
#[cfg(not(feature = "remote"))]
|
||||
hub.texture_views.identity.lock().free(id);
|
||||
(view.life_guard, NativeResource::ImageView(view.raw))
|
||||
(view.life_guard, NativeResource::ImageView(raw))
|
||||
}
|
||||
ResourceId::BindGroup(id) => {
|
||||
trackers.bind_groups.remove(id);
|
||||
let bind_group = bind_group_guard.remove(id);
|
||||
let bind_group = bind_group_guard.remove(id).unwrap();
|
||||
#[cfg(not(feature = "remote"))]
|
||||
hub.bind_groups.identity.lock().free(id);
|
||||
(
|
||||
@ -354,7 +353,7 @@ impl<B: GfxBackend> PendingResources<B> {
|
||||
let buf = &buffer_guard[resource_id];
|
||||
|
||||
let submit_index = buf.life_guard.submission_index.load(Ordering::Acquire);
|
||||
trace!(
|
||||
log::trace!(
|
||||
"Mapping of {:?} at submission {:?} gets assigned to active {:?}",
|
||||
resource_id,
|
||||
submit_index,
|
||||
@ -714,7 +713,7 @@ impl<B: GfxBackend> Device<B> {
|
||||
levels: 0 .. desc.mip_level_count as hal::image::Level,
|
||||
layers: 0 .. desc.array_layer_count as hal::image::Layer,
|
||||
},
|
||||
placement: resource::TexturePlacement::Memory(memory),
|
||||
memory,
|
||||
life_guard: LifeGuard::new(),
|
||||
}
|
||||
}
|
||||
@ -929,16 +928,17 @@ pub fn texture_create_view<B: GfxBackend>(
|
||||
};
|
||||
|
||||
let view = resource::TextureView {
|
||||
raw,
|
||||
texture_id: Stored {
|
||||
value: texture_id,
|
||||
ref_count: texture.life_guard.ref_count.clone(),
|
||||
inner: resource::TextureViewInner::Native {
|
||||
raw,
|
||||
source_id: Stored {
|
||||
value: texture_id,
|
||||
ref_count: texture.life_guard.ref_count.clone(),
|
||||
},
|
||||
},
|
||||
format: texture.format,
|
||||
extent: texture.kind.extent().at_level(range.levels.start),
|
||||
samples: texture.kind.num_samples(),
|
||||
range,
|
||||
is_owned_by_swap_chain: false,
|
||||
life_guard: LifeGuard::new(),
|
||||
};
|
||||
|
||||
@ -991,7 +991,12 @@ pub fn texture_view_destroy<B: GfxBackend>(texture_view_id: TextureViewId) {
|
||||
let (texture_guard, mut token) = hub.textures.read(&mut token);
|
||||
let (texture_view_guard, _) = hub.texture_views.read(&mut token);
|
||||
let view = &texture_view_guard[texture_view_id];
|
||||
let device_id = texture_guard[view.texture_id.value].device_id.value;
|
||||
let device_id = match view.inner {
|
||||
resource::TextureViewInner::Native { ref source_id, .. } =>
|
||||
texture_guard[source_id.value].device_id.value,
|
||||
resource::TextureViewInner::SwapChain { .. } =>
|
||||
panic!("Can't destroy a swap chain image"),
|
||||
};
|
||||
device_guard[device_id].pending.lock().destroy(
|
||||
ResourceId::TextureView(texture_view_id),
|
||||
view.life_guard.ref_count.clone(),
|
||||
@ -1248,17 +1253,23 @@ pub fn device_create_bind_group<B: GfxBackend>(
|
||||
.views
|
||||
.use_extend(&*texture_view_guard, id, (), ())
|
||||
.unwrap();
|
||||
let texture = used.textures
|
||||
.use_extend(
|
||||
&*texture_guard,
|
||||
view.texture_id.value,
|
||||
view.range.clone(),
|
||||
usage,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(texture.usage.contains(usage));
|
||||
match view.inner {
|
||||
resource::TextureViewInner::Native { ref raw, ref source_id } => {
|
||||
let texture = used.textures
|
||||
.use_extend(
|
||||
&*texture_guard,
|
||||
source_id.value,
|
||||
view.range.clone(),
|
||||
usage,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(texture.usage.contains(usage));
|
||||
|
||||
hal::pso::Descriptor::Image(&view.raw, image_layout)
|
||||
hal::pso::Descriptor::Image(raw, image_layout)
|
||||
}
|
||||
resource::TextureViewInner::SwapChain { .. } =>
|
||||
panic!("Unable to create a bind group with a swap chain image"),
|
||||
}
|
||||
}
|
||||
};
|
||||
writes.alloc().init(hal::pso::DescriptorSetWrite {
|
||||
@ -1409,117 +1420,108 @@ pub fn queue_submit<B: GfxBackend>(queue_id: QueueId, command_buffer_ids: &[Comm
|
||||
let (mut device_guard, mut token) = hub.devices.write(&mut token);
|
||||
let (swap_chain_guard, mut token) = hub.swap_chains.read(&mut token);
|
||||
let device = &mut device_guard[queue_id];
|
||||
|
||||
let mut trackers = device.trackers.lock();
|
||||
let mut wait_semaphores = Vec::new();
|
||||
let mut signal_semaphores = Vec::new();
|
||||
|
||||
let submit_index = 1 + device
|
||||
.life_guard
|
||||
.submission_index
|
||||
.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
let (mut command_buffer_guard, mut token) = hub.command_buffers.write(&mut token);
|
||||
let (bind_group_guard, mut token) = hub.bind_groups.read(&mut token);
|
||||
let (buffer_guard, mut token) = hub.buffers.read(&mut token);
|
||||
let (texture_guard, mut token) = hub.textures.read(&mut token);
|
||||
let (texture_view_guard, _) = hub.texture_views.read(&mut token);
|
||||
|
||||
//TODO: if multiple command buffers are submitted, we can re-use the last
|
||||
// native command buffer of the previous chain instead of always creating
|
||||
// a temporary one, since the chains are not finished.
|
||||
{
|
||||
let (mut command_buffer_guard, mut token) = hub.command_buffers.write(&mut token);
|
||||
let (bind_group_guard, mut token) = hub.bind_groups.read(&mut token);
|
||||
let (buffer_guard, mut token) = hub.buffers.read(&mut token);
|
||||
let (texture_guard, mut token) = hub.textures.read(&mut token);
|
||||
let (texture_view_guard, _) = hub.texture_views.read(&mut token);
|
||||
|
||||
// finish all the command buffers first
|
||||
for &cmb_id in command_buffer_ids {
|
||||
let comb = &mut command_buffer_guard[cmb_id];
|
||||
for link in comb.swap_chain_links.drain(..) {
|
||||
let swap_chain = &swap_chain_guard[link.swap_chain_id];
|
||||
let frame = &swap_chain.frames[link.image_index as usize];
|
||||
if frame.need_waiting.swap(false, Ordering::AcqRel) {
|
||||
assert_eq!(frame.acquired_epoch, Some(link.epoch),
|
||||
"{}. Image index {} with epoch {} != current epoch {:?}",
|
||||
"Attempting to render to a swapchain output that has already been presented",
|
||||
link.image_index, link.epoch, frame.acquired_epoch);
|
||||
wait_semaphores.push((
|
||||
&frame.sem_available,
|
||||
hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT,
|
||||
));
|
||||
}
|
||||
}
|
||||
// finish all the command buffers first
|
||||
for &cmb_id in command_buffer_ids {
|
||||
let comb = &mut command_buffer_guard[cmb_id];
|
||||
|
||||
// optimize the tracked states
|
||||
comb.trackers.optimize();
|
||||
if let Some(view_id) = comb.used_swap_chain_image.take() {
|
||||
let sem = match texture_view_guard[view_id.value].inner {
|
||||
resource::TextureViewInner::Native { .. } => unreachable!(),
|
||||
resource::TextureViewInner::SwapChain { ref source_id, .. } =>
|
||||
&swap_chain_guard[source_id.value].semaphore,
|
||||
};
|
||||
signal_semaphores.push(sem);
|
||||
}
|
||||
|
||||
// update submission IDs
|
||||
for id in comb.trackers.buffers.used() {
|
||||
let buffer = &buffer_guard[id];
|
||||
assert!(buffer.pending_map_operation.is_none());
|
||||
buffer
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(submit_index, Ordering::Release);
|
||||
}
|
||||
for id in comb.trackers.textures.used() {
|
||||
texture_guard[id]
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(submit_index, Ordering::Release);
|
||||
}
|
||||
for id in comb.trackers.views.used() {
|
||||
texture_view_guard[id]
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(submit_index, Ordering::Release);
|
||||
}
|
||||
for id in comb.trackers.bind_groups.used() {
|
||||
bind_group_guard[id]
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(submit_index, Ordering::Release);
|
||||
}
|
||||
// optimize the tracked states
|
||||
comb.trackers.optimize();
|
||||
|
||||
// execute resource transitions
|
||||
let mut transit = device.com_allocator.extend(comb);
|
||||
unsafe {
|
||||
transit.begin(
|
||||
hal::command::CommandBufferFlags::ONE_TIME_SUBMIT,
|
||||
hal::command::CommandBufferInheritanceInfo::default(),
|
||||
);
|
||||
}
|
||||
trace!("Stitching command buffer {:?} before submission", cmb_id);
|
||||
command::CommandBuffer::insert_barriers(
|
||||
&mut transit,
|
||||
&mut *trackers,
|
||||
&comb.trackers,
|
||||
Stitch::Init,
|
||||
&*buffer_guard,
|
||||
&*texture_guard,
|
||||
// update submission IDs
|
||||
for id in comb.trackers.buffers.used() {
|
||||
let buffer = &buffer_guard[id];
|
||||
assert!(buffer.pending_map_operation.is_none());
|
||||
buffer
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(submit_index, Ordering::Release);
|
||||
}
|
||||
for id in comb.trackers.textures.used() {
|
||||
texture_guard[id]
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(submit_index, Ordering::Release);
|
||||
}
|
||||
for id in comb.trackers.views.used() {
|
||||
texture_view_guard[id]
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(submit_index, Ordering::Release);
|
||||
}
|
||||
for id in comb.trackers.bind_groups.used() {
|
||||
bind_group_guard[id]
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(submit_index, Ordering::Release);
|
||||
}
|
||||
|
||||
// execute resource transitions
|
||||
let mut transit = device.com_allocator.extend(comb);
|
||||
unsafe {
|
||||
transit.begin(
|
||||
hal::command::CommandBufferFlags::ONE_TIME_SUBMIT,
|
||||
hal::command::CommandBufferInheritanceInfo::default(),
|
||||
);
|
||||
unsafe {
|
||||
transit.finish();
|
||||
}
|
||||
comb.raw.insert(0, transit);
|
||||
unsafe {
|
||||
comb.raw.last_mut().unwrap().finish();
|
||||
}
|
||||
}
|
||||
log::trace!("Stitching command buffer {:?} before submission", cmb_id);
|
||||
command::CommandBuffer::insert_barriers(
|
||||
&mut transit,
|
||||
&mut *trackers,
|
||||
&comb.trackers,
|
||||
Stitch::Init,
|
||||
&*buffer_guard,
|
||||
&*texture_guard,
|
||||
);
|
||||
unsafe {
|
||||
transit.finish();
|
||||
}
|
||||
comb.raw.insert(0, transit);
|
||||
unsafe {
|
||||
comb.raw.last_mut().unwrap().finish();
|
||||
}
|
||||
}
|
||||
|
||||
// now prepare the GPU submission
|
||||
let fence = device.raw.create_fence(false).unwrap();
|
||||
{
|
||||
let (command_buffer_guard, _) = hub.command_buffers.read(&mut token);
|
||||
let submission = hal::queue::Submission::<_, _, &[B::Semaphore]> {
|
||||
//TODO: may `OneShot` be enough?
|
||||
command_buffers: command_buffer_ids
|
||||
.iter()
|
||||
.flat_map(|&cmb_id| &command_buffer_guard[cmb_id].raw),
|
||||
wait_semaphores,
|
||||
signal_semaphores: &[], //TODO: signal `sem_present`?
|
||||
};
|
||||
let submission = hal::queue::Submission::<_, _, Vec<&B::Semaphore>> {
|
||||
command_buffers: command_buffer_ids
|
||||
.iter()
|
||||
.flat_map(|&cmb_id| &command_buffer_guard[cmb_id].raw),
|
||||
wait_semaphores: Vec::new(),
|
||||
signal_semaphores,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
device.queue_group.queues[0]
|
||||
.submit(submission, Some(&fence));
|
||||
}
|
||||
unsafe {
|
||||
device.queue_group.queues[0]
|
||||
.submit(submission, Some(&fence));
|
||||
}
|
||||
|
||||
(submit_index, fence)
|
||||
@ -1896,16 +1898,15 @@ pub fn device_create_swap_chain<B: GfxBackend>(
|
||||
device_id: DeviceId,
|
||||
surface_id: SurfaceId,
|
||||
desc: &swap_chain::SwapChainDescriptor,
|
||||
id_in: Input<SwapChainId>,
|
||||
image_ids: Vec<(Input<TextureId>, Input<TextureViewId>)>,
|
||||
) -> Output<SwapChainId> {
|
||||
info!("creating swap chain {:?}", desc);
|
||||
) -> SwapChainId {
|
||||
log::info!("creating swap chain {:?}", desc);
|
||||
let hub = B::hub();
|
||||
let mut token = Token::root();
|
||||
|
||||
let (mut surface_guard, mut token) = GLOBAL.surfaces.write(&mut token);
|
||||
let (adapter_guard, mut token) = hub.adapters.read(&mut token);
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let (mut swap_chain_guard, _) = hub.swap_chains.write(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
let surface = &mut surface_guard[surface_id];
|
||||
|
||||
@ -1926,159 +1927,41 @@ pub fn device_create_swap_chain<B: GfxBackend>(
|
||||
formats
|
||||
);
|
||||
}
|
||||
//TODO: properly exclusive range
|
||||
/* TODO: this is way too restrictive
|
||||
assert!(desc.width >= caps.extents.start.width && desc.width <= caps.extents.end.width &&
|
||||
desc.height >= caps.extents.start.height && desc.height <= caps.extents.end.height,
|
||||
"Requested size {}x{} is outside of the supported range: {:?}",
|
||||
desc.width, desc.height, caps.extents);
|
||||
*/
|
||||
if desc.width < caps.extents.start().width ||
|
||||
desc.width > caps.extents.end().width ||
|
||||
desc.height < caps.extents.start().height ||
|
||||
desc.height > caps.extents.end().height
|
||||
{
|
||||
log::warn!("Requested size {}x{} is outside of the supported range: {:?}",
|
||||
desc.width, desc.height, caps.extents);
|
||||
}
|
||||
|
||||
let (old_raw, sem_available, command_pool) = match surface.swap_chain.take() {
|
||||
Some(old_id) => {
|
||||
//TODO: remove this once gfx-rs stops destroying the old swapchain
|
||||
device.raw.wait_idle().unwrap();
|
||||
let mut pending = device.pending.lock();
|
||||
let hal_desc = desc.to_hal(num_frames);
|
||||
unsafe {
|
||||
B::get_surface_mut(surface)
|
||||
.configure_swapchain(&device.raw, hal_desc)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let (mut old, _) = hub.swap_chains.unregister(old_id, &mut token);
|
||||
assert_eq!(old.device_id.value, device_id);
|
||||
for frame in old.frames {
|
||||
pending.destroy(
|
||||
ResourceId::Texture(frame.texture_id.value),
|
||||
frame.texture_id.ref_count,
|
||||
);
|
||||
pending.destroy(
|
||||
ResourceId::TextureView(frame.view_id.value),
|
||||
frame.view_id.ref_count,
|
||||
);
|
||||
}
|
||||
unsafe { old.command_pool.reset(false) };
|
||||
(old.raw, old.sem_available, old.command_pool)
|
||||
let sc_id = surface_id.to_swap_chain_id(B::VARIANT);
|
||||
if let Some(sc) = swap_chain_guard.remove(sc_id) {
|
||||
unsafe {
|
||||
device.raw.destroy_semaphore(sc.semaphore);
|
||||
}
|
||||
None => unsafe {
|
||||
let sem_available = device.raw.create_semaphore().unwrap();
|
||||
let command_pool = device
|
||||
.raw
|
||||
.create_command_pool(
|
||||
device.queue_group.family,
|
||||
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
|
||||
)
|
||||
.unwrap();
|
||||
(None, sem_available, command_pool)
|
||||
},
|
||||
};
|
||||
|
||||
let (raw_swap_chain, images) = unsafe {
|
||||
let suf = B::get_surface_mut(surface);
|
||||
device
|
||||
.raw
|
||||
.create_swapchain(suf, config, old_raw)
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let (id, id_out) = hub.swap_chains.new_identity(id_in);
|
||||
surface.swap_chain = Some(id);
|
||||
|
||||
let mut trackers = device.trackers.lock();
|
||||
let mut swap_chain = swap_chain::SwapChain::<B> {
|
||||
raw: Some(raw_swap_chain),
|
||||
surface_id: Stored {
|
||||
value: surface_id,
|
||||
ref_count: surface.ref_count.clone(),
|
||||
},
|
||||
}
|
||||
let swap_chain = swap_chain::SwapChain {
|
||||
life_guard: LifeGuard::new(),
|
||||
device_id: Stored {
|
||||
value: device_id,
|
||||
ref_count: device.life_guard.ref_count.clone(),
|
||||
},
|
||||
desc: desc.clone(),
|
||||
frames: Vec::with_capacity(num_frames as usize),
|
||||
acquired: Vec::with_capacity(1), //TODO: get it from gfx-hal?
|
||||
sem_available,
|
||||
command_pool,
|
||||
num_frames,
|
||||
acquired_view_id: None,
|
||||
semaphore: device.raw.create_semaphore().unwrap(),
|
||||
};
|
||||
|
||||
for ((i, image), (id_texture_in, id_view_in)) in images.into_iter().enumerate().zip(image_ids) {
|
||||
let kind = hal::image::Kind::D2(desc.width, desc.height, 1, 1);
|
||||
let range = hal::image::SubresourceRange {
|
||||
aspects: hal::format::Aspects::COLOR,
|
||||
levels: 0 .. 1,
|
||||
layers: 0 .. 1,
|
||||
};
|
||||
|
||||
let view_raw = unsafe {
|
||||
device
|
||||
.raw
|
||||
.create_image_view(
|
||||
&image,
|
||||
hal::image::ViewKind::D2,
|
||||
conv::map_texture_format(desc.format),
|
||||
hal::format::Swizzle::NO,
|
||||
range.clone(),
|
||||
)
|
||||
.unwrap()
|
||||
};
|
||||
let texture = resource::Texture {
|
||||
raw: image,
|
||||
device_id: Stored {
|
||||
value: device_id,
|
||||
ref_count: device.life_guard.ref_count.clone(),
|
||||
},
|
||||
usage: resource::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
kind,
|
||||
format: desc.format,
|
||||
full_range: range.clone(),
|
||||
placement: resource::TexturePlacement::SwapChain(swap_chain::SwapChainLink {
|
||||
swap_chain_id: id, //TODO: strongly
|
||||
epoch: Mutex::new(0),
|
||||
image_index: i as hal::window::SwapImageIndex,
|
||||
}),
|
||||
life_guard: LifeGuard::new(),
|
||||
};
|
||||
let (id_texture, _) = hub.textures.new_identity(id_texture_in);
|
||||
let texture_id = Stored {
|
||||
ref_count: texture.life_guard.ref_count.clone(),
|
||||
value: id_texture,
|
||||
};
|
||||
trackers.textures.init(
|
||||
id_texture,
|
||||
&texture_id.ref_count,
|
||||
range.clone(),
|
||||
resource::TextureUsage::UNINITIALIZED,
|
||||
);
|
||||
hub.textures.register(id_texture, texture, &mut token);
|
||||
|
||||
let view = resource::TextureView {
|
||||
raw: view_raw,
|
||||
texture_id: texture_id.clone(),
|
||||
format: desc.format,
|
||||
extent: kind.extent(),
|
||||
samples: kind.num_samples(),
|
||||
range,
|
||||
is_owned_by_swap_chain: true,
|
||||
life_guard: LifeGuard::new(),
|
||||
};
|
||||
let (id_view, _) = hub.texture_views.new_identity(id_view_in);
|
||||
let view_id = Stored {
|
||||
ref_count: view.life_guard.ref_count.clone(),
|
||||
value: id_view,
|
||||
};
|
||||
trackers.views.init(id_view, &view_id.ref_count, (), ());
|
||||
hub.texture_views.register(id_view, view, &mut token);
|
||||
|
||||
swap_chain.frames.alloc().init(swap_chain::Frame {
|
||||
texture_id,
|
||||
view_id,
|
||||
fence: device.raw.create_fence(true).unwrap(),
|
||||
sem_available: device.raw.create_semaphore().unwrap(),
|
||||
sem_present: device.raw.create_semaphore().unwrap(),
|
||||
acquired_epoch: None,
|
||||
need_waiting: AtomicBool::new(false),
|
||||
comb: swap_chain.command_pool.allocate_one(hal::command::Level::Primary),
|
||||
});
|
||||
}
|
||||
|
||||
hub.swap_chains.register(id, swap_chain, &mut token);
|
||||
id_out
|
||||
swap_chain_guard.insert(sc_id, swap_chain);
|
||||
sc_id
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "remote"))]
|
||||
@ -2088,8 +1971,7 @@ pub extern "C" fn wgpu_device_create_swap_chain(
|
||||
surface_id: SurfaceId,
|
||||
desc: &swap_chain::SwapChainDescriptor,
|
||||
) -> SwapChainId {
|
||||
let image_ids = vec![(PhantomData, PhantomData); 10]; //TODO: make this compatible with "remote"
|
||||
gfx_select!(device_id => device_create_swap_chain(device_id, surface_id, desc, PhantomData, image_ids))
|
||||
gfx_select!(device_id => device_create_swap_chain(device_id, surface_id, desc))
|
||||
}
|
||||
|
||||
pub fn device_poll<B: GfxBackend>(device_id: DeviceId, force_wait: bool) {
|
||||
|
@ -135,11 +135,19 @@ impl<T, I: TypedId> Storage<T, I> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, id: I) -> T {
|
||||
pub fn insert(&mut self, id: I, value: T) -> Option<T> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
let (value, storage_epoch) = self.map.remove(index as usize).unwrap();
|
||||
assert_eq!(epoch, storage_epoch);
|
||||
value
|
||||
let old = self.map.insert(index as usize, (value, epoch));
|
||||
old.map(|(v, _storage_epoch)| v)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, id: I) -> Option<T> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
self.map.remove(index as usize)
|
||||
.map(|(value, storage_epoch)| {
|
||||
assert_eq!(epoch, storage_epoch);
|
||||
value
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,9 +208,9 @@ impl<B: hal::Backend> Access<Buffer<B>> for RenderPass<B> {}
|
||||
impl<B: hal::Backend> Access<Buffer<B>> for RenderPipeline<B> {}
|
||||
impl<B: hal::Backend> Access<Texture<B>> for Root {}
|
||||
impl<B: hal::Backend> Access<Texture<B>> for Device<B> {}
|
||||
impl<B: hal::Backend> Access<Texture<B>> for SwapChain<B> {}
|
||||
impl<B: hal::Backend> Access<Texture<B>> for Buffer<B> {}
|
||||
impl<B: hal::Backend> Access<TextureView<B>> for Root {}
|
||||
impl<B: hal::Backend> Access<TextureView<B>> for SwapChain<B> {}
|
||||
impl<B: hal::Backend> Access<TextureView<B>> for Device<B> {}
|
||||
impl<B: hal::Backend> Access<TextureView<B>> for Texture<B> {}
|
||||
impl<B: hal::Backend> Access<Sampler<B>> for Root {}
|
||||
@ -281,9 +289,8 @@ impl<T, I: TypedId> Registry<T, I> {
|
||||
|
||||
impl<T, I: TypedId + Copy> Registry<T, I> {
|
||||
pub fn register<A: Access<T>>(&self, id: I, value: T, _token: &mut Token<A>) {
|
||||
let (index, epoch, backend) = id.unzip();
|
||||
debug_assert_eq!(backend, self.backend);
|
||||
let old = self.data.write().map.insert(index as usize, (value, epoch));
|
||||
debug_assert_eq!(id.unzip().2, self.backend);
|
||||
let old = self.data.write().insert(id, value);
|
||||
assert!(old.is_none());
|
||||
}
|
||||
|
||||
@ -311,7 +318,7 @@ impl<T, I: TypedId + Copy> Registry<T, I> {
|
||||
}
|
||||
|
||||
pub fn unregister<A: Access<T>>(&self, id: I, _token: &mut Token<A>) -> (T, Token<T>) {
|
||||
let value = self.data.write().remove(id);
|
||||
let value = self.data.write().remove(id).unwrap();
|
||||
//Note: careful about the order here!
|
||||
#[cfg(not(feature = "remote"))]
|
||||
self.identity.lock().free(id);
|
||||
|
@ -35,7 +35,7 @@ impl<T> Clone for Id<T> {
|
||||
|
||||
impl<T> fmt::Debug for Id<T> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(formatter)
|
||||
self.unzip().fmt(formatter)
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,6 +109,19 @@ pub type ComputePassId = Id<crate::ComputePass<Dummy>>;
|
||||
pub type SurfaceId = Id<crate::Surface>;
|
||||
pub type SwapChainId = Id<crate::SwapChain<Dummy>>;
|
||||
|
||||
impl SurfaceId {
|
||||
pub(crate) fn to_swap_chain_id(&self, backend: Backend) -> SwapChainId {
|
||||
let (index, epoch, _) = self.unzip();
|
||||
Id::zip(index, epoch, backend)
|
||||
}
|
||||
}
|
||||
impl SwapChainId {
|
||||
pub(crate) fn to_surface_id(&self) -> SurfaceId {
|
||||
let (index, epoch, _) = self.unzip();
|
||||
Id::zip(index, epoch, Backend::Empty)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_id_backend() {
|
||||
for &b in &[
|
||||
|
@ -8,11 +8,9 @@ use crate::{
|
||||
Backend,
|
||||
Device,
|
||||
DeviceId,
|
||||
RefCount,
|
||||
SwapChainId,
|
||||
};
|
||||
#[cfg(not(feature = "remote"))]
|
||||
use crate::{gfx_select, LifeGuard, SurfaceId};
|
||||
use crate::{gfx_select, SurfaceId};
|
||||
|
||||
#[cfg(not(feature = "remote"))]
|
||||
use bitflags::bitflags;
|
||||
@ -61,8 +59,6 @@ type GfxSurface<B> = <B as hal::Backend>::Surface;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Surface {
|
||||
pub(crate) swap_chain: Option<SwapChainId>,
|
||||
pub(crate) ref_count: RefCount,
|
||||
#[cfg(any(not(any(target_os = "ios", target_os = "macos")), feature = "gfx-backend-vulkan"))]
|
||||
pub(crate) vulkan: Option<GfxSurface<backend::Vulkan>>,
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
@ -163,12 +159,9 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
|
||||
use raw_window_handle::RawWindowHandle as Rwh;
|
||||
|
||||
let instance = &GLOBAL.instance;
|
||||
let ref_count = LifeGuard::new().ref_count;
|
||||
let surface = match raw_handle {
|
||||
#[cfg(target_os = "ios")]
|
||||
Rwh::IOS(h) => Surface {
|
||||
swap_chain: None,
|
||||
ref_count,
|
||||
#[cfg(feature = "gfx-backend-vulkan")]
|
||||
vulkan: None,
|
||||
metal: instance
|
||||
@ -177,8 +170,6 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
|
||||
},
|
||||
#[cfg(target_os = "macos")]
|
||||
Rwh::MacOS(h) => Surface {
|
||||
swap_chain: None,
|
||||
ref_count,
|
||||
#[cfg(feature = "gfx-backend-vulkan")]
|
||||
vulkan: instance
|
||||
.vulkan
|
||||
@ -190,8 +181,6 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
|
||||
},
|
||||
#[cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))]
|
||||
Rwh::X11(h) => Surface {
|
||||
swap_chain: None,
|
||||
ref_count,
|
||||
vulkan: instance
|
||||
.vulkan
|
||||
.as_ref()
|
||||
@ -199,8 +188,6 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
|
||||
},
|
||||
#[cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))]
|
||||
Rwh::Wayland(h) => Surface {
|
||||
swap_chain: None,
|
||||
ref_count,
|
||||
vulkan: instance
|
||||
.vulkan
|
||||
.as_ref()
|
||||
@ -208,8 +195,6 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
|
||||
},
|
||||
#[cfg(windows)]
|
||||
Rwh::Windows(h) => Surface {
|
||||
swap_chain: None,
|
||||
ref_count,
|
||||
vulkan: instance
|
||||
.vulkan
|
||||
.as_ref()
|
||||
@ -247,8 +232,6 @@ pub extern "C" fn wgpu_create_surface_from_xlib(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_create_surface_from_metal_layer(layer: *mut std::ffi::c_void) -> SurfaceId {
|
||||
let surface = Surface {
|
||||
swap_chain: None,
|
||||
ref_count: LifeGuard::new().ref_count,
|
||||
#[cfg(feature = "gfx-backend-vulkan")]
|
||||
vulkan: None, //TODO: currently requires `NSView`
|
||||
metal: GLOBAL
|
||||
|
@ -1,5 +1,4 @@
|
||||
use crate::{
|
||||
swap_chain::{SwapChainLink, SwapImageEpoch},
|
||||
BufferAddress,
|
||||
BufferMapReadCallback,
|
||||
BufferMapWriteCallback,
|
||||
@ -8,12 +7,12 @@ use crate::{
|
||||
LifeGuard,
|
||||
RefCount,
|
||||
Stored,
|
||||
SwapChainId,
|
||||
TextureId,
|
||||
};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use hal;
|
||||
use parking_lot::Mutex;
|
||||
use rendy_memory::MemoryBlock;
|
||||
|
||||
use std::borrow::Borrow;
|
||||
@ -207,22 +206,6 @@ pub struct TextureDescriptor {
|
||||
pub usage: TextureUsage,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum TexturePlacement<B: hal::Backend> {
|
||||
#[cfg_attr(not(not(feature = "remote")), allow(unused))]
|
||||
SwapChain(SwapChainLink<Mutex<SwapImageEpoch>>),
|
||||
Memory(MemoryBlock<B>),
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> TexturePlacement<B> {
|
||||
pub fn as_swap_chain(&self) -> &SwapChainLink<Mutex<SwapImageEpoch>> {
|
||||
match *self {
|
||||
TexturePlacement::SwapChain(ref link) => link,
|
||||
TexturePlacement::Memory(_) => panic!("Expected swap chain link!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Texture<B: hal::Backend> {
|
||||
pub(crate) raw: B::Image,
|
||||
@ -231,7 +214,7 @@ pub struct Texture<B: hal::Backend> {
|
||||
pub(crate) kind: hal::image::Kind,
|
||||
pub(crate) format: TextureFormat,
|
||||
pub(crate) full_range: hal::image::SubresourceRange,
|
||||
pub(crate) placement: TexturePlacement<B>,
|
||||
pub(crate) memory: MemoryBlock<B>,
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
}
|
||||
|
||||
@ -278,17 +261,27 @@ pub struct TextureViewDescriptor {
|
||||
pub array_layer_count: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum TextureViewInner<B: hal::Backend> {
|
||||
Native {
|
||||
raw: B::ImageView,
|
||||
source_id: Stored<TextureId>,
|
||||
},
|
||||
SwapChain {
|
||||
image: <B::Surface as hal::window::PresentationSurface<B>>::SwapchainImage,
|
||||
source_id: Stored<SwapChainId>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TextureView<B: hal::Backend> {
|
||||
pub(crate) raw: B::ImageView,
|
||||
pub(crate) texture_id: Stored<TextureId>,
|
||||
pub(crate) inner: TextureViewInner<B>,
|
||||
//TODO: store device_id for quick access?
|
||||
pub(crate) format: TextureFormat,
|
||||
pub(crate) extent: hal::image::Extent,
|
||||
pub(crate) samples: hal::image::NumSamples,
|
||||
pub(crate) range: hal::image::SubresourceRange,
|
||||
pub(crate) is_owned_by_swap_chain: bool,
|
||||
#[cfg_attr(not(not(feature = "remote")), allow(dead_code))]
|
||||
#[cfg_attr(feature = "remote", allow(dead_code))]
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
}
|
||||
|
||||
|
@ -1,81 +1,66 @@
|
||||
/*! Swap chain management.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
At the low level, the swap chain is using the new simplified model of gfx-rs.
|
||||
|
||||
A swap chain is a separate object that is backend-dependent but shares the index with
|
||||
the parent surface, which is backend-independent. This ensures a 1:1 correspondence
|
||||
between them.
|
||||
|
||||
`get_next_image()` requests a new image from the surface. It becomes a part of
|
||||
`TextureViewInner::SwapChain` of the resulted view. The view is registered in the HUB
|
||||
but not in the device tracker.
|
||||
|
||||
The only operation allowed on the view is to be either a color or a resolve attachment.
|
||||
It can only be used in one command buffer, which needs to be submitted before presenting.
|
||||
Command buffer tracker knows about the view, but only for the duration of recording.
|
||||
The view ID is erased from it at the end, so that it's not merged into the device tracker.
|
||||
|
||||
When a swapchain view is used in `begin_render_pass()`, we assume the start and end image
|
||||
layouts purely based on whether or not this view was used in this command buffer before.
|
||||
It always starts with `Uninitialized` and ends with `Present`, so that no barriers are
|
||||
needed when we need to actually present it.
|
||||
|
||||
In `queue_submit()` we make sure to signal the semaphore whenever we render to a swap
|
||||
chain view.
|
||||
|
||||
In `present()` we return the swap chain image back and wait on the semaphore.
|
||||
!*/
|
||||
|
||||
use crate::{
|
||||
conv,
|
||||
device::all_image_stages,
|
||||
gfx_select,
|
||||
hub::{GfxBackend, Token},
|
||||
hub::{GLOBAL, GfxBackend, Token},
|
||||
resource,
|
||||
DeviceId,
|
||||
Extent3d,
|
||||
Input,
|
||||
LifeGuard,
|
||||
Stored,
|
||||
SwapChainId,
|
||||
SurfaceId,
|
||||
TextureId,
|
||||
TextureViewId,
|
||||
};
|
||||
#[cfg(not(feature = "remote"))]
|
||||
use crate::hub::GLOBAL;
|
||||
|
||||
use hal::{
|
||||
self,
|
||||
command::CommandBuffer as _,
|
||||
device::Device as _,
|
||||
queue::CommandQueue as _,
|
||||
window::Swapchain as _,
|
||||
};
|
||||
use log::{trace, warn};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use std::{
|
||||
iter,
|
||||
mem,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
window::PresentationSurface as _,
|
||||
};
|
||||
|
||||
pub type SwapImageEpoch = u64;
|
||||
#[cfg(not(feature = "remote"))]
|
||||
use std::marker::PhantomData;
|
||||
|
||||
const FRAME_TIMEOUT_MS: u64 = 1000;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct SwapChainLink<E> {
|
||||
pub swap_chain_id: SwapChainId, //TODO: strongly
|
||||
pub epoch: E,
|
||||
pub image_index: hal::window::SwapImageIndex,
|
||||
}
|
||||
|
||||
impl SwapChainLink<Mutex<SwapImageEpoch>> {
|
||||
pub fn bump_epoch(&self) -> SwapImageEpoch {
|
||||
let mut epoch = self.epoch.lock();
|
||||
*epoch += 1;
|
||||
*epoch
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Frame<B: hal::Backend> {
|
||||
pub texture_id: Stored<TextureId>,
|
||||
pub view_id: Stored<TextureViewId>,
|
||||
pub fence: B::Fence,
|
||||
pub sem_available: B::Semaphore,
|
||||
pub sem_present: B::Semaphore,
|
||||
pub acquired_epoch: Option<SwapImageEpoch>,
|
||||
pub need_waiting: AtomicBool,
|
||||
pub comb: B::CommandBuffer,
|
||||
}
|
||||
|
||||
//TODO: does it need a ref-counted lifetime?
|
||||
#[derive(Debug)]
|
||||
pub struct SwapChain<B: hal::Backend> {
|
||||
//Note: it's only an option because we may need to move it out
|
||||
// and then put a new swapchain back in.
|
||||
pub(crate) raw: Option<B::Swapchain>,
|
||||
pub(crate) surface_id: Stored<SurfaceId>,
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
pub(crate) device_id: Stored<DeviceId>,
|
||||
pub(crate) desc: SwapChainDescriptor,
|
||||
pub(crate) frames: Vec<Frame<B>>,
|
||||
pub(crate) acquired: Vec<hal::window::SwapImageIndex>,
|
||||
pub(crate) sem_available: B::Semaphore,
|
||||
#[cfg_attr(feature = "remote", allow(dead_code))] //TODO: remove
|
||||
pub(crate) command_pool: B::CommandPool,
|
||||
pub(crate) num_frames: hal::window::SwapImageIndex,
|
||||
pub(crate) acquired_view_id: Option<Stored<TextureViewId>>,
|
||||
pub(crate) semaphore: B::Semaphore,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -133,221 +118,119 @@ impl SwapChainDescriptor {
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct SwapChainOutput {
|
||||
pub texture_id: TextureId,
|
||||
pub view_id: TextureViewId,
|
||||
}
|
||||
|
||||
pub fn swap_chain_get_next_texture<B: GfxBackend>(
|
||||
swap_chain_id: SwapChainId
|
||||
swap_chain_id: SwapChainId,
|
||||
view_id_in: Input<TextureViewId>,
|
||||
) -> SwapChainOutput {
|
||||
let hub = B::hub();
|
||||
let mut token = Token::root();
|
||||
|
||||
#[cfg(not(feature = "remote"))]
|
||||
let (mut surface_guard, mut token) = GLOBAL.surfaces.write(&mut token);
|
||||
let surface = &mut surface_guard[swap_chain_id.to_surface_id()];
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let (mut swap_chain_guard, _) = hub.swap_chains.write(&mut token);
|
||||
let swap_chain = &mut swap_chain_guard[swap_chain_id];
|
||||
let device = &device_guard[swap_chain.device_id.value];
|
||||
let (mut swap_chain_guard, mut token) = hub.swap_chains.write(&mut token);
|
||||
let sc = &mut swap_chain_guard[swap_chain_id];
|
||||
let device = &device_guard[sc.device_id.value];
|
||||
|
||||
let image_index = unsafe {
|
||||
swap_chain
|
||||
.raw
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.acquire_image(!0, Some(&swap_chain.sem_available), None)
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "remote"))]
|
||||
{
|
||||
if image_index.is_err() {
|
||||
warn!("acquire_image failed, re-creating");
|
||||
//TODO: remove this once gfx-rs stops destroying the old swapchain
|
||||
device.raw.wait_idle().unwrap();
|
||||
let (mut texture_guard, mut token) = hub.textures.write(&mut token);
|
||||
let (mut texture_view_guard, _) = hub.texture_views.write(&mut token);
|
||||
let mut trackers = device.trackers.lock();
|
||||
|
||||
let old_raw = swap_chain.raw.take();
|
||||
let config = swap_chain.desc.to_hal(swap_chain.frames.len() as u32);
|
||||
let surface = &mut surface_guard[swap_chain.surface_id.value];
|
||||
|
||||
let (raw, images) = unsafe {
|
||||
let suf = B::get_surface_mut(surface);
|
||||
device
|
||||
.raw
|
||||
.create_swapchain(suf, config, old_raw)
|
||||
.unwrap()
|
||||
};
|
||||
swap_chain.raw = Some(raw);
|
||||
for (frame, image) in swap_chain.frames.iter_mut().zip(images) {
|
||||
let texture = &mut texture_guard[frame.texture_id.value];
|
||||
let view_raw = unsafe {
|
||||
device
|
||||
.raw
|
||||
.create_image_view(
|
||||
&image,
|
||||
hal::image::ViewKind::D2,
|
||||
conv::map_texture_format(texture.format),
|
||||
hal::format::Swizzle::NO,
|
||||
texture.full_range.clone(),
|
||||
)
|
||||
.unwrap()
|
||||
};
|
||||
texture.raw = image;
|
||||
trackers.textures.reset(
|
||||
frame.texture_id.value,
|
||||
texture.full_range.clone(),
|
||||
resource::TextureUsage::UNINITIALIZED,
|
||||
);
|
||||
let old_view = mem::replace(&mut texture_view_guard[frame.view_id.value].raw, view_raw);
|
||||
let (image, _) = {
|
||||
let suf = B::get_surface_mut(surface);
|
||||
match unsafe { suf.acquire_image(FRAME_TIMEOUT_MS * 1_000_000) } {
|
||||
Ok(surface_image) => surface_image,
|
||||
Err(hal::window::AcquireError::Timeout) => {
|
||||
panic!("GPU took too much time processing last frames :(");
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("acquire_image() failed ({:?}), reconfiguring swapchain", e);
|
||||
let desc = sc.desc.to_hal(sc.num_frames);
|
||||
unsafe {
|
||||
device.raw.destroy_image_view(old_view);
|
||||
suf
|
||||
.configure_swapchain(&device.raw, desc)
|
||||
.unwrap();
|
||||
suf
|
||||
.acquire_image(FRAME_TIMEOUT_MS * 1_000_000)
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let image_index = match image_index {
|
||||
Ok((index, suboptimal)) => {
|
||||
if suboptimal.is_some() {
|
||||
warn!("acquire_image: sub-optimal");
|
||||
}
|
||||
index
|
||||
}
|
||||
Err(_) => unsafe {
|
||||
swap_chain
|
||||
.raw
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.acquire_image(!0, Some(&swap_chain.sem_available), None)
|
||||
.unwrap()
|
||||
.0
|
||||
let view = resource::TextureView {
|
||||
inner: resource::TextureViewInner::SwapChain {
|
||||
image,
|
||||
source_id: Stored {
|
||||
value: swap_chain_id,
|
||||
ref_count: sc.life_guard.ref_count.clone(),
|
||||
},
|
||||
},
|
||||
format: sc.desc.format,
|
||||
extent: hal::image::Extent {
|
||||
width: sc.desc.width,
|
||||
height: sc.desc.height,
|
||||
depth: 1,
|
||||
},
|
||||
samples: 1,
|
||||
range: hal::image::SubresourceRange {
|
||||
aspects: hal::format::Aspects::COLOR,
|
||||
layers: 0 .. 1,
|
||||
levels: 0 .. 1,
|
||||
},
|
||||
life_guard: LifeGuard::new(),
|
||||
};
|
||||
let ref_count = view.life_guard.ref_count.clone();
|
||||
let (view_id, _) = hub.texture_views.new_identity(view_id_in);
|
||||
hub.texture_views.register(view_id, view, &mut token);
|
||||
|
||||
assert_ne!(
|
||||
swap_chain.acquired.len(),
|
||||
swap_chain.acquired.capacity(),
|
||||
"Unable to acquire any more swap chain images before presenting"
|
||||
);
|
||||
swap_chain.acquired.push(image_index);
|
||||
|
||||
let frame = &mut swap_chain.frames[image_index as usize];
|
||||
let status = unsafe {
|
||||
device
|
||||
.raw
|
||||
.wait_for_fence(&frame.fence, FRAME_TIMEOUT_MS * 1_000_000)
|
||||
};
|
||||
assert_eq!(
|
||||
status,
|
||||
Ok(true),
|
||||
"GPU got stuck on a frame (image {}) :(",
|
||||
image_index
|
||||
);
|
||||
mem::swap(&mut frame.sem_available, &mut swap_chain.sem_available);
|
||||
frame.need_waiting.store(true, Ordering::Release);
|
||||
|
||||
let (texture_guard, _) = hub.textures.read(&mut token);
|
||||
let frame_epoch = texture_guard[frame.texture_id.value]
|
||||
.placement
|
||||
.as_swap_chain()
|
||||
.bump_epoch();
|
||||
|
||||
assert_eq!(
|
||||
frame.acquired_epoch, None,
|
||||
"Last swapchain output hasn't been presented"
|
||||
);
|
||||
frame.acquired_epoch = Some(frame_epoch);
|
||||
assert!(sc.acquired_view_id.is_none(), "Swap chain image is already acquired");
|
||||
sc.acquired_view_id = Some(Stored {
|
||||
value: view_id,
|
||||
ref_count,
|
||||
});
|
||||
|
||||
SwapChainOutput {
|
||||
texture_id: frame.texture_id.value,
|
||||
view_id: frame.view_id.value,
|
||||
view_id,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "remote"))]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_swap_chain_get_next_texture(swap_chain_id: SwapChainId) -> SwapChainOutput {
|
||||
gfx_select!(swap_chain_id => swap_chain_get_next_texture(swap_chain_id))
|
||||
gfx_select!(swap_chain_id => swap_chain_get_next_texture(swap_chain_id, PhantomData))
|
||||
}
|
||||
|
||||
pub fn swap_chain_present<B: GfxBackend>(swap_chain_id: SwapChainId) {
|
||||
let hub = B::hub();
|
||||
let mut token = Token::root();
|
||||
|
||||
let (mut surface_guard, mut token) = GLOBAL.surfaces.write(&mut token);
|
||||
let surface = &mut surface_guard[swap_chain_id.to_surface_id()];
|
||||
let (mut device_guard, mut token) = hub.devices.write(&mut token);
|
||||
let (mut swap_chain_guard, mut token) = hub.swap_chains.write(&mut token);
|
||||
let swap_chain = &mut swap_chain_guard[swap_chain_id];
|
||||
let device = &mut device_guard[swap_chain.device_id.value];
|
||||
let sc = &mut swap_chain_guard[swap_chain_id];
|
||||
let device = &mut device_guard[sc.device_id.value];
|
||||
|
||||
let image_index = swap_chain.acquired.remove(0);
|
||||
let frame = &mut swap_chain.frames[image_index as usize];
|
||||
let epoch = frame.acquired_epoch.take();
|
||||
assert!(
|
||||
epoch.is_some(),
|
||||
"Presented frame (image {}) was not acquired",
|
||||
image_index
|
||||
);
|
||||
assert!(
|
||||
!frame.need_waiting.load(Ordering::Acquire),
|
||||
"No rendering work has been submitted for the presented frame (image {})",
|
||||
image_index
|
||||
);
|
||||
|
||||
let (texture_guard, _) = hub.textures.read(&mut token);
|
||||
let texture = &texture_guard[frame.texture_id.value];
|
||||
texture.placement.as_swap_chain().bump_epoch();
|
||||
|
||||
//TODO: support for swapchain being sampled or read by the shader?
|
||||
|
||||
trace!("transit {:?} to present", frame.texture_id.value);
|
||||
let mut trackers = device.trackers.lock();
|
||||
let barriers = trackers
|
||||
.textures
|
||||
.change_replace(
|
||||
frame.texture_id.value,
|
||||
&texture.life_guard.ref_count,
|
||||
texture.full_range.clone(),
|
||||
resource::TextureUsage::UNINITIALIZED,
|
||||
)
|
||||
.map(|pending| hal::memory::Barrier::Image {
|
||||
states: conv::map_texture_state(pending.usage.start, hal::format::Aspects::COLOR)
|
||||
.. (
|
||||
hal::image::Access::COLOR_ATTACHMENT_WRITE,
|
||||
hal::image::Layout::Present,
|
||||
),
|
||||
target: &texture.raw,
|
||||
families: None,
|
||||
range: pending.selector,
|
||||
});
|
||||
let view_id = sc.acquired_view_id
|
||||
.take()
|
||||
.expect("Swap chain image is not acquired");
|
||||
let (view, _) = hub.texture_views.unregister(view_id.value, &mut token);
|
||||
let image = match view.inner {
|
||||
resource::TextureViewInner::Native { .. } => unreachable!(),
|
||||
resource::TextureViewInner::SwapChain { image, .. } => image,
|
||||
};
|
||||
|
||||
let err = unsafe {
|
||||
frame.comb.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT);
|
||||
frame.comb.pipeline_barrier(
|
||||
all_image_stages() .. hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT,
|
||||
hal::memory::Dependencies::empty(),
|
||||
barriers,
|
||||
);
|
||||
frame.comb.finish();
|
||||
|
||||
// now prepare the GPU submission
|
||||
let submission = hal::queue::Submission {
|
||||
command_buffers: iter::once(&frame.comb),
|
||||
wait_semaphores: None,
|
||||
signal_semaphores: Some(&frame.sem_present),
|
||||
};
|
||||
|
||||
device.raw.reset_fence(&frame.fence).unwrap();
|
||||
let queue = &mut device.queue_group.queues[0];
|
||||
queue.submit(submission, Some(&frame.fence));
|
||||
queue.present(
|
||||
iter::once((swap_chain.raw.as_ref().unwrap(), image_index)),
|
||||
iter::once(&frame.sem_present),
|
||||
queue.present_surface(
|
||||
B::get_surface_mut(surface),
|
||||
image,
|
||||
Some(&sc.semaphore),
|
||||
)
|
||||
};
|
||||
|
||||
if let Err(e) = err {
|
||||
warn!("present failed: {:?}", e);
|
||||
log::warn!("present failed: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,27 +223,6 @@ impl<S: ResourceState> ResourceTracker<S> {
|
||||
.is_none()
|
||||
}
|
||||
|
||||
/// Resets a resource to the specified usage.
|
||||
#[cfg(not(feature = "remote"))]
|
||||
pub fn reset(
|
||||
&mut self,
|
||||
id: S::Id,
|
||||
selector: S::Selector,
|
||||
default: S::Usage,
|
||||
) {
|
||||
let mut state = S::default();
|
||||
match state.change(id, selector, default, None) {
|
||||
Ok(()) => (),
|
||||
Err(_) => unreachable!(),
|
||||
}
|
||||
|
||||
let (index, epoch, backend) = id.unzip();
|
||||
debug_assert_eq!(backend, self.backend);
|
||||
let res = self.map.get_mut(&index).unwrap();
|
||||
assert_eq!(res.epoch, epoch);
|
||||
res.state = state;
|
||||
}
|
||||
|
||||
/// Query the usage of a resource selector.
|
||||
///
|
||||
/// Returns `Some(Usage)` only if this usage is consistent
|
||||
|
Loading…
Reference in New Issue
Block a user