steamvr poc works
This commit is contained in:
106
Cargo.lock
generated
106
Cargo.lock
generated
@@ -293,7 +293,7 @@ dependencies = [
|
|||||||
"futures-lite 2.1.0",
|
"futures-lite 2.1.0",
|
||||||
"parking",
|
"parking",
|
||||||
"polling 3.3.1",
|
"polling 3.3.1",
|
||||||
"rustix 0.38.26",
|
"rustix 0.38.28",
|
||||||
"slab",
|
"slab",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
@@ -332,7 +332,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"event-listener 3.1.0",
|
"event-listener 3.1.0",
|
||||||
"futures-lite 1.13.0",
|
"futures-lite 1.13.0",
|
||||||
"rustix 0.38.26",
|
"rustix 0.38.28",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -359,7 +359,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"rustix 0.38.26",
|
"rustix 0.38.28",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"slab",
|
"slab",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
@@ -1794,7 +1794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.3.3",
|
"hermit-abi 0.3.3",
|
||||||
"rustix 0.38.26",
|
"rustix 0.38.28",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1818,9 +1818,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.9"
|
version = "1.0.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jni"
|
name = "jni"
|
||||||
@@ -2101,9 +2101,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
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 = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
|
checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
@@ -2328,9 +2328,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.18.0"
|
version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orbclient"
|
name = "orbclient"
|
||||||
@@ -2520,7 +2520,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustix 0.38.26",
|
"rustix 0.38.28",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
@@ -2593,6 +2593,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.30.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.33"
|
||||||
@@ -2747,9 +2756,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.26"
|
version = "0.38.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a"
|
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.1",
|
"bitflags 2.4.1",
|
||||||
"errno",
|
"errno",
|
||||||
@@ -2774,9 +2783,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.15"
|
version = "1.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "same-file"
|
||||||
@@ -3115,7 +3124,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand 2.0.1",
|
"fastrand 2.0.1",
|
||||||
"redox_syscall 0.4.1",
|
"redox_syscall 0.4.1",
|
||||||
"rustix 0.38.26",
|
"rustix 0.38.28",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3298,9 +3307,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.13"
|
version = "0.3.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
@@ -3373,18 +3382,18 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vk-parse"
|
name = "vk-parse"
|
||||||
version = "0.8.0"
|
version = "0.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c6a0bda9bbe6b9e50e6456c80aa8fe4cca3b21e4311a1130c41e4915ec2e32a"
|
checksum = "81086c28be67a8759cd80cbb3c8f7b520e0874605fc5eb74d5a1c9c2d1878e79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"xml-rs",
|
"xml-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vulkano"
|
name = "vulkano"
|
||||||
version = "0.33.0"
|
version = "0.34.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e1f15eeb9d93a05eb3c237332a10806eac1eb82444e54485bfcc1859c483c23"
|
checksum = "70f4278f76307b3c388679234b397b4f90de29cdba53873c26b624ed82653d75"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"ash",
|
"ash",
|
||||||
@@ -3393,13 +3402,14 @@ dependencies = [
|
|||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"half",
|
"half",
|
||||||
"heck",
|
"heck",
|
||||||
"indexmap 1.9.3",
|
"indexmap 2.1.0",
|
||||||
"libloading 0.7.4",
|
"libloading 0.8.1",
|
||||||
"objc",
|
"objc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"raw-window-handle",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -3411,9 +3421,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vulkano-macros"
|
name = "vulkano-macros"
|
||||||
version = "0.33.0"
|
version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "895b8a2cac1e7650d2d0552f2392da0970a358515ac11a34adaf19bfdc771b98"
|
checksum = "52be622d364272fd77e298e7f68e8547ae66e7687cb86eb85335412cee7e3965"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -3423,36 +3433,35 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vulkano-shaders"
|
name = "vulkano-shaders"
|
||||||
version = "0.33.0"
|
version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f8cf18e9becbc6d39f1c39e26bcf69546c93989553eb5748cd734a8a697a6e5"
|
checksum = "d1f63401297565d74afb96e9add12587d8e46235140cee325a8eb6ba4602f4ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"shaderc",
|
"shaderc",
|
||||||
"syn 1.0.109",
|
"syn 2.0.39",
|
||||||
"vulkano",
|
"vulkano",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vulkano-util"
|
name = "vulkano-util"
|
||||||
version = "0.33.0"
|
version = "0.34.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a71b6df05a391161c1baec645a918437c2949d3494bf74c8358fde291d37f5f4"
|
checksum = "ff1f96a4055a8362c8fa77a17c01da184c6412961cd9572110533ff89e6669a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"vulkano",
|
"vulkano",
|
||||||
"vulkano-win",
|
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vulkano-win"
|
name = "vulkano-win"
|
||||||
version = "0.33.0"
|
version = "0.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "666c77efe5ea82837781961a6bcd957ee2e926777e8de0005f580335d6eaefe7"
|
checksum = "b26c66e8600327823c15184e096eab37a7491d2f3f52b4956c21d84594fb0183"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-graphics-types",
|
"core-graphics-types",
|
||||||
"objc",
|
"objc",
|
||||||
@@ -3682,7 +3691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "b9b873b257fbc32ec909c0eb80dea312076a67014e65e245f5eb69a6b8ab330e"
|
checksum = "b9b873b257fbc32ec909c0eb80dea312076a67014e65e245f5eb69a6b8ab330e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quick-xml",
|
"quick-xml 0.28.2",
|
||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3727,7 +3736,7 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
"home",
|
"home",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 0.38.26",
|
"rustix 0.38.28",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4014,9 +4023,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.5.22"
|
version = "0.5.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40460c13b1e9b107cfc9ede71232f204c36250bbf6f9c78515e2e27ead3122a7"
|
checksum = "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@@ -4090,23 +4099,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xcb"
|
name = "xcb"
|
||||||
version = "1.2.2"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb3acf6b0945550d37d3a683b8f7de9d9f66b2c14dc390313b34d7ac6f1b4089"
|
checksum = "5d27b37e69b8c05bfadcd968eb1a4fe27c9c52565b727f88512f43b89567e262"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"libc",
|
"libc",
|
||||||
"quick-xml",
|
"quick-xml 0.30.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xcursor"
|
name = "xcursor"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
|
checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911"
|
||||||
dependencies = [
|
|
||||||
"nom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xdg-home"
|
name = "xdg-home"
|
||||||
@@ -4220,18 +4226,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.28"
|
version = "0.7.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e"
|
checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.7.28"
|
version = "0.7.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b"
|
checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ serde_yaml = "0.9.25"
|
|||||||
smallvec = "1.11.0"
|
smallvec = "1.11.0"
|
||||||
strum = { version = "0.25.0", features = ["derive"] }
|
strum = { version = "0.25.0", features = ["derive"] }
|
||||||
tinyvec = "1.6.0"
|
tinyvec = "1.6.0"
|
||||||
vulkano = { version = "0.33.0", features = ["serde"] }
|
vulkano = { version = "0.34.1", features = ["serde"] }
|
||||||
vulkano-shaders = "0.33.0"
|
vulkano-shaders = "0.34.0"
|
||||||
vulkano-util = "0.33.0"
|
vulkano-util = "0.34.1"
|
||||||
vulkano-win = "0.33.0"
|
vulkano-win = "0.34.0"
|
||||||
winit = "0.28.6"
|
winit = "0.28.6"
|
||||||
wlx-capture = { path = "../wlx-capture" }
|
wlx-capture = { path = "../wlx-capture" }
|
||||||
|
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ where
|
|||||||
get_screens_x11()
|
get_screens_x11()
|
||||||
};
|
};
|
||||||
|
|
||||||
let watch = create_watch::<T>(&app, &screens);
|
//let watch = create_watch::<T>(&app, &screens);
|
||||||
overlays.insert(watch.state.id, watch);
|
//overlays.insert(watch.state.id, watch);
|
||||||
|
|
||||||
let keyboard = create_keyboard(&app);
|
//let keyboard = create_keyboard(&app);
|
||||||
overlays.insert(keyboard.state.id, keyboard);
|
//overlays.insert(keyboard.state.id, keyboard);
|
||||||
|
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for mut screen in screens {
|
for mut screen in screens {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use ovr_overlay::overlay::OverlayManager;
|
|||||||
use vulkano::command_buffer::CommandBufferUsage;
|
use vulkano::command_buffer::CommandBufferUsage;
|
||||||
use vulkano::format::Format;
|
use vulkano::format::Format;
|
||||||
use vulkano::image::view::ImageView;
|
use vulkano::image::view::ImageView;
|
||||||
use vulkano::image::{ImageAccess, ImageLayout, ImageViewAbstract, ImmutableImage};
|
use vulkano::image::ImageLayout;
|
||||||
|
|
||||||
use crate::backend::overlay::{OverlayData, OverlayRenderer, OverlayState, SplitOverlayBackend};
|
use crate::backend::overlay::{OverlayData, OverlayRenderer, OverlayState, SplitOverlayBackend};
|
||||||
use crate::graphics::WlxGraphics;
|
use crate::graphics::WlxGraphics;
|
||||||
@@ -20,7 +20,7 @@ static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(1);
|
|||||||
|
|
||||||
pub(super) struct LinePool {
|
pub(super) struct LinePool {
|
||||||
lines: IdMap<usize, OverlayData<OpenVrOverlayData>>,
|
lines: IdMap<usize, OverlayData<OpenVrOverlayData>>,
|
||||||
view: Arc<ImageView<ImmutableImage>>,
|
view: Arc<ImageView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LinePool {
|
impl LinePool {
|
||||||
@@ -34,7 +34,7 @@ impl LinePool {
|
|||||||
|
|
||||||
graphics
|
graphics
|
||||||
.transition_layout(
|
.transition_layout(
|
||||||
texture.inner().image.clone(),
|
texture.clone(),
|
||||||
ImageLayout::ShaderReadOnlyOptimal,
|
ImageLayout::ShaderReadOnlyOptimal,
|
||||||
ImageLayout::TransferSrcOptimal,
|
ImageLayout::TransferSrcOptimal,
|
||||||
)
|
)
|
||||||
@@ -116,7 +116,7 @@ impl LinePool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct StaticRenderer {
|
struct StaticRenderer {
|
||||||
view: Arc<ImageView<ImmutableImage>>,
|
view: Arc<ImageView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayRenderer for StaticRenderer {
|
impl OverlayRenderer for StaticRenderer {
|
||||||
@@ -124,7 +124,7 @@ impl OverlayRenderer for StaticRenderer {
|
|||||||
fn pause(&mut self, _app: &mut AppState) {}
|
fn pause(&mut self, _app: &mut AppState) {}
|
||||||
fn resume(&mut self, _app: &mut AppState) {}
|
fn resume(&mut self, _app: &mut AppState) {}
|
||||||
fn render(&mut self, _app: &mut AppState) {}
|
fn render(&mut self, _app: &mut AppState) {}
|
||||||
fn view(&mut self) -> Option<Arc<dyn ImageViewAbstract>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
Some(self.view.clone())
|
Some(self.view.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use ovr_overlay::{
|
|||||||
pose::Matrix3x4,
|
pose::Matrix3x4,
|
||||||
sys::{ETrackingUniverseOrigin, VRVulkanTextureData_t},
|
sys::{ETrackingUniverseOrigin, VRVulkanTextureData_t},
|
||||||
};
|
};
|
||||||
use vulkano::{image::ImageAccess, Handle, VulkanObject};
|
use vulkano::{Handle, VulkanObject};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::overlay::{OverlayData, RelativeTo},
|
backend::overlay::{OverlayData, RelativeTo},
|
||||||
@@ -195,7 +195,7 @@ impl OverlayData<OpenVrOverlayData> {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let image = view.image().inner().image.clone();
|
let image = view.image().clone();
|
||||||
|
|
||||||
let raw_image = image.handle().as_raw();
|
let raw_image = image.handle().as_raw();
|
||||||
|
|
||||||
@@ -205,17 +205,14 @@ impl OverlayData<OpenVrOverlayData> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(format) = image.format() else {
|
let dimensions = image.extent();
|
||||||
panic!("{}: Image format is None", self.state.name);
|
let format = image.format();
|
||||||
};
|
|
||||||
|
|
||||||
let dimensions = image.dimensions();
|
|
||||||
|
|
||||||
let mut texture = VRVulkanTextureData_t {
|
let mut texture = VRVulkanTextureData_t {
|
||||||
m_nImage: raw_image,
|
m_nImage: raw_image,
|
||||||
m_nFormat: format as _,
|
m_nFormat: format as _,
|
||||||
m_nWidth: dimensions.width(),
|
m_nWidth: dimensions[0],
|
||||||
m_nHeight: dimensions.height(),
|
m_nHeight: dimensions[1],
|
||||||
m_nSampleCount: image.samples() as u32,
|
m_nSampleCount: image.samples() as u32,
|
||||||
m_pDevice: graphics.device.handle().as_raw() as *mut _,
|
m_pDevice: graphics.device.handle().as_raw() as *mut _,
|
||||||
m_pPhysicalDevice: graphics.device.physical_device().handle().as_raw() as *mut _,
|
m_pPhysicalDevice: graphics.device.physical_device().handle().as_raw() as *mut _,
|
||||||
@@ -224,8 +221,9 @@ impl OverlayData<OpenVrOverlayData> {
|
|||||||
m_nQueueFamilyIndex: graphics.queue.queue_family_index(),
|
m_nQueueFamilyIndex: graphics.queue.queue_family_index(),
|
||||||
};
|
};
|
||||||
|
|
||||||
log::debug!(
|
log::info!(
|
||||||
"UploadTex: {:?}, {}x{}, {:?}",
|
"{}: UploadTex {:?}, {}x{}, {:?}",
|
||||||
|
self.state.name,
|
||||||
format,
|
format,
|
||||||
texture.m_nWidth,
|
texture.m_nWidth,
|
||||||
texture.m_nHeight,
|
texture.m_nHeight,
|
||||||
@@ -234,5 +232,6 @@ impl OverlayData<OpenVrOverlayData> {
|
|||||||
if let Err(e) = overlay.set_image_vulkan(handle, &mut texture) {
|
if let Err(e) = overlay.set_image_vulkan(handle, &mut texture) {
|
||||||
panic!("Failed to set overlay texture: {}", e);
|
panic!("Failed to set overlay texture: {}", e);
|
||||||
}
|
}
|
||||||
|
log::info!("{}: Uploaded texture", self.state.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use glam::{Affine2, Affine3A, Mat3A, Quat, Vec3, Vec3A};
|
use glam::{Affine2, Affine3A, Mat3A, Quat, Vec3, Vec3A};
|
||||||
use vulkano::image::ImageViewAbstract;
|
use vulkano::image::view::ImageView;
|
||||||
|
|
||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ where
|
|||||||
pub fn render(&mut self, app: &mut AppState) {
|
pub fn render(&mut self, app: &mut AppState) {
|
||||||
self.backend.render(app);
|
self.backend.render(app);
|
||||||
}
|
}
|
||||||
pub fn view(&mut self) -> Option<Arc<dyn ImageViewAbstract>> {
|
pub fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
self.backend.view()
|
self.backend.view()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ pub trait OverlayRenderer {
|
|||||||
fn pause(&mut self, app: &mut AppState);
|
fn pause(&mut self, app: &mut AppState);
|
||||||
fn resume(&mut self, app: &mut AppState);
|
fn resume(&mut self, app: &mut AppState);
|
||||||
fn render(&mut self, app: &mut AppState);
|
fn render(&mut self, app: &mut AppState);
|
||||||
fn view(&mut self) -> Option<Arc<dyn ImageViewAbstract>>;
|
fn view(&mut self) -> Option<Arc<ImageView>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FallbackRenderer;
|
pub struct FallbackRenderer;
|
||||||
@@ -154,7 +154,7 @@ impl OverlayRenderer for FallbackRenderer {
|
|||||||
fn pause(&mut self, _app: &mut AppState) {}
|
fn pause(&mut self, _app: &mut AppState) {}
|
||||||
fn resume(&mut self, _app: &mut AppState) {}
|
fn resume(&mut self, _app: &mut AppState) {}
|
||||||
fn render(&mut self, _app: &mut AppState) {}
|
fn render(&mut self, _app: &mut AppState) {}
|
||||||
fn view(&mut self) -> Option<Arc<dyn ImageViewAbstract>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ impl OverlayRenderer for SplitOverlayBackend {
|
|||||||
fn render(&mut self, app: &mut AppState) {
|
fn render(&mut self, app: &mut AppState) {
|
||||||
self.renderer.render(app);
|
self.renderer.render(app);
|
||||||
}
|
}
|
||||||
fn view(&mut self) -> Option<Arc<dyn ImageViewAbstract>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
self.renderer.view()
|
self.renderer.view()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
561
src/graphics.rs
561
src/graphics.rs
@@ -1,22 +1,26 @@
|
|||||||
use std::{error::Error, io::Cursor, slice::Iter, sync::Arc};
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
io::Cursor,
|
||||||
|
os::fd::{FromRawFd, IntoRawFd},
|
||||||
|
slice::Iter,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use ash::vk::SubmitInfo;
|
use ash::vk::SubmitInfo;
|
||||||
use smallvec::smallvec;
|
use smallvec::{smallvec, SmallVec};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::{
|
buffer::{
|
||||||
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
|
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
|
||||||
Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer,
|
Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer,
|
||||||
},
|
},
|
||||||
command_buffer::{
|
command_buffer::{
|
||||||
allocator::{
|
allocator::{StandardCommandBufferAllocator, StandardCommandBufferAllocatorCreateInfo},
|
||||||
CommandBufferAllocator, CommandBufferBuilderAlloc, StandardCommandBufferAllocator,
|
|
||||||
},
|
|
||||||
sys::{CommandBufferBeginInfo, UnsafeCommandBufferBuilder},
|
sys::{CommandBufferBeginInfo, UnsafeCommandBufferBuilder},
|
||||||
AutoCommandBufferBuilder, CommandBufferExecFuture, CommandBufferInheritanceInfo,
|
AutoCommandBufferBuilder, CommandBufferExecFuture, CommandBufferInheritanceInfo,
|
||||||
CommandBufferInheritanceRenderPassType, CommandBufferInheritanceRenderingInfo,
|
CommandBufferInheritanceRenderPassInfo, CommandBufferInheritanceRenderPassType,
|
||||||
CommandBufferLevel, CommandBufferUsage, PrimaryAutoCommandBuffer,
|
CommandBufferLevel, CommandBufferUsage, CopyBufferToImageInfo, PrimaryAutoCommandBuffer,
|
||||||
PrimaryCommandBufferAbstract, RenderingAttachmentInfo, RenderingInfo,
|
PrimaryCommandBufferAbstract, RenderPassBeginInfo, SecondaryAutoCommandBuffer,
|
||||||
SecondaryAutoCommandBuffer, SubpassContents,
|
SubpassBeginInfo, SubpassContents, SubpassEndInfo,
|
||||||
},
|
},
|
||||||
descriptor_set::{
|
descriptor_set::{
|
||||||
allocator::StandardDescriptorSetAllocator, PersistentDescriptorSet, WriteDescriptorSet,
|
allocator::StandardDescriptorSetAllocator, PersistentDescriptorSet, WriteDescriptorSet,
|
||||||
@@ -27,33 +31,47 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
sys::Image, AttachmentImage, ImageCreateFlags, ImageDimensions, ImageError, ImageLayout,
|
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||||
ImageUsage, ImageViewAbstract, ImmutableImage, MipmapsCount, StorageImage, SubresourceData,
|
sys::RawImage,
|
||||||
SwapchainImage,
|
view::ImageView,
|
||||||
|
Image, ImageCreateInfo, ImageLayout, ImageTiling, ImageType, ImageUsage, SampleCount,
|
||||||
|
SubresourceLayout,
|
||||||
|
},
|
||||||
|
instance::{Instance, InstanceCreateFlags, InstanceCreateInfo, InstanceExtensions},
|
||||||
|
memory::{
|
||||||
|
allocator::{
|
||||||
|
AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter, StandardMemoryAllocator,
|
||||||
|
},
|
||||||
|
DedicatedAllocation, DeviceMemory, ExternalMemoryHandleType, ExternalMemoryHandleTypes,
|
||||||
|
MemoryAllocateInfo, MemoryImportInfo, ResourceMemory,
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo, InstanceExtensions},
|
|
||||||
memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator},
|
|
||||||
pipeline::{
|
pipeline::{
|
||||||
graphics::{
|
graphics::{
|
||||||
color_blend::{AttachmentBlend, ColorBlendState},
|
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
|
||||||
input_assembly::InputAssemblyState,
|
input_assembly::InputAssemblyState,
|
||||||
render_pass::PipelineRenderingCreateInfo,
|
multisample::MultisampleState,
|
||||||
vertex_input::Vertex,
|
rasterization::RasterizationState,
|
||||||
|
vertex_input::{Vertex, VertexDefinition},
|
||||||
viewport::{Viewport, ViewportState},
|
viewport::{Viewport, ViewportState},
|
||||||
|
GraphicsPipelineCreateInfo,
|
||||||
},
|
},
|
||||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
layout::PipelineDescriptorSetLayoutCreateInfo,
|
||||||
|
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
|
||||||
|
PipelineShaderStageCreateInfo,
|
||||||
|
},
|
||||||
|
render_pass::{
|
||||||
|
AttachmentDescription, AttachmentLoadOp, AttachmentReference, AttachmentStoreOp,
|
||||||
|
Framebuffer, FramebufferCreateInfo, RenderPass, RenderPassCreateInfo, Subpass,
|
||||||
|
SubpassDescription,
|
||||||
},
|
},
|
||||||
render_pass::{LoadOp, StoreOp},
|
|
||||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
|
||||||
shader::ShaderModule,
|
shader::ShaderModule,
|
||||||
swapchain::{CompositeAlpha, Surface, Swapchain, SwapchainCreateInfo},
|
swapchain::{CompositeAlpha, Surface, Swapchain, SwapchainCreateInfo},
|
||||||
sync::{
|
sync::{
|
||||||
fence::Fence, future::NowFuture, AccessFlags, DependencyInfo, GpuFuture,
|
fence::Fence, future::NowFuture, AccessFlags, DependencyInfo, GpuFuture,
|
||||||
ImageMemoryBarrier, PipelineStages,
|
ImageMemoryBarrier, PipelineStages,
|
||||||
},
|
},
|
||||||
Version, VulkanLibrary, VulkanObject,
|
DeviceSize, VulkanLibrary, VulkanObject,
|
||||||
};
|
};
|
||||||
use vulkano_win::VkSurfaceBuild;
|
|
||||||
use winit::{
|
use winit::{
|
||||||
event_loop::EventLoop,
|
event_loop::EventLoop,
|
||||||
window::{Window, WindowBuilder},
|
window::{Window, WindowBuilder},
|
||||||
@@ -98,8 +116,11 @@ impl WlxGraphics {
|
|||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
let layers = vec![];
|
let layers = vec![];
|
||||||
|
|
||||||
|
// TODO headless
|
||||||
|
let event_loop = EventLoop::new();
|
||||||
|
let library_extensions = Surface::required_extensions(&event_loop);
|
||||||
|
|
||||||
let library = VulkanLibrary::new().unwrap();
|
let library = VulkanLibrary::new().unwrap();
|
||||||
let library_extensions = vulkano_win::required_extensions(&library);
|
|
||||||
let required_extensions = library_extensions.union(&vk_instance_extensions);
|
let required_extensions = library_extensions.union(&vk_instance_extensions);
|
||||||
|
|
||||||
log::debug!("Instance exts for app: {:?}", &required_extensions);
|
log::debug!("Instance exts for app: {:?}", &required_extensions);
|
||||||
@@ -108,9 +129,9 @@ impl WlxGraphics {
|
|||||||
let instance = Instance::new(
|
let instance = Instance::new(
|
||||||
library,
|
library,
|
||||||
InstanceCreateInfo {
|
InstanceCreateInfo {
|
||||||
|
flags: InstanceCreateFlags::ENUMERATE_PORTABILITY,
|
||||||
enabled_extensions: required_extensions,
|
enabled_extensions: required_extensions,
|
||||||
enabled_layers: layers,
|
enabled_layers: layers,
|
||||||
enumerate_portability: true,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -128,17 +149,15 @@ impl WlxGraphics {
|
|||||||
log::debug!("Device exts for app: {:?}", &device_extensions);
|
log::debug!("Device exts for app: {:?}", &device_extensions);
|
||||||
|
|
||||||
// TODO headless
|
// TODO headless
|
||||||
let event_loop = EventLoop::new();
|
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
|
||||||
let surface = WindowBuilder::new()
|
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
|
||||||
.build_vk_surface(&event_loop, instance.clone())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let (physical_device, my_extensions, queue_family_index) = instance
|
let (physical_device, my_extensions, queue_family_index) = instance
|
||||||
.enumerate_physical_devices()
|
.enumerate_physical_devices()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.filter(|p| {
|
//.filter(|p| {
|
||||||
p.api_version() >= Version::V1_3 || p.supported_extensions().khr_dynamic_rendering
|
// p.api_version() >= Version::V1_3 || p.supported_extensions().khr_dynamic_rendering
|
||||||
})
|
//})
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
let runtime_extensions = vk_device_extensions_fn(&p);
|
let runtime_extensions = vk_device_extensions_fn(&p);
|
||||||
log::debug!(
|
log::debug!(
|
||||||
@@ -178,9 +197,9 @@ impl WlxGraphics {
|
|||||||
physical_device.properties().device_name,
|
physical_device.properties().device_name,
|
||||||
);
|
);
|
||||||
|
|
||||||
if physical_device.api_version() < Version::V1_3 {
|
//if physical_device.api_version() < Version::V1_3 {
|
||||||
device_extensions.khr_dynamic_rendering = true;
|
// device_extensions.khr_dynamic_rendering = true;
|
||||||
}
|
//}
|
||||||
|
|
||||||
let (device, mut queues) = Device::new(
|
let (device, mut queues) = Device::new(
|
||||||
physical_device,
|
physical_device,
|
||||||
@@ -203,11 +222,16 @@ impl WlxGraphics {
|
|||||||
|
|
||||||
let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone()));
|
let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone()));
|
||||||
let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
|
let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new(
|
||||||
|
device.clone(),
|
||||||
|
StandardCommandBufferAllocatorCreateInfo {
|
||||||
|
secondary_buffer_count: 32,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
));
|
||||||
|
let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
));
|
));
|
||||||
let descriptor_set_allocator =
|
|
||||||
Arc::new(StandardDescriptorSetAllocator::new(device.clone()));
|
|
||||||
|
|
||||||
let vertices = [
|
let vertices = [
|
||||||
Vert2Uv {
|
Vert2Uv {
|
||||||
@@ -228,13 +252,14 @@ impl WlxGraphics {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
let quad_verts = Buffer::from_iter(
|
let quad_verts = Buffer::from_iter(
|
||||||
&memory_allocator,
|
memory_allocator.clone(),
|
||||||
BufferCreateInfo {
|
BufferCreateInfo {
|
||||||
usage: BufferUsage::VERTEX_BUFFER,
|
usage: BufferUsage::VERTEX_BUFFER,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
AllocationCreateInfo {
|
AllocationCreateInfo {
|
||||||
usage: MemoryUsage::Upload,
|
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
|
||||||
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
vertices.into_iter(),
|
vertices.into_iter(),
|
||||||
@@ -242,13 +267,14 @@ impl WlxGraphics {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let quad_indices = Buffer::from_iter(
|
let quad_indices = Buffer::from_iter(
|
||||||
&memory_allocator,
|
memory_allocator.clone(),
|
||||||
BufferCreateInfo {
|
BufferCreateInfo {
|
||||||
usage: BufferUsage::INDEX_BUFFER,
|
usage: BufferUsage::INDEX_BUFFER,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
AllocationCreateInfo {
|
AllocationCreateInfo {
|
||||||
usage: MemoryUsage::Upload,
|
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
|
||||||
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
INDICES.iter().cloned(),
|
INDICES.iter().cloned(),
|
||||||
@@ -271,10 +297,7 @@ impl WlxGraphics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn create_swapchain(
|
pub fn create_swapchain(&self, format: Option<Format>) -> (Arc<Swapchain>, Vec<Arc<Image>>) {
|
||||||
&self,
|
|
||||||
format: Option<Format>,
|
|
||||||
) -> (Arc<Swapchain>, Vec<Arc<SwapchainImage>>) {
|
|
||||||
let (min_image_count, composite_alpha, image_format) = if let Some(format) = format {
|
let (min_image_count, composite_alpha, image_format) = if let Some(format) = format {
|
||||||
(1, CompositeAlpha::Opaque, format)
|
(1, CompositeAlpha::Opaque, format)
|
||||||
} else {
|
} else {
|
||||||
@@ -314,7 +337,7 @@ impl WlxGraphics {
|
|||||||
self.surface.clone(),
|
self.surface.clone(),
|
||||||
SwapchainCreateInfo {
|
SwapchainCreateInfo {
|
||||||
min_image_count,
|
min_image_count,
|
||||||
image_format: Some(image_format),
|
image_format,
|
||||||
image_extent: window.inner_size().into(),
|
image_extent: window.inner_size().into(),
|
||||||
image_usage: ImageUsage::COLOR_ATTACHMENT,
|
image_usage: ImageUsage::COLOR_ATTACHMENT,
|
||||||
composite_alpha,
|
composite_alpha,
|
||||||
@@ -370,13 +393,14 @@ impl WlxGraphics {
|
|||||||
T: BufferContents + Clone,
|
T: BufferContents + Clone,
|
||||||
{
|
{
|
||||||
Buffer::from_iter(
|
Buffer::from_iter(
|
||||||
&self.memory_allocator,
|
self.memory_allocator.clone(),
|
||||||
BufferCreateInfo {
|
BufferCreateInfo {
|
||||||
usage,
|
usage,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
AllocationCreateInfo {
|
AllocationCreateInfo {
|
||||||
usage: MemoryUsage::Upload,
|
memory_type_filter: MemoryTypeFilter::PREFER_HOST
|
||||||
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
contents.cloned(),
|
contents.cloned(),
|
||||||
@@ -384,12 +408,8 @@ impl WlxGraphics {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dmabuf_texture(&self, frame: DmabufFrame) -> Result<Arc<StorageImage>, ImageError> {
|
pub fn dmabuf_texture(&self, frame: DmabufFrame) -> Option<Arc<Image>> {
|
||||||
let dimensions = ImageDimensions::Dim2d {
|
let extent = [frame.format.width, frame.format.height, 1];
|
||||||
width: frame.format.width,
|
|
||||||
height: frame.format.height,
|
|
||||||
array_layers: 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
let format = match frame.format.fourcc {
|
let format = match frame.format.fourcc {
|
||||||
DRM_FORMAT_ABGR8888 => Format::R8G8B8A8_UNORM,
|
DRM_FORMAT_ABGR8888 => Format::R8G8B8A8_UNORM,
|
||||||
@@ -399,60 +419,145 @@ impl WlxGraphics {
|
|||||||
_ => panic!("Unsupported dmabuf format {:x}", frame.format.fourcc),
|
_ => panic!("Unsupported dmabuf format {:x}", frame.format.fourcc),
|
||||||
};
|
};
|
||||||
|
|
||||||
let planes = frame
|
let layouts: Vec<SubresourceLayout> = (0..frame.num_planes)
|
||||||
.planes
|
.into_iter()
|
||||||
.iter()
|
.map(|i| {
|
||||||
.take(frame.num_planes)
|
let plane = &frame.planes[i];
|
||||||
.filter_map(|plane| {
|
SubresourceLayout {
|
||||||
let Some(fd) = plane.fd else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(SubresourceData {
|
|
||||||
fd,
|
|
||||||
offset: plane.offset as _,
|
offset: plane.offset as _,
|
||||||
|
size: 0,
|
||||||
row_pitch: plane.stride as _,
|
row_pitch: plane.stride as _,
|
||||||
})
|
array_pitch: None,
|
||||||
|
depth_pitch: None,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
StorageImage::new_from_dma_buf_fd(
|
let external_memory_handle_types = ExternalMemoryHandleTypes::DMA_BUF;
|
||||||
&self.memory_allocator,
|
|
||||||
self.device.clone(),
|
|
||||||
dimensions,
|
|
||||||
format,
|
|
||||||
ImageUsage::SAMPLED | ImageUsage::TRANSFER_SRC,
|
|
||||||
ImageCreateFlags::empty(),
|
|
||||||
[self.queue.queue_family_index()],
|
|
||||||
planes,
|
|
||||||
frame.format.modifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_texture(&self, width: u32, height: u32, format: Format) -> Arc<AttachmentImage> {
|
let image = RawImage::new(
|
||||||
let tex = AttachmentImage::with_usage(
|
self.device.clone(),
|
||||||
&self.memory_allocator,
|
ImageCreateInfo {
|
||||||
[width, height],
|
image_type: ImageType::Dim2d,
|
||||||
format,
|
format,
|
||||||
ImageUsage::SAMPLED | ImageUsage::TRANSFER_SRC | ImageUsage::COLOR_ATTACHMENT,
|
extent,
|
||||||
|
usage: ImageUsage::SAMPLED | ImageUsage::TRANSFER_SRC,
|
||||||
|
external_memory_handle_types,
|
||||||
|
tiling: ImageTiling::DrmFormatModifier,
|
||||||
|
drm_format_modifiers: vec![frame.format.modifier],
|
||||||
|
drm_format_modifier_plane_layouts: layouts,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
tex
|
let requirements = image.memory_requirements()[0];
|
||||||
|
let memory_type_index = self
|
||||||
|
.memory_allocator
|
||||||
|
.find_memory_type_index(
|
||||||
|
requirements.memory_type_bits,
|
||||||
|
MemoryTypeFilter::PREFER_DEVICE,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
debug_assert!(self.device.enabled_extensions().khr_external_memory_fd);
|
||||||
|
debug_assert!(self.device.enabled_extensions().khr_external_memory);
|
||||||
|
debug_assert!(self.device.enabled_extensions().ext_external_memory_dma_buf);
|
||||||
|
|
||||||
|
let memory = unsafe {
|
||||||
|
if frame.num_planes != 1 {
|
||||||
|
log::error!("Unsupported number of DMA-buf planes: {}", frame.num_planes);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let Some(fd) = frame.planes[0].fd else {
|
||||||
|
log::error!("DMA-buf plane has no FD");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let file = std::fs::File::from_raw_fd(fd);
|
||||||
|
let new_file = file.try_clone().unwrap();
|
||||||
|
file.into_raw_fd();
|
||||||
|
|
||||||
|
DeviceMemory::import(
|
||||||
|
self.device.clone(),
|
||||||
|
MemoryAllocateInfo {
|
||||||
|
allocation_size: requirements.layout.size(),
|
||||||
|
memory_type_index,
|
||||||
|
dedicated_allocation: Some(DedicatedAllocation::Image(&image)),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
MemoryImportInfo::Fd {
|
||||||
|
file: new_file,
|
||||||
|
handle_type: ExternalMemoryHandleType::DmaBuf,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let allocations: SmallVec<[ResourceMemory; 1]> =
|
||||||
|
smallvec![ResourceMemory::new_dedicated(memory)];
|
||||||
|
|
||||||
|
if let Some(image) = image.bind_memory(allocations).ok() {
|
||||||
|
Some(Arc::new(image))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_texture(&self, width: u32, height: u32, format: Format) -> Arc<Image> {
|
||||||
|
Image::new(
|
||||||
|
self.memory_allocator.clone(),
|
||||||
|
ImageCreateInfo {
|
||||||
|
image_type: ImageType::Dim2d,
|
||||||
|
format,
|
||||||
|
extent: [width, height, 1],
|
||||||
|
usage: ImageUsage::TRANSFER_SRC
|
||||||
|
| ImageUsage::SAMPLED
|
||||||
|
| ImageUsage::COLOR_ATTACHMENT,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AllocationCreateInfo::default(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_pipeline(
|
pub fn create_pipeline(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
|
render_target: Arc<ImageView>,
|
||||||
vert: Arc<ShaderModule>,
|
vert: Arc<ShaderModule>,
|
||||||
frag: Arc<ShaderModule>,
|
frag: Arc<ShaderModule>,
|
||||||
format: Format,
|
format: Format,
|
||||||
) -> Arc<WlxPipeline> {
|
) -> Arc<WlxPipeline> {
|
||||||
Arc::new(WlxPipeline::new(self.clone(), vert, frag, format))
|
Arc::new(WlxPipeline::new(
|
||||||
|
render_target,
|
||||||
|
self.clone(),
|
||||||
|
vert,
|
||||||
|
frag,
|
||||||
|
format,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_command_buffer(
|
pub fn create_pipeline_with_layouts(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
usage: CommandBufferUsage,
|
render_target: Arc<ImageView>,
|
||||||
) -> WlxCommandBuffer<PrimaryAutoCommandBuffer> {
|
vert: Arc<ShaderModule>,
|
||||||
|
frag: Arc<ShaderModule>,
|
||||||
|
format: Format,
|
||||||
|
initial_layout: ImageLayout,
|
||||||
|
final_layout: ImageLayout,
|
||||||
|
) -> Arc<WlxPipeline> {
|
||||||
|
Arc::new(WlxPipeline::new_with_layout(
|
||||||
|
render_target,
|
||||||
|
self.clone(),
|
||||||
|
vert,
|
||||||
|
frag,
|
||||||
|
format,
|
||||||
|
initial_layout,
|
||||||
|
final_layout,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_command_buffer(self: &Arc<Self>, usage: CommandBufferUsage) -> WlxCommandBuffer {
|
||||||
let command_buffer = AutoCommandBufferBuilder::primary(
|
let command_buffer = AutoCommandBufferBuilder::primary(
|
||||||
&self.command_buffer_allocator,
|
&self.command_buffer_allocator,
|
||||||
self.queue.queue_family_index(),
|
self.queue.queue_family_index(),
|
||||||
@@ -482,31 +587,25 @@ impl WlxGraphics {
|
|||||||
..ImageMemoryBarrier::image(image)
|
..ImageMemoryBarrier::image(image)
|
||||||
};
|
};
|
||||||
|
|
||||||
let builder_alloc = self
|
|
||||||
.command_buffer_allocator
|
|
||||||
.allocate(
|
|
||||||
self.queue.queue_family_index(),
|
|
||||||
CommandBufferLevel::Primary,
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.next()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let command_buffer = unsafe {
|
let command_buffer = unsafe {
|
||||||
let mut builder = UnsafeCommandBufferBuilder::new(
|
let mut builder = UnsafeCommandBufferBuilder::new(
|
||||||
&builder_alloc.inner(),
|
&self.command_buffer_allocator,
|
||||||
|
self.queue.queue_family_index(),
|
||||||
|
CommandBufferLevel::Primary,
|
||||||
CommandBufferBeginInfo {
|
CommandBufferBeginInfo {
|
||||||
usage: CommandBufferUsage::OneTimeSubmit,
|
usage: CommandBufferUsage::OneTimeSubmit,
|
||||||
|
inheritance_info: None,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
builder.pipeline_barrier(&DependencyInfo {
|
builder
|
||||||
image_memory_barriers: smallvec![barrier],
|
.pipeline_barrier(&DependencyInfo {
|
||||||
..Default::default()
|
image_memory_barriers: smallvec![barrier],
|
||||||
});
|
..Default::default()
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
builder.build().unwrap()
|
builder.build().unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -535,24 +634,27 @@ impl WlxGraphics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WlxCommandBuffer<T> {
|
pub struct WlxCommandBuffer {
|
||||||
graphics: Arc<WlxGraphics>,
|
graphics: Arc<WlxGraphics>,
|
||||||
command_buffer: AutoCommandBufferBuilder<T, Arc<StandardCommandBufferAllocator>>,
|
command_buffer: AutoCommandBufferBuilder<
|
||||||
|
PrimaryAutoCommandBuffer<Arc<StandardCommandBufferAllocator>>,
|
||||||
|
Arc<StandardCommandBufferAllocator>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> WlxCommandBuffer<T> {
|
impl WlxCommandBuffer {
|
||||||
pub fn begin(mut self, render_target: Arc<dyn ImageViewAbstract>) -> Self {
|
pub fn begin_render_pass(mut self, pipeline: &WlxPipeline) -> Self {
|
||||||
self.command_buffer
|
self.command_buffer
|
||||||
.begin_rendering(RenderingInfo {
|
.begin_render_pass(
|
||||||
contents: SubpassContents::SecondaryCommandBuffers,
|
RenderPassBeginInfo {
|
||||||
color_attachments: vec![Some(RenderingAttachmentInfo {
|
clear_values: vec![Some([0.0, 0.0, 0.0, 1.0].into())],
|
||||||
load_op: LoadOp::Clear,
|
..RenderPassBeginInfo::framebuffer(pipeline.framebuffer.clone())
|
||||||
store_op: StoreOp::Store,
|
},
|
||||||
clear_value: Some([0.0, 0.0, 0.0, 0.0].into()),
|
SubpassBeginInfo {
|
||||||
..RenderingAttachmentInfo::image_view(render_target.clone())
|
contents: SubpassContents::SecondaryCommandBuffers,
|
||||||
})],
|
..Default::default()
|
||||||
..Default::default()
|
},
|
||||||
})
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -571,26 +673,46 @@ impl<T> WlxCommandBuffer<T> {
|
|||||||
height: u32,
|
height: u32,
|
||||||
format: Format,
|
format: Format,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Arc<ImmutableImage> {
|
) -> Arc<Image> {
|
||||||
let dimensions = ImageDimensions::Dim2d {
|
let image = Image::new(
|
||||||
width,
|
self.graphics.memory_allocator.clone(),
|
||||||
height,
|
ImageCreateInfo {
|
||||||
array_layers: 1,
|
image_type: ImageType::Dim2d,
|
||||||
};
|
format,
|
||||||
|
extent: [width, height, 1],
|
||||||
ImmutableImage::from_iter(
|
usage: ImageUsage::TRANSFER_DST | ImageUsage::TRANSFER_SRC | ImageUsage::SAMPLED,
|
||||||
&self.graphics.memory_allocator,
|
..Default::default()
|
||||||
data,
|
},
|
||||||
dimensions,
|
AllocationCreateInfo::default(),
|
||||||
MipmapsCount::Log2, // required for TRANSFER_SRC
|
|
||||||
format,
|
|
||||||
&mut self.command_buffer,
|
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap();
|
||||||
|
|
||||||
|
let buffer: Subbuffer<[u8]> = Buffer::new_slice(
|
||||||
|
self.graphics.memory_allocator.clone(),
|
||||||
|
BufferCreateInfo {
|
||||||
|
usage: BufferUsage::TRANSFER_SRC,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AllocationCreateInfo {
|
||||||
|
memory_type_filter: MemoryTypeFilter::PREFER_HOST
|
||||||
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
data.len() as DeviceSize,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
buffer.write().unwrap().copy_from_slice(data.as_slice());
|
||||||
|
|
||||||
|
self.command_buffer
|
||||||
|
.copy_buffer_to_image(CopyBufferToImageInfo::buffer_image(buffer, image.clone()))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
image
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn texture2d_png(&mut self, bytes: Vec<u8>) -> Arc<ImmutableImage> {
|
pub fn texture2d_png(&mut self, bytes: Vec<u8>) -> Arc<Image> {
|
||||||
let cursor = Cursor::new(bytes);
|
let cursor = Cursor::new(bytes);
|
||||||
let decoder = png::Decoder::new(cursor);
|
let decoder = png::Decoder::new(cursor);
|
||||||
let mut reader = decoder.read_info().unwrap();
|
let mut reader = decoder.read_info().unwrap();
|
||||||
@@ -604,13 +726,15 @@ impl<T> WlxCommandBuffer<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlxCommandBuffer<PrimaryAutoCommandBuffer> {
|
impl WlxCommandBuffer {
|
||||||
pub fn end_render(mut self) -> Self {
|
pub fn end_render_pass(mut self) -> Self {
|
||||||
self.command_buffer.end_rendering().unwrap();
|
self.command_buffer
|
||||||
|
.end_render_pass(SubpassEndInfo::default())
|
||||||
|
.unwrap();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> PrimaryAutoCommandBuffer {
|
pub fn build(self) -> Arc<PrimaryAutoCommandBuffer<Arc<StandardCommandBufferAllocator>>> {
|
||||||
self.command_buffer.build().unwrap()
|
self.command_buffer.build().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,11 +753,79 @@ impl WlxCommandBuffer<PrimaryAutoCommandBuffer> {
|
|||||||
pub struct WlxPipeline {
|
pub struct WlxPipeline {
|
||||||
pub graphics: Arc<WlxGraphics>,
|
pub graphics: Arc<WlxGraphics>,
|
||||||
pub pipeline: Arc<GraphicsPipeline>,
|
pub pipeline: Arc<GraphicsPipeline>,
|
||||||
|
pub render_pass: Arc<RenderPass>,
|
||||||
|
pub framebuffer: Arc<Framebuffer>,
|
||||||
|
pub view: Arc<ImageView>,
|
||||||
pub format: Format,
|
pub format: Format,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlxPipeline {
|
impl WlxPipeline {
|
||||||
fn new(
|
fn new(
|
||||||
|
render_target: Arc<ImageView>,
|
||||||
|
graphics: Arc<WlxGraphics>,
|
||||||
|
vert: Arc<ShaderModule>,
|
||||||
|
frag: Arc<ShaderModule>,
|
||||||
|
format: Format,
|
||||||
|
) -> Self {
|
||||||
|
let render_pass = vulkano::single_pass_renderpass!(
|
||||||
|
graphics.device.clone(),
|
||||||
|
attachments: {
|
||||||
|
color: {
|
||||||
|
format: format,
|
||||||
|
samples: 1,
|
||||||
|
load_op: Clear,
|
||||||
|
store_op: Store,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pass: {
|
||||||
|
color: [color],
|
||||||
|
depth_stencil: {},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Self::new_from_pass(render_target, render_pass, graphics, vert, frag, format)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_with_layout(
|
||||||
|
render_target: Arc<ImageView>,
|
||||||
|
graphics: Arc<WlxGraphics>,
|
||||||
|
vert: Arc<ShaderModule>,
|
||||||
|
frag: Arc<ShaderModule>,
|
||||||
|
format: Format,
|
||||||
|
initial_layout: ImageLayout,
|
||||||
|
final_layout: ImageLayout,
|
||||||
|
) -> Self {
|
||||||
|
let render_pass_description = RenderPassCreateInfo {
|
||||||
|
attachments: vec![AttachmentDescription {
|
||||||
|
format: format,
|
||||||
|
samples: SampleCount::Sample1,
|
||||||
|
load_op: AttachmentLoadOp::Clear,
|
||||||
|
store_op: AttachmentStoreOp::Store,
|
||||||
|
initial_layout,
|
||||||
|
final_layout,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
|
subpasses: vec![SubpassDescription {
|
||||||
|
color_attachments: vec![Some(AttachmentReference {
|
||||||
|
attachment: 0,
|
||||||
|
layout: ImageLayout::ColorAttachmentOptimal,
|
||||||
|
..Default::default()
|
||||||
|
})],
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let render_pass =
|
||||||
|
RenderPass::new(graphics.device.clone(), render_pass_description).unwrap();
|
||||||
|
|
||||||
|
Self::new_from_pass(render_target, render_pass, graphics, vert, frag, format)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_from_pass(
|
||||||
|
render_target: Arc<ImageView>,
|
||||||
|
render_pass: Arc<RenderPass>,
|
||||||
graphics: Arc<WlxGraphics>,
|
graphics: Arc<WlxGraphics>,
|
||||||
vert: Arc<ShaderModule>,
|
vert: Arc<ShaderModule>,
|
||||||
frag: Arc<ShaderModule>,
|
frag: Arc<ShaderModule>,
|
||||||
@@ -641,24 +833,64 @@ impl WlxPipeline {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let vep = vert.entry_point("main").unwrap();
|
let vep = vert.entry_point("main").unwrap();
|
||||||
let fep = frag.entry_point("main").unwrap();
|
let fep = frag.entry_point("main").unwrap();
|
||||||
let pipeline = GraphicsPipeline::start()
|
|
||||||
.render_pass(PipelineRenderingCreateInfo {
|
let vertex_input_state = Vert2Uv::per_vertex()
|
||||||
color_attachment_formats: vec![Some(format)],
|
.definition(&vep.info().input_interface)
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.color_blend_state(ColorBlendState::default().blend(AttachmentBlend::alpha()))
|
|
||||||
.vertex_input_state(Vert2Uv::per_vertex())
|
|
||||||
.input_assembly_state(InputAssemblyState::new())
|
|
||||||
.vertex_shader(vep, ())
|
|
||||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
|
||||||
.fragment_shader(fep, ())
|
|
||||||
.build(graphics.device.clone())
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let stages = smallvec![
|
||||||
|
PipelineShaderStageCreateInfo::new(vep),
|
||||||
|
PipelineShaderStageCreateInfo::new(fep),
|
||||||
|
];
|
||||||
|
|
||||||
|
let layout = PipelineLayout::new(
|
||||||
|
graphics.device.clone(),
|
||||||
|
PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages)
|
||||||
|
.into_pipeline_layout_create_info(graphics.device.clone())
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let framebuffer = Framebuffer::new(
|
||||||
|
render_pass.clone(),
|
||||||
|
FramebufferCreateInfo {
|
||||||
|
attachments: vec![render_target.clone()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let pipeline = GraphicsPipeline::new(
|
||||||
|
graphics.device.clone(),
|
||||||
|
None,
|
||||||
|
GraphicsPipelineCreateInfo {
|
||||||
|
stages,
|
||||||
|
vertex_input_state: Some(vertex_input_state),
|
||||||
|
input_assembly_state: Some(InputAssemblyState::default()),
|
||||||
|
viewport_state: Some(ViewportState::default()),
|
||||||
|
color_blend_state: Some(ColorBlendState {
|
||||||
|
attachments: vec![ColorBlendAttachmentState {
|
||||||
|
blend: Some(AttachmentBlend::alpha()),
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
rasterization_state: Some(RasterizationState::default()),
|
||||||
|
multisample_state: Some(MultisampleState::default()),
|
||||||
|
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
|
||||||
|
subpass: Some(Subpass::from(render_pass.clone(), 0).unwrap().into()),
|
||||||
|
..GraphicsPipelineCreateInfo::layout(layout)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
graphics,
|
graphics,
|
||||||
pipeline,
|
pipeline,
|
||||||
format,
|
format,
|
||||||
|
render_pass,
|
||||||
|
framebuffer,
|
||||||
|
view: render_target,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,7 +901,7 @@ impl WlxPipeline {
|
|||||||
pub fn uniform_sampler(
|
pub fn uniform_sampler(
|
||||||
&self,
|
&self,
|
||||||
set: usize,
|
set: usize,
|
||||||
texture: Arc<dyn ImageViewAbstract>,
|
texture: Arc<ImageView>,
|
||||||
filter: Filter,
|
filter: Filter,
|
||||||
) -> Arc<PersistentDescriptorSet> {
|
) -> Arc<PersistentDescriptorSet> {
|
||||||
let sampler = Sampler::new(
|
let sampler = Sampler::new(
|
||||||
@@ -689,6 +921,7 @@ impl WlxPipeline {
|
|||||||
&self.graphics.descriptor_set_allocator,
|
&self.graphics.descriptor_set_allocator,
|
||||||
layout.clone(),
|
layout.clone(),
|
||||||
[WriteDescriptorSet::image_view_sampler(0, texture, sampler)],
|
[WriteDescriptorSet::image_view_sampler(0, texture, sampler)],
|
||||||
|
[],
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@@ -701,6 +934,8 @@ impl WlxPipeline {
|
|||||||
self.graphics.memory_allocator.clone(),
|
self.graphics.memory_allocator.clone(),
|
||||||
SubbufferAllocatorCreateInfo {
|
SubbufferAllocatorCreateInfo {
|
||||||
buffer_usage: BufferUsage::UNIFORM_BUFFER,
|
buffer_usage: BufferUsage::UNIFORM_BUFFER,
|
||||||
|
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
|
||||||
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -716,6 +951,7 @@ impl WlxPipeline {
|
|||||||
&self.graphics.descriptor_set_allocator,
|
&self.graphics.descriptor_set_allocator,
|
||||||
layout.clone(),
|
layout.clone(),
|
||||||
[WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer)],
|
[WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer)],
|
||||||
|
[],
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@@ -743,7 +979,7 @@ pub struct WlxPass {
|
|||||||
vertex_buffer: Subbuffer<[Vert2Uv]>,
|
vertex_buffer: Subbuffer<[Vert2Uv]>,
|
||||||
index_buffer: Subbuffer<[u16]>,
|
index_buffer: Subbuffer<[u16]>,
|
||||||
descriptor_sets: Vec<Arc<PersistentDescriptorSet>>,
|
descriptor_sets: Vec<Arc<PersistentDescriptorSet>>,
|
||||||
pub command_buffer: Arc<SecondaryAutoCommandBuffer>,
|
pub command_buffer: Arc<SecondaryAutoCommandBuffer<Arc<StandardCommandBufferAllocator>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlxPass {
|
impl WlxPass {
|
||||||
@@ -755,9 +991,9 @@ impl WlxPass {
|
|||||||
descriptor_sets: Vec<Arc<PersistentDescriptorSet>>,
|
descriptor_sets: Vec<Arc<PersistentDescriptorSet>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let viewport = Viewport {
|
let viewport = Viewport {
|
||||||
origin: [0.0, 0.0],
|
offset: [0.0, 0.0],
|
||||||
dimensions,
|
extent: dimensions,
|
||||||
depth_range: 0.0..1.0,
|
depth_range: 0.0..=1.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let pipeline_inner = pipeline.inner().clone();
|
let pipeline_inner = pipeline.inner().clone();
|
||||||
@@ -766,10 +1002,10 @@ impl WlxPass {
|
|||||||
pipeline.graphics.queue.queue_family_index(),
|
pipeline.graphics.queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
CommandBufferInheritanceInfo {
|
CommandBufferInheritanceInfo {
|
||||||
render_pass: Some(CommandBufferInheritanceRenderPassType::BeginRendering(
|
render_pass: Some(CommandBufferInheritanceRenderPassType::BeginRenderPass(
|
||||||
CommandBufferInheritanceRenderingInfo {
|
CommandBufferInheritanceRenderPassInfo {
|
||||||
color_attachment_formats: vec![Some(pipeline.format)],
|
subpass: Subpass::from(pipeline.render_pass.clone(), 0).unwrap(),
|
||||||
..Default::default()
|
framebuffer: None,
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -778,16 +1014,21 @@ impl WlxPass {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
command_buffer
|
command_buffer
|
||||||
.set_viewport(0, [viewport])
|
.set_viewport(0, smallvec![viewport])
|
||||||
|
.unwrap()
|
||||||
.bind_pipeline_graphics(pipeline_inner)
|
.bind_pipeline_graphics(pipeline_inner)
|
||||||
|
.unwrap()
|
||||||
.bind_descriptor_sets(
|
.bind_descriptor_sets(
|
||||||
PipelineBindPoint::Graphics,
|
PipelineBindPoint::Graphics,
|
||||||
pipeline.inner().layout().clone(),
|
pipeline.inner().layout().clone(),
|
||||||
0,
|
0,
|
||||||
descriptor_sets.clone(),
|
descriptor_sets.clone(),
|
||||||
)
|
)
|
||||||
|
.unwrap()
|
||||||
.bind_vertex_buffers(0, vertex_buffer.clone())
|
.bind_vertex_buffers(0, vertex_buffer.clone())
|
||||||
|
.unwrap()
|
||||||
.bind_index_buffer(index_buffer.clone())
|
.bind_index_buffer(index_buffer.clone())
|
||||||
|
.unwrap()
|
||||||
.draw_indexed(index_buffer.len() as u32, 1, 0, 0, 0)
|
.draw_indexed(index_buffer.len() as u32, 1, 0, 0, 0)
|
||||||
.or_else(|err| {
|
.or_else(|err| {
|
||||||
if let Some(source) = err.source() {
|
if let Some(source) = err.source() {
|
||||||
@@ -802,7 +1043,7 @@ impl WlxPass {
|
|||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
index_buffer,
|
index_buffer,
|
||||||
descriptor_sets,
|
descriptor_sets,
|
||||||
command_buffer: Arc::new(command_buffer.build().unwrap()),
|
command_buffer: command_buffer.build().unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::{rc::Rc, str::FromStr, sync::Arc};
|
|||||||
use fontconfig::{FontConfig, OwnedPattern};
|
use fontconfig::{FontConfig, OwnedPattern};
|
||||||
use freetype::{bitmap::PixelMode, face::LoadFlag, Face, Library};
|
use freetype::{bitmap::PixelMode, face::LoadFlag, Face, Library};
|
||||||
use idmap::IdMap;
|
use idmap::IdMap;
|
||||||
use vulkano::{command_buffer::CommandBufferUsage, format::Format, image::ImmutableImage};
|
use vulkano::{command_buffer::CommandBufferUsage, format::Format, image::Image};
|
||||||
|
|
||||||
use crate::graphics::WlxGraphics;
|
use crate::graphics::WlxGraphics;
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ struct Font {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Glyph {
|
pub struct Glyph {
|
||||||
pub tex: Option<Arc<ImmutableImage>>,
|
pub tex: Option<Arc<Image>>,
|
||||||
pub top: f32,
|
pub top: f32,
|
||||||
pub left: f32,
|
pub left: f32,
|
||||||
pub width: f32,
|
pub width: f32,
|
||||||
|
|||||||
153
src/gui/mod.rs
153
src/gui/mod.rs
@@ -2,10 +2,9 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use glam::{Vec2, Vec3};
|
use glam::{Vec2, Vec3};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
command_buffer::{CommandBufferUsage, PrimaryAutoCommandBuffer},
|
command_buffer::CommandBufferUsage,
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, AttachmentImage, ImageAccess, ImageLayout, ImageViewAbstract},
|
image::{sampler::Filter, view::ImageView, ImageLayout},
|
||||||
sampler::Filter,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -189,8 +188,9 @@ pub struct CanvasData<D> {
|
|||||||
|
|
||||||
graphics: Arc<WlxGraphics>,
|
graphics: Arc<WlxGraphics>,
|
||||||
|
|
||||||
pipeline_color: Arc<WlxPipeline>,
|
pipeline_bg_color: Arc<WlxPipeline>,
|
||||||
pipeline_glyph: Arc<WlxPipeline>,
|
pipeline_fg_glyph: Arc<WlxPipeline>,
|
||||||
|
pipeline_final: Arc<WlxPipeline>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Canvas<D, S> {
|
pub struct Canvas<D, S> {
|
||||||
@@ -204,14 +204,10 @@ pub struct Canvas<D, S> {
|
|||||||
interact_stride: usize,
|
interact_stride: usize,
|
||||||
interact_rows: usize,
|
interact_rows: usize,
|
||||||
|
|
||||||
view_fg: Arc<ImageView<AttachmentImage>>,
|
view_final: Arc<ImageView>,
|
||||||
view_bg: Arc<ImageView<AttachmentImage>>,
|
|
||||||
view_final: Arc<ImageView<AttachmentImage>>,
|
|
||||||
|
|
||||||
pass_fg: WlxPass,
|
pass_fg: WlxPass,
|
||||||
pass_bg: WlxPass,
|
pass_bg: WlxPass,
|
||||||
|
|
||||||
first_render: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D, S> Canvas<D, S> {
|
impl<D, S> Canvas<D, S> {
|
||||||
@@ -222,27 +218,6 @@ impl<D, S> Canvas<D, S> {
|
|||||||
format: Format,
|
format: Format,
|
||||||
data: D,
|
data: D,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let pipeline_color = graphics.create_pipeline(
|
|
||||||
vert_common::load(graphics.device.clone()).unwrap(),
|
|
||||||
frag_color::load(graphics.device.clone()).unwrap(),
|
|
||||||
format,
|
|
||||||
);
|
|
||||||
|
|
||||||
let pipeline_glyph = graphics.create_pipeline(
|
|
||||||
vert_common::load(graphics.device.clone()).unwrap(),
|
|
||||||
frag_glyph::load(graphics.device.clone()).unwrap(),
|
|
||||||
format,
|
|
||||||
);
|
|
||||||
|
|
||||||
let vertex_buffer =
|
|
||||||
graphics.upload_verts(width as _, height as _, 0., 0., width as _, height as _);
|
|
||||||
|
|
||||||
let pipeline = graphics.create_pipeline(
|
|
||||||
vert_common::load(graphics.device.clone()).unwrap(),
|
|
||||||
frag_sprite::load(graphics.device.clone()).unwrap(),
|
|
||||||
format,
|
|
||||||
);
|
|
||||||
|
|
||||||
let tex_fg = graphics.render_texture(width as _, height as _, format);
|
let tex_fg = graphics.render_texture(width as _, height as _, format);
|
||||||
let tex_bg = graphics.render_texture(width as _, height as _, format);
|
let tex_bg = graphics.render_texture(width as _, height as _, format);
|
||||||
let tex_final = graphics.render_texture(width as _, height as _, format);
|
let tex_final = graphics.render_texture(width as _, height as _, format);
|
||||||
@@ -251,15 +226,41 @@ impl<D, S> Canvas<D, S> {
|
|||||||
let view_bg = ImageView::new_default(tex_bg.clone()).unwrap();
|
let view_bg = ImageView::new_default(tex_bg.clone()).unwrap();
|
||||||
let view_final = ImageView::new_default(tex_final.clone()).unwrap();
|
let view_final = ImageView::new_default(tex_final.clone()).unwrap();
|
||||||
|
|
||||||
let set_fg = pipeline.uniform_sampler(0, view_fg.clone(), Filter::Nearest);
|
let pipeline_bg_color = graphics.create_pipeline(
|
||||||
let set_bg = pipeline.uniform_sampler(0, view_bg.clone(), Filter::Nearest);
|
view_bg.clone(),
|
||||||
let pass_fg = pipeline.create_pass(
|
vert_common::load(graphics.device.clone()).unwrap(),
|
||||||
|
frag_color::load(graphics.device.clone()).unwrap(),
|
||||||
|
format,
|
||||||
|
);
|
||||||
|
|
||||||
|
let pipeline_fg_glyph = graphics.create_pipeline(
|
||||||
|
view_fg.clone(),
|
||||||
|
vert_common::load(graphics.device.clone()).unwrap(),
|
||||||
|
frag_glyph::load(graphics.device.clone()).unwrap(),
|
||||||
|
format,
|
||||||
|
);
|
||||||
|
|
||||||
|
let vertex_buffer =
|
||||||
|
graphics.upload_verts(width as _, height as _, 0., 0., width as _, height as _);
|
||||||
|
|
||||||
|
let pipeline_final = graphics.create_pipeline_with_layouts(
|
||||||
|
view_final.clone(),
|
||||||
|
vert_common::load(graphics.device.clone()).unwrap(),
|
||||||
|
frag_sprite::load(graphics.device.clone()).unwrap(),
|
||||||
|
format,
|
||||||
|
ImageLayout::TransferSrcOptimal,
|
||||||
|
ImageLayout::TransferSrcOptimal,
|
||||||
|
);
|
||||||
|
|
||||||
|
let set_fg = pipeline_final.uniform_sampler(0, view_fg.clone(), Filter::Linear);
|
||||||
|
let set_bg = pipeline_final.uniform_sampler(0, view_bg.clone(), Filter::Linear);
|
||||||
|
let pass_fg = pipeline_final.create_pass(
|
||||||
[width as _, height as _],
|
[width as _, height as _],
|
||||||
vertex_buffer.clone(),
|
vertex_buffer.clone(),
|
||||||
graphics.quad_indices.clone(),
|
graphics.quad_indices.clone(),
|
||||||
vec![set_fg],
|
vec![set_fg],
|
||||||
);
|
);
|
||||||
let pass_bg = pipeline.create_pass(
|
let pass_bg = pipeline_final.create_pass(
|
||||||
[width as _, height as _],
|
[width as _, height as _],
|
||||||
vertex_buffer.clone(),
|
vertex_buffer.clone(),
|
||||||
graphics.quad_indices.clone(),
|
graphics.quad_indices.clone(),
|
||||||
@@ -275,8 +276,9 @@ impl<D, S> Canvas<D, S> {
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
graphics,
|
graphics,
|
||||||
pipeline_color,
|
pipeline_bg_color,
|
||||||
pipeline_glyph,
|
pipeline_fg_glyph,
|
||||||
|
pipeline_final,
|
||||||
},
|
},
|
||||||
controls: Vec::new(),
|
controls: Vec::new(),
|
||||||
hover_controls: [None, None],
|
hover_controls: [None, None],
|
||||||
@@ -284,12 +286,9 @@ impl<D, S> Canvas<D, S> {
|
|||||||
interact_map: vec![None; stride * rows],
|
interact_map: vec![None; stride * rows],
|
||||||
interact_stride: stride,
|
interact_stride: stride,
|
||||||
interact_rows: rows,
|
interact_rows: rows,
|
||||||
view_fg,
|
|
||||||
view_bg,
|
|
||||||
view_final,
|
view_final,
|
||||||
pass_fg,
|
pass_fg,
|
||||||
pass_bg,
|
pass_bg,
|
||||||
first_render: true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,13 +320,13 @@ impl<D, S> Canvas<D, S> {
|
|||||||
.canvas
|
.canvas
|
||||||
.graphics
|
.graphics
|
||||||
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
||||||
.begin(self.view_bg.clone());
|
.begin_render_pass(&self.canvas.pipeline_final);
|
||||||
for c in self.controls.iter_mut() {
|
for c in self.controls.iter_mut() {
|
||||||
if let Some(fun) = c.on_render_bg {
|
if let Some(fun) = c.on_render_bg {
|
||||||
fun(c, &self.canvas, app, &mut cmd_buffer);
|
fun(c, &self.canvas, app, &mut cmd_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd_buffer.end_render().build_and_execute_now()
|
cmd_buffer.end_render_pass().build_and_execute_now()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_fg(&mut self, app: &mut AppState) {
|
fn render_fg(&mut self, app: &mut AppState) {
|
||||||
@@ -335,13 +334,13 @@ impl<D, S> Canvas<D, S> {
|
|||||||
.canvas
|
.canvas
|
||||||
.graphics
|
.graphics
|
||||||
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
||||||
.begin(self.view_fg.clone());
|
.begin_render_pass(&self.canvas.pipeline_final);
|
||||||
for c in self.controls.iter_mut() {
|
for c in self.controls.iter_mut() {
|
||||||
if let Some(fun) = c.on_render_fg {
|
if let Some(fun) = c.on_render_fg {
|
||||||
fun(c, &self.canvas, app, &mut cmd_buffer);
|
fun(c, &self.canvas, app, &mut cmd_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd_buffer.end_render().build_and_execute_now()
|
cmd_buffer.end_render_pass().build_and_execute_now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,8 +398,12 @@ impl<D, S> OverlayRenderer for Canvas<D, S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let image = self.view_final.image().inner().image.clone();
|
if !dirty {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
let image = self.view_final.image().clone();
|
||||||
if self.first_render {
|
if self.first_render {
|
||||||
self.first_render = false;
|
self.first_render = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -414,16 +417,15 @@ impl<D, S> OverlayRenderer for Canvas<D, S> {
|
|||||||
.wait(None)
|
.wait(None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
let mut cmd_buffer = self
|
let mut cmd_buffer = self
|
||||||
.canvas
|
.canvas
|
||||||
.graphics
|
.graphics
|
||||||
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
||||||
.begin(self.view_final.clone());
|
.begin_render_pass(&self.canvas.pipeline_final);
|
||||||
|
|
||||||
if dirty {
|
self.render_fg(app);
|
||||||
self.render_fg(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static background
|
// static background
|
||||||
cmd_buffer.run_ref(&self.pass_bg);
|
cmd_buffer.run_ref(&self.pass_bg);
|
||||||
@@ -444,8 +446,10 @@ impl<D, S> OverlayRenderer for Canvas<D, S> {
|
|||||||
// mostly static text
|
// mostly static text
|
||||||
cmd_buffer.run_ref(&self.pass_fg);
|
cmd_buffer.run_ref(&self.pass_fg);
|
||||||
{
|
{
|
||||||
let _ = cmd_buffer.end_render().build_and_execute();
|
let _ = cmd_buffer.end_render_pass().build_and_execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
self.canvas
|
self.canvas
|
||||||
.graphics
|
.graphics
|
||||||
.transition_layout(
|
.transition_layout(
|
||||||
@@ -455,8 +459,9 @@ impl<D, S> OverlayRenderer for Canvas<D, S> {
|
|||||||
)
|
)
|
||||||
.wait(None)
|
.wait(None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
fn view(&mut self) -> Option<Arc<dyn ImageViewAbstract>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
Some(self.view_final.clone())
|
Some(self.view_final.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -477,21 +482,9 @@ pub struct Control<D, S> {
|
|||||||
pub on_release: Option<fn(&mut Self, &mut D, &mut AppState)>,
|
pub on_release: Option<fn(&mut Self, &mut D, &mut AppState)>,
|
||||||
pub test_highlight: Option<fn(&Self, &mut D, &mut AppState) -> bool>,
|
pub test_highlight: Option<fn(&Self, &mut D, &mut AppState) -> bool>,
|
||||||
|
|
||||||
on_render_bg: Option<
|
on_render_bg: Option<fn(&Self, &CanvasData<D>, &mut AppState, &mut WlxCommandBuffer)>,
|
||||||
fn(&Self, &CanvasData<D>, &mut AppState, &mut WlxCommandBuffer<PrimaryAutoCommandBuffer>),
|
on_render_hl: Option<fn(&Self, &CanvasData<D>, &mut AppState, &mut WlxCommandBuffer, bool)>,
|
||||||
>,
|
on_render_fg: Option<fn(&Self, &CanvasData<D>, &mut AppState, &mut WlxCommandBuffer)>,
|
||||||
on_render_hl: Option<
|
|
||||||
fn(
|
|
||||||
&Self,
|
|
||||||
&CanvasData<D>,
|
|
||||||
&mut AppState,
|
|
||||||
&mut WlxCommandBuffer<PrimaryAutoCommandBuffer>,
|
|
||||||
bool,
|
|
||||||
),
|
|
||||||
>,
|
|
||||||
on_render_fg: Option<
|
|
||||||
fn(&Self, &CanvasData<D>, &mut AppState, &mut WlxCommandBuffer<PrimaryAutoCommandBuffer>),
|
|
||||||
>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D, S> Control<D, S> {
|
impl<D, S> Control<D, S> {
|
||||||
@@ -532,7 +525,7 @@ impl<D, S> Control<D, S> {
|
|||||||
&self,
|
&self,
|
||||||
canvas: &CanvasData<D>,
|
canvas: &CanvasData<D>,
|
||||||
_: &mut AppState,
|
_: &mut AppState,
|
||||||
cmd_buffer: &mut WlxCommandBuffer<PrimaryAutoCommandBuffer>,
|
cmd_buffer: &mut WlxCommandBuffer,
|
||||||
) {
|
) {
|
||||||
let pass = {
|
let pass = {
|
||||||
let vertex_buffer = canvas.graphics.upload_verts(
|
let vertex_buffer = canvas.graphics.upload_verts(
|
||||||
@@ -543,11 +536,11 @@ impl<D, S> Control<D, S> {
|
|||||||
self.rect.w,
|
self.rect.w,
|
||||||
self.rect.h,
|
self.rect.h,
|
||||||
);
|
);
|
||||||
let set0 = canvas.pipeline_color.uniform_buffer(
|
let set0 = canvas.pipeline_bg_color.uniform_buffer(
|
||||||
0,
|
0,
|
||||||
vec![self.bg_color.x, self.bg_color.y, self.bg_color.z, 1.],
|
vec![self.bg_color.x, self.bg_color.y, self.bg_color.z, 1.],
|
||||||
);
|
);
|
||||||
canvas.pipeline_color.create_pass(
|
canvas.pipeline_bg_color.create_pass(
|
||||||
[canvas.width as _, canvas.height as _],
|
[canvas.width as _, canvas.height as _],
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
canvas.graphics.quad_indices.clone(),
|
canvas.graphics.quad_indices.clone(),
|
||||||
@@ -562,7 +555,7 @@ impl<D, S> Control<D, S> {
|
|||||||
&self,
|
&self,
|
||||||
canvas: &CanvasData<D>,
|
canvas: &CanvasData<D>,
|
||||||
_: &mut AppState,
|
_: &mut AppState,
|
||||||
cmd_buffer: &mut WlxCommandBuffer<PrimaryAutoCommandBuffer>,
|
cmd_buffer: &mut WlxCommandBuffer,
|
||||||
strong: bool,
|
strong: bool,
|
||||||
) {
|
) {
|
||||||
let vertex_buffer = canvas.graphics.upload_verts(
|
let vertex_buffer = canvas.graphics.upload_verts(
|
||||||
@@ -573,7 +566,7 @@ impl<D, S> Control<D, S> {
|
|||||||
self.rect.w,
|
self.rect.w,
|
||||||
self.rect.h,
|
self.rect.h,
|
||||||
);
|
);
|
||||||
let set0 = canvas.pipeline_color.uniform_buffer(
|
let set0 = canvas.pipeline_bg_color.uniform_buffer(
|
||||||
0,
|
0,
|
||||||
vec![
|
vec![
|
||||||
self.bg_color.x,
|
self.bg_color.x,
|
||||||
@@ -582,7 +575,7 @@ impl<D, S> Control<D, S> {
|
|||||||
if strong { 0.5 } else { 0.3 },
|
if strong { 0.5 } else { 0.3 },
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
let pass = canvas.pipeline_color.create_pass(
|
let pass = canvas.pipeline_bg_color.create_pass(
|
||||||
[canvas.width as _, canvas.height as _],
|
[canvas.width as _, canvas.height as _],
|
||||||
vertex_buffer.clone(),
|
vertex_buffer.clone(),
|
||||||
canvas.graphics.quad_indices.clone(),
|
canvas.graphics.quad_indices.clone(),
|
||||||
@@ -596,7 +589,7 @@ impl<D, S> Control<D, S> {
|
|||||||
&self,
|
&self,
|
||||||
canvas: &CanvasData<D>,
|
canvas: &CanvasData<D>,
|
||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
cmd_buffer: &mut WlxCommandBuffer<PrimaryAutoCommandBuffer>,
|
cmd_buffer: &mut WlxCommandBuffer,
|
||||||
) {
|
) {
|
||||||
let mut cur_y = self.rect.y;
|
let mut cur_y = self.rect.y;
|
||||||
for line in self.text.lines() {
|
for line in self.text.lines() {
|
||||||
@@ -611,16 +604,16 @@ impl<D, S> Control<D, S> {
|
|||||||
glyph.width,
|
glyph.width,
|
||||||
glyph.height,
|
glyph.height,
|
||||||
);
|
);
|
||||||
let set0 = canvas.pipeline_glyph.uniform_sampler(
|
let set0 = canvas.pipeline_fg_glyph.uniform_sampler(
|
||||||
0,
|
0,
|
||||||
ImageView::new_default(tex).unwrap(),
|
ImageView::new_default(tex).unwrap(),
|
||||||
Filter::Nearest,
|
Filter::Nearest,
|
||||||
);
|
);
|
||||||
let set1 = canvas.pipeline_glyph.uniform_buffer(
|
let set1 = canvas.pipeline_fg_glyph.uniform_buffer(
|
||||||
1,
|
1,
|
||||||
vec![self.fg_color.x, self.fg_color.y, self.fg_color.z, 1.],
|
vec![self.fg_color.x, self.fg_color.y, self.fg_color.z, 1.],
|
||||||
);
|
);
|
||||||
let pass = canvas.pipeline_glyph.create_pass(
|
let pass = canvas.pipeline_fg_glyph.create_pass(
|
||||||
[canvas.width as _, canvas.height as _],
|
[canvas.width as _, canvas.height as _],
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
canvas.graphics.quad_indices.clone(),
|
canvas.graphics.quad_indices.clone(),
|
||||||
@@ -637,7 +630,7 @@ impl<D, S> Control<D, S> {
|
|||||||
&self,
|
&self,
|
||||||
canvas: &CanvasData<D>,
|
canvas: &CanvasData<D>,
|
||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
cmd_buffer: &mut WlxCommandBuffer<PrimaryAutoCommandBuffer>,
|
cmd_buffer: &mut WlxCommandBuffer,
|
||||||
) {
|
) {
|
||||||
let (w, h) = app
|
let (w, h) = app
|
||||||
.fc
|
.fc
|
||||||
@@ -656,16 +649,16 @@ impl<D, S> Control<D, S> {
|
|||||||
glyph.width,
|
glyph.width,
|
||||||
glyph.height,
|
glyph.height,
|
||||||
);
|
);
|
||||||
let set0 = canvas.pipeline_glyph.uniform_sampler(
|
let set0 = canvas.pipeline_fg_glyph.uniform_sampler(
|
||||||
0,
|
0,
|
||||||
ImageView::new_default(tex).unwrap(),
|
ImageView::new_default(tex).unwrap(),
|
||||||
Filter::Nearest,
|
Filter::Nearest,
|
||||||
);
|
);
|
||||||
let set1 = canvas.pipeline_glyph.uniform_buffer(
|
let set1 = canvas.pipeline_fg_glyph.uniform_buffer(
|
||||||
1,
|
1,
|
||||||
vec![self.fg_color.x, self.fg_color.y, self.fg_color.z, 1.],
|
vec![self.fg_color.x, self.fg_color.y, self.fg_color.z, 1.],
|
||||||
);
|
);
|
||||||
let pass = canvas.pipeline_glyph.create_pass(
|
let pass = canvas.pipeline_fg_glyph.create_pass(
|
||||||
[canvas.width as _, canvas.height as _],
|
[canvas.width as _, canvas.height as _],
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
canvas.graphics.quad_indices.clone(),
|
canvas.graphics.quad_indices.clone(),
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ use vulkano::{
|
|||||||
buffer::Subbuffer,
|
buffer::Subbuffer,
|
||||||
command_buffer::CommandBufferUsage,
|
command_buffer::CommandBufferUsage,
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{sampler::Filter, view::ImageView, Image, ImageLayout},
|
||||||
view::ImageView, AttachmentImage, ImageAccess, ImageLayout, ImageViewAbstract, StorageImage,
|
|
||||||
},
|
|
||||||
sampler::Filter,
|
|
||||||
sync::GpuFuture,
|
sync::GpuFuture,
|
||||||
Handle, VulkanObject,
|
Handle, VulkanObject,
|
||||||
};
|
};
|
||||||
@@ -32,7 +29,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
graphics::{Vert2Uv, WlxGraphics, WlxPipeline},
|
graphics::{Vert2Uv, WlxGraphics, WlxPipeline},
|
||||||
hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
|
hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
|
||||||
shaders::{frag_sprite, vert_common},
|
shaders::{frag_screen, vert_common},
|
||||||
state::{AppSession, AppState},
|
state::{AppSession, AppState},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,19 +107,11 @@ struct ScreenPipeline {
|
|||||||
graphics: Arc<WlxGraphics>,
|
graphics: Arc<WlxGraphics>,
|
||||||
pipeline: Arc<WlxPipeline>,
|
pipeline: Arc<WlxPipeline>,
|
||||||
vertex_buffer: Subbuffer<[Vert2Uv]>,
|
vertex_buffer: Subbuffer<[Vert2Uv]>,
|
||||||
target_layout: ImageLayout,
|
|
||||||
pub view: Arc<ImageView<AttachmentImage>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenPipeline {
|
impl ScreenPipeline {
|
||||||
fn new(graphics: Arc<WlxGraphics>, image: &StorageImage) -> Self {
|
fn new(graphics: Arc<WlxGraphics>, image: &Image) -> Self {
|
||||||
let pipeline = graphics.create_pipeline(
|
let dim = image.extent();
|
||||||
vert_common::load(graphics.device.clone()).unwrap(),
|
|
||||||
frag_sprite::load(graphics.device.clone()).unwrap(),
|
|
||||||
Format::R8G8B8A8_UNORM,
|
|
||||||
);
|
|
||||||
|
|
||||||
let dim = image.dimensions().width_height();
|
|
||||||
|
|
||||||
let vertex_buffer =
|
let vertex_buffer =
|
||||||
graphics.upload_verts(dim[0] as _, dim[1] as _, 0.0, 0.0, dim[0] as _, dim[1] as _);
|
graphics.upload_verts(dim[0] as _, dim[1] as _, 0.0, 0.0, dim[0] as _, dim[1] as _);
|
||||||
@@ -131,26 +120,31 @@ impl ScreenPipeline {
|
|||||||
|
|
||||||
let view = ImageView::new_default(render_texture).unwrap();
|
let view = ImageView::new_default(render_texture).unwrap();
|
||||||
|
|
||||||
|
let pipeline = graphics.create_pipeline_with_layouts(
|
||||||
|
view,
|
||||||
|
vert_common::load(graphics.device.clone()).unwrap(),
|
||||||
|
frag_screen::load(graphics.device.clone()).unwrap(),
|
||||||
|
Format::R8G8B8A8_UNORM,
|
||||||
|
ImageLayout::ColorAttachmentOptimal,
|
||||||
|
ImageLayout::ColorAttachmentOptimal,
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
graphics,
|
graphics,
|
||||||
pipeline,
|
pipeline,
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
view,
|
|
||||||
target_layout: ImageLayout::Undefined,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, image: Arc<StorageImage>) {
|
fn render(&mut self, image: Arc<Image>) {
|
||||||
if image.inner().image.handle().as_raw()
|
if image.handle().as_raw() == self.pipeline.view.image().handle().as_raw() {
|
||||||
== self.view.image().inner().image.handle().as_raw()
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut command_buffer = self
|
let mut command_buffer = self
|
||||||
.graphics
|
.graphics
|
||||||
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
.create_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
||||||
.begin(self.view.clone());
|
.begin_render_pass(&self.pipeline);
|
||||||
|
|
||||||
let set0 = self.pipeline.uniform_sampler(
|
let set0 = self.pipeline.uniform_sampler(
|
||||||
0,
|
0,
|
||||||
@@ -158,7 +152,7 @@ impl ScreenPipeline {
|
|||||||
Filter::Linear,
|
Filter::Linear,
|
||||||
);
|
);
|
||||||
|
|
||||||
let dim = self.view.dimensions().width_height();
|
let dim = self.pipeline.view.image().extent();
|
||||||
let dim = [dim[0] as f32, dim[1] as f32];
|
let dim = [dim[0] as f32, dim[1] as f32];
|
||||||
|
|
||||||
let pass = self.pipeline.create_pass(
|
let pass = self.pipeline.create_pass(
|
||||||
@@ -169,35 +163,15 @@ impl ScreenPipeline {
|
|||||||
);
|
);
|
||||||
command_buffer.run_ref(&pass);
|
command_buffer.run_ref(&pass);
|
||||||
|
|
||||||
let image = self.view.image().inner().image.clone();
|
|
||||||
|
|
||||||
if self.target_layout == ImageLayout::TransferSrcOptimal {
|
|
||||||
self.graphics
|
|
||||||
.transition_layout(
|
|
||||||
image.clone(),
|
|
||||||
ImageLayout::TransferSrcOptimal,
|
|
||||||
ImageLayout::ColorAttachmentOptimal,
|
|
||||||
)
|
|
||||||
.wait(None)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut exec = command_buffer.end_render().build_and_execute();
|
let mut exec = command_buffer.end_render_pass().build_and_execute();
|
||||||
exec.flush().unwrap();
|
exec.flush().unwrap();
|
||||||
exec.cleanup_finished();
|
exec.cleanup_finished();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.graphics
|
pub(super) fn view(&self) -> Arc<ImageView> {
|
||||||
.transition_layout(
|
self.pipeline.view.clone()
|
||||||
image,
|
|
||||||
ImageLayout::ColorAttachmentOptimal,
|
|
||||||
ImageLayout::TransferSrcOptimal,
|
|
||||||
)
|
|
||||||
.wait(None)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
self.target_layout = ImageLayout::TransferSrcOptimal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +179,7 @@ pub struct ScreenRenderer {
|
|||||||
capture: Box<dyn WlxCapture>,
|
capture: Box<dyn WlxCapture>,
|
||||||
receiver: Option<Receiver<WlxFrame>>,
|
receiver: Option<Receiver<WlxFrame>>,
|
||||||
pipeline: Option<ScreenPipeline>,
|
pipeline: Option<ScreenPipeline>,
|
||||||
last_frame: Option<Arc<dyn ImageViewAbstract>>,
|
last_image: Option<Arc<ImageView>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenRenderer {
|
impl ScreenRenderer {
|
||||||
@@ -218,7 +192,7 @@ impl ScreenRenderer {
|
|||||||
capture: Box::new(capture),
|
capture: Box::new(capture),
|
||||||
receiver: None,
|
receiver: None,
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
last_frame: None,
|
last_image: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +210,7 @@ impl ScreenRenderer {
|
|||||||
capture: Box::new(capture),
|
capture: Box::new(capture),
|
||||||
receiver: None,
|
receiver: None,
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
last_frame: None,
|
last_image: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,13 +228,13 @@ impl OverlayRenderer for ScreenRenderer {
|
|||||||
for frame in receiver.try_iter() {
|
for frame in receiver.try_iter() {
|
||||||
match frame {
|
match frame {
|
||||||
WlxFrame::Dmabuf(frame) => {
|
WlxFrame::Dmabuf(frame) => {
|
||||||
if let Ok(new) = app.graphics.dmabuf_texture(frame) {
|
if let Some(new) = app.graphics.dmabuf_texture(frame) {
|
||||||
let pipeline = self
|
let pipeline = self
|
||||||
.pipeline
|
.pipeline
|
||||||
.get_or_insert_with(|| ScreenPipeline::new(app.graphics.clone(), &new));
|
.get_or_insert_with(|| ScreenPipeline::new(app.graphics.clone(), &new));
|
||||||
|
log::info!("New frame");
|
||||||
pipeline.render(new);
|
pipeline.render(new);
|
||||||
self.last_frame = Some(pipeline.view.clone());
|
self.last_image = Some(pipeline.view());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WlxFrame::MemFd(_frame) => {
|
WlxFrame::MemFd(_frame) => {
|
||||||
@@ -280,8 +254,8 @@ impl OverlayRenderer for ScreenRenderer {
|
|||||||
fn resume(&mut self, _app: &mut AppState) {
|
fn resume(&mut self, _app: &mut AppState) {
|
||||||
self.capture.resume();
|
self.capture.resume();
|
||||||
}
|
}
|
||||||
fn view(&mut self) -> Option<Arc<dyn ImageViewAbstract>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
self.last_frame.take()
|
self.last_image.take()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,3 +106,120 @@ pub mod frag_srgb {
|
|||||||
",
|
",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod frag_screen {
|
||||||
|
vulkano_shaders::shader! {
|
||||||
|
ty: "fragment",
|
||||||
|
src: r"#version 310 es
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 in_uv;
|
||||||
|
layout (location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
layout (set = 0, binding = 0) uniform sampler2D in_texture;
|
||||||
|
|
||||||
|
layout (set = 0, binding = 1) uniform ColorBlock {
|
||||||
|
uniform vec4 in_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
vec4 supersample(sampler2D tex, vec2 uv) {
|
||||||
|
float ddx = dFdx(uv.x);
|
||||||
|
float ddy = dFdy(uv.y);
|
||||||
|
float width = sqrt(ddx*ddx + ddy*ddy);
|
||||||
|
|
||||||
|
ivec2 size = textureSize(tex, 0);
|
||||||
|
|
||||||
|
ivec2 pixelWidth = ivec2(width * vec2(size));
|
||||||
|
ivec2 xy = ivec2(uv * vec2(size));
|
||||||
|
|
||||||
|
ivec2 start = xy - pixelWidth/2;
|
||||||
|
ivec2 end = xy + pixelWidth/2;
|
||||||
|
|
||||||
|
vec4 outColor = vec4(0.0);
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
for (int xSample = start.x; xSample <= end.x; xSample++) {
|
||||||
|
for (int ySample = start.y; ySample <= end.y; ySample++) {
|
||||||
|
n++;
|
||||||
|
outColor += texelFetch(tex, clamp(ivec2(xSample, ySample), ivec2(0), size), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n > 0) {
|
||||||
|
return outColor / float(n);
|
||||||
|
} else {
|
||||||
|
return vec4(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float gaussian(float x, float t) {
|
||||||
|
float PI = 3.14159265358;
|
||||||
|
return exp(-x*x/(2.0 * t*t))/(sqrt(2.0*PI)*t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float besselI0(float x) {
|
||||||
|
return 1.0 + pow(x, 2.0) * (0.25 + pow(x, 2.0) * (0.015625 + pow(x, 2.0) * (0.000434028 + pow(x, 2.0) * (6.78168e-6 + pow(x, 2.0) * (6.78168e-8 + pow(x, 2.0) * (4.7095e-10 + pow(x, 2.0) * (2.40281e-12 + pow(x, 2.0) * (9.38597e-15 + pow(x, 2.0) * (2.8969e-17 + 7.24226e-20 * pow(x, 2.0))))))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
float kaiser(float x, float alpha) {
|
||||||
|
if (x > 1.0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
return besselI0(alpha * sqrt(1.0-x*x));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 lowpassFilter(sampler2D tex, vec2 uv, float alpha) {
|
||||||
|
float PI = 3.14159265358;
|
||||||
|
|
||||||
|
vec4 q = vec4(0.0);
|
||||||
|
|
||||||
|
vec2 dx_uv = dFdx(uv);
|
||||||
|
vec2 dy_uv = dFdy(uv);
|
||||||
|
//float width = sqrt(max(dot(dx_uv, dx_uv), dot(dy_uv, dy_uv)));
|
||||||
|
vec2 width = abs(vec2(dx_uv.x, dy_uv.y));
|
||||||
|
|
||||||
|
|
||||||
|
ivec2 size = textureSize(tex, 0);
|
||||||
|
|
||||||
|
vec2 pixelWidth = floor(width * vec2(size));
|
||||||
|
vec2 aspectRatio = normalize(pixelWidth);
|
||||||
|
|
||||||
|
ivec2 xy = ivec2(uv * vec2(size));
|
||||||
|
vec2 xyf = uv * vec2(size);
|
||||||
|
|
||||||
|
pixelWidth = clamp(pixelWidth, vec2(1.0), vec2(2.0));
|
||||||
|
|
||||||
|
|
||||||
|
ivec2 start = xy - ivec2(pixelWidth);
|
||||||
|
ivec2 end = xy + ivec2(pixelWidth);
|
||||||
|
|
||||||
|
vec4 outColor = vec4(0.0);
|
||||||
|
|
||||||
|
float qSum = 0.0;
|
||||||
|
|
||||||
|
for (int v = start.y; v <= end.y; v++) {
|
||||||
|
for (int u = start.x; u <= end.x; u++) {
|
||||||
|
float kx = (xyf.x - float(u))/pixelWidth.x;
|
||||||
|
float ky = (xyf.y - float(v))/pixelWidth.y;
|
||||||
|
|
||||||
|
//float lanczosValue = gaussian(kx, fcx);
|
||||||
|
float lanczosValue = kaiser(sqrt(kx*kx + ky*ky), alpha);
|
||||||
|
|
||||||
|
q += texelFetch(tex, ivec2(u, v), 0) * lanczosValue;
|
||||||
|
qSum += lanczosValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return q/qSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
out_color = lowpassFilter(in_texture, in_uv, 4.0);
|
||||||
|
out_color.a = 1.0;
|
||||||
|
}
|
||||||
|
",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
111
src/shaders/src/screen.frag
Normal file
111
src/shaders/src/screen.frag
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#version 310 es
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 in_uv;
|
||||||
|
layout (location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
layout (set = 0, binding = 0) uniform sampler2D in_texture;
|
||||||
|
|
||||||
|
layout (set = 0, binding = 1) uniform ColorBlock {
|
||||||
|
uniform vec4 in_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
vec4 supersample(sampler2D tex, vec2 uv) {
|
||||||
|
float ddx = dFdx(uv.x);
|
||||||
|
float ddy = dFdy(uv.y);
|
||||||
|
float width = sqrt(ddx*ddx + ddy*ddy);
|
||||||
|
|
||||||
|
ivec2 size = textureSize(tex, 0);
|
||||||
|
|
||||||
|
ivec2 pixelWidth = ivec2(width * vec2(size));
|
||||||
|
ivec2 xy = ivec2(uv * vec2(size));
|
||||||
|
|
||||||
|
ivec2 start = xy - pixelWidth/2;
|
||||||
|
ivec2 end = xy + pixelWidth/2;
|
||||||
|
|
||||||
|
vec4 outColor = vec4(0.0);
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
for (int xSample = start.x; xSample <= end.x; xSample++) {
|
||||||
|
for (int ySample = start.y; ySample <= end.y; ySample++) {
|
||||||
|
n++;
|
||||||
|
outColor += texelFetch(tex, clamp(ivec2(xSample, ySample), ivec2(0), size), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n > 0) {
|
||||||
|
return outColor / float(n);
|
||||||
|
} else {
|
||||||
|
return vec4(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float gaussian(float x, float t) {
|
||||||
|
float PI = 3.14159265358;
|
||||||
|
return exp(-x*x/(2.0 * t*t))/(sqrt(2.0*PI)*t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float besselI0(float x) {
|
||||||
|
return 1.0 + pow(x, 2.0) * (0.25 + pow(x, 2.0) * (0.015625 + pow(x, 2.0) * (0.000434028 + pow(x, 2.0) * (6.78168e-6 + pow(x, 2.0) * (6.78168e-8 + pow(x, 2.0) * (4.7095e-10 + pow(x, 2.0) * (2.40281e-12 + pow(x, 2.0) * (9.38597e-15 + pow(x, 2.0) * (2.8969e-17 + 7.24226e-20 * pow(x, 2.0))))))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
float kaiser(float x, float alpha) {
|
||||||
|
if (x > 1.0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
return besselI0(alpha * sqrt(1.0-x*x));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 lowpassFilter(sampler2D tex, vec2 uv, float alpha) {
|
||||||
|
float PI = 3.14159265358;
|
||||||
|
|
||||||
|
vec4 q = vec4(0.0);
|
||||||
|
|
||||||
|
vec2 dx_uv = dFdx(uv);
|
||||||
|
vec2 dy_uv = dFdy(uv);
|
||||||
|
//float width = sqrt(max(dot(dx_uv, dx_uv), dot(dy_uv, dy_uv)));
|
||||||
|
vec2 width = abs(vec2(dx_uv.x, dy_uv.y));
|
||||||
|
|
||||||
|
|
||||||
|
ivec2 size = textureSize(tex, 0);
|
||||||
|
|
||||||
|
vec2 pixelWidth = floor(width * vec2(size));
|
||||||
|
vec2 aspectRatio = normalize(pixelWidth);
|
||||||
|
|
||||||
|
ivec2 xy = ivec2(uv * vec2(size));
|
||||||
|
vec2 xyf = uv * vec2(size);
|
||||||
|
|
||||||
|
pixelWidth = clamp(pixelWidth, vec2(1.0), vec2(2.0));
|
||||||
|
|
||||||
|
|
||||||
|
ivec2 start = xy - ivec2(pixelWidth);
|
||||||
|
ivec2 end = xy + ivec2(pixelWidth);
|
||||||
|
|
||||||
|
vec4 outColor = vec4(0.0);
|
||||||
|
|
||||||
|
float qSum = 0.0;
|
||||||
|
|
||||||
|
for (int v = start.y; v <= end.y; v++) {
|
||||||
|
for (int u = start.x; u <= end.x; u++) {
|
||||||
|
float kx = fcFactor * (xyf.x - float(u))/pixelWidth.x;
|
||||||
|
float ky = fcFactor * (xyf.y - float(v))/pixelWidth.y;
|
||||||
|
|
||||||
|
//float lanczosValue = gaussian(kx, fcx);
|
||||||
|
float lanczosValue = kaiser(sqrt(kx*kx + ky*ky), alpha);
|
||||||
|
|
||||||
|
q += texelFetch(tex, ivec2(u, v), 0) * lanczosValue;
|
||||||
|
qSum += lanczosValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return q/qSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
out_color = lowpassFilter(in_texture, in_uv, 4.0);
|
||||||
|
out_color.a = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user